2

2021: This was in fact an issue with the package. Regex link matching has since been implemented with the solution I created to solve it for myself. You can read about it in the documentation here.


I'm using Laravel 5.8 with AdminLTE for Laravel.

There's several options to create a menu, one of which is to create it in the provided config file, which I use.

You can specify an active key in the menu that allows you to make the menu have the class that makes the menu item active and activates the dropdown.

I have a menu item, which I would like to make active on these pages:

  • /posts (works with active => ['/posts'])
  • /posts/{post_id} (id are only numbers)

These URL's shouldn't match:

  • /posts/create
  • /posts/anyotherlink
  • /posts/1text

I can not use /posts/* because that would make the create page and some others active.

The readme suggest that you can also use regex to do this. I don't use regex at all, but I came to this, which, according tot regex101 seems to match what I need it to:

^\/posts\/[0-9]+$

I've tried to implement it like so:

[
    'text'    => 'Posts overview',
    'url'     => '/posts',
    'icon'    => 'list',
    'active'  => ['/posts', '^\/posts\/[0-9]+$'],
    'active'  => ['/posts', '/posts/[^0-9]'] // also tried this
],

Unfortunately, this does not seem to work as it doesn't make the menu item active on the pages listed above.

Edit: I've also created an issue in the GitHub repository as I suspect that this might be an issue with the package.

Am I missing something, or doing something wrong?

3
  • Try 'active' => ['/^\/posts(?:\/\d+)?$/'] Commented May 11, 2019 at 17:50
  • @WiktorStribiżew Thanks for your suggestion, however the result remains the same: the menu doesn't light up. I'm starting to think that this might be an issue with the package on GitHub.
    – rpm192
    Commented May 11, 2019 at 18:01
  • Ok, probably, I just wanted to point out that regexps in PHP are defined with regex delimiters, and in most cases adding them is enough. Also, '/^\/posts(?:\/\d+)?$/' regex matches a string that starts with /posts and ends either immediately here or has / and 1+ digits after (optional). Maybe once you figure out how to make regex work within this code it will be helpful. Commented May 11, 2019 at 18:03

4 Answers 4

3
+50

In the ActiveChecker.php class of the project you can find this piece of code

protected function checkPattern($pattern)
{
    $fullUrlPattern = $this->url->to($pattern);

    $fullUrl = $this->request->fullUrl();

    return Str::is($fullUrlPattern, $fullUrl);
}

Based on laravel documentation, Str::is does not run regexp matching, but justs supports asterisks for wildcards.

In your case you could post a PR that will use regexo if the given pattern is a regular expression, otherwise, run Str::is

3
  • I was also thinking about something like this, but checking if a string is a regex with another regex is a solution that will not work for all regexes. Another solution would be something like the accepted answer of this question. But it seems really hacky to me.
    – rpm192
    Commented May 15, 2019 at 14:33
  • Hey, I've opened a pull request for a similar solution to what you suggested, I'll award you the bounty.
    – rpm192
    Commented May 20, 2019 at 14:40
  • Thanks! I had a look at the PR and it's good stuff. Just fix the syntax (I guess their CI doesn't allow adding empty lines in commit), and push to get it merged Commented May 20, 2019 at 16:18
0

You can try using the below pattern in your code:

/^\/posts(\/[0-9]+)?$/

This will work for the below test scenarios:

/posts
/posts/3829
/posts/921
/posts/1

You can check the requirement with the provided solution on REGEX_Solution

Hope it works!

0

This is where route naming is really helpful. So, in my code this route would named something like admin:post.index. Then to check if it was active I could use the request helper and a method called routeIs().

Using the name I'd use, here's an example:

request()->routeIs('admin:post.index')

Now, if I wanted this link to be active for the create, edit, delete etc routes I'd do the following:

request()->routeIs('admin:post.*')

This would work since I apply route names following a dot notation hierarchy.

You can optionally provide multiple patterns to that method if there were specific routes you wanted to match.

0

I have created a solution for my problem, it's by no means the prettiest solution, but it'll work, for now.

I have edited the ActiveChecker.php file and edited the checkPattern() function, so it evaluates regex if the pattern in the config file starts with regex:.

protected function checkPattern($pattern)
{
    $fullUrlPattern = $this->url->to($pattern);

    $fullUrl = $this->request->fullUrl();

    if(mb_substr($pattern, 0, 6) === "regex:") {

      $regex = mb_substr($pattern, 6);

      if(preg_match($regex, request()->path()) == 1) {
        return true;
      }

      return false;
    }
    return Str::is($fullUrlPattern, $fullUrl);
}

In my config file, I can now just do this, to use a regex pattern, simply by using the regex: prefix.

'active'  => ['/suppliers', 'regex:@^posts/[0-9]+$@'],

The path of the request which is posts/1 for example, will get compared with the regex, not the full URL.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.