├── .editorconfig ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── composer.json └── src ├── DevMarketer └── EasyNav │ ├── EasyNav.php │ ├── EasyNavFacade.php │ ├── EasyNavServiceProvider.php │ └── functions.php └── config └── easynav.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | thumbs.db 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Laravel Quick Nav Change Log 2 | 3 | All features, bug fixes, and changes in the code base will be updated and documented here with each release. 4 | 5 | ## Version 1: Official Release 6 | 7 | ##### 1.0.1 - 1.0.3 8 | 9 | **Fixes:** 10 | 11 | 1. (1.0.4) - Default active class is now "active" instead of "is-active". This now matches the default used by bootstrap framework and matches the statements made in the Readme documentation. [Issue \#3](https://github.com/DevMarketer/LaravelEasyNav/issues/3) 12 | 1. (1.0.3) - Removed problematic feature allowing you to selectively enable helper functions. This will be removed until I can find a better way to do it. 13 | 1. (1.0.2) - Fixed typos in config files 14 | 1. (1.0.1) - Merge config files so that users do not have to export the config if they do not want to. 15 | 16 | ##### 1.0.0 17 | 18 | This update was focused on the core of EasyNav package. This builds out the basic functions of EasyNav and how it works. It provides a basic facade to access various helpful functions focused around returning a specified class name based on the current page the user is on. 19 | 20 | This allows a developer to set rules in their navigation partials and then never worry about navigation again. 21 | 22 | This update includes the basic structure of the package, includes helper functions and the `Nav` Facade that you can use to configure your app's navigation 23 | 24 | **New Features:*** 25 | 26 | 1. Four core methods to use for your navigation and menus 27 | 1. `Nav::hasSegment()` - checks if the current page matches the given value at the given segment; 28 | 1. `Nav::isRoute()` = checks if the current page matches the given named route 29 | 1. `Nav::isResource()` - checks if the current page matches a given resource 30 | 1. `Nav::urlDoesContain()` - searches the current path for a search term you provide 31 | 1. Three Helper functions provided 32 | 1. `navHasSegment()` - shortcut of `Nav::hasSegment()` 33 | 1. `navIsRoute()` - shortcut of `Nav::isRoute()` 34 | 1. `navIsResource()` - shortcut of `Nav::isResource` 35 | 1. Publishable config file available with the `-tag=easynav` 36 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | Thank you for your interest in contributing to **Laravel EasyNav**! Together we can build an even better package for the whole community. 4 | 5 | ## Use GitHub issues 6 | 7 | If you experience a bug or error please submit a GitHub issue by going here: https://github.com/DevMarketer/LaravelEasyNav/issues 8 | 9 | The issues are generally handled immediately and will receive a label as appropriate (such as "Bug", "New Feature", "Improvement", or "Out of Scope"). If you wish to fix the problem or add the feature yourself, please mention that in the issue so that a moderator can mark the issue as responsible by you and you can begin work towards submitting a PR (Pull Request). 10 | 11 | When you submit a PR or commit, please add "Resolves \#10" or "Fixed \#22" in the commit message to link your PR/Commit to the Issue you are addressing. 12 | 13 | ## Versioning 14 | 15 | Versioning in this package follows the [Semantic Versioning 2.0.0](http://semver.org/) standard. This is generally represented as: `MAJOR.MINOR.PATCH`. 16 | 17 | PRs will be accepted and merged into the Dev branch. Bugs will be pushed to Master as soon as possible as a _patch_ or _incremental_ update (x.x.1), new features will be grouped together and pushed in clusters as minor upgrades (x.1.x). 18 | 19 | Major upgrades will be noted with the community and planned in advance. These will be reserved for significant re-writes or to mark incompatibility with previous versions. 20 | 21 | Note that the _Master_ branch is considered stable at all times and is safe to use in production. The _Dev_ branch represents the working branch and the most cutting edge features but may not be suitable for production environments. 22 | 23 | ## Roadmap 24 | 25 | To see all the upcoming features planned for this project please visit Roadmap on the projects tab: https://github.com/DevMarketer/LaravelEasyNav/projects/1 26 | 27 | Here you can click through any of the cards and see the issues that these cards represent. On the issues you are welcome to discuss the feature/bug/improvement to your hearts content and I encourage you to do so. 28 | 29 | ## Thank You! 30 | 31 | Please fill free to contribute in any way that you feel you can. Even adding issues related to bugs is helpful to the community, as is discussing new features or improvements. There are many ways like this to contribute even if you are not comfortable submitting code. 32 | 33 | #### Contact 34 | 35 | If you want to reach out to the Maintainer of this package, please email me at hello@jacurtis.com or follow me/ mention me on Twitter: https://twitter.com/_jacurtis 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 DevMarketer www.devmarketer.io 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel EasyNav: Easy Navigation Tools for Laravel 2 | 3 | Every time I build another Laravel app, I find myself re-using the same custom Navigation helpers I have been perfecting over the years. These tools allow you to accurately and concisely change the class on navigation elements depending on the current page. Tools like these allow you to have your navigation manage itself, speeding up the development progress, but with the efficiency for long term production use. 4 | 5 | ## Installation 6 | 7 | Installation is straightforward, setup is similar to every other Laravel Package. 8 | 9 | #### 1. Install via Composer 10 | 11 | Begin by pulling in the package through Composer: 12 | 13 | ``` 14 | composer require devmarketer/easynav 15 | ``` 16 | 17 | #### 2. Define the Service Provider and alias 18 | 19 | Next we need to pull in the alias and service providers. 20 | 21 | **Note:** This package supports the new _auto-discovery_ features of Laravel 5.5, so if you are working on a Laravel 5.5 project, then your install is complete, you can skip to step 3. 22 | 23 | If you are using Laravel 5.0 - 5.4 then you need to add a provider and alias. Inside of your `config/app.php` define a new service provider 24 | 25 | ``` 26 | 'providers' => [ 27 | // other providers 28 | 29 | DevMarketer\EasyNav\EasyNavServiceProvider::class, 30 | ]; 31 | ``` 32 | 33 | Then we want to define an alias in the same `config/app.php` file. 34 | 35 | ``` 36 | 'aliases' => [ 37 | // other aliases 38 | 39 | 'Nav' => DevMarketer\EasyNav\EasyNavFacade::class, 40 | ]; 41 | ``` 42 | 43 | #### 3. Publish Config File (OPTIONAL) 44 | 45 | The config file allows you to override default settings of this package to meet your specific needs. It is optional and allows you to set a default active class name to output on active navigational elements. You can override this value in each function, but setting a default makes your code cleaner. It defaults to `"active"`, which is a common class name used by many developers and **supports Bootstrap**. If you are using a framework like **Bulma** then you want to change this value to `"is-active"`. Many CSS BLM frameworks would require `"--active"`. Set this once and forget it. 46 | 47 | To generate a config file type this command into your terminal: 48 | 49 | ``` 50 | php artisan vendor:publish --tag=easynav 51 | ``` 52 | 53 | This generates a config file at `config/easynav.php`. 54 | 55 | ## Usage 56 | 57 | This package is easy to use. It provides a handful of helpful functions for navigation. Think of each of these methods as "tools" to define rules for a navigation element. Once you set the _"rule"_ for that navigation element, you don't have to worry about it. If a user visits that page (based on the rule) then it will output a CSS class that you define (generally something like `"active"` or `"is-active"`) to the html element, which will display an active state on your navigation. 58 | 59 | ##### [IMPORTANT] What this package does NOT do 60 | 61 | This does NOT generate HTML for navigation. It simply adds "active" css classes to your HTML elements based on rules you define. You customize what an active menu/navigation link looks like in your CSS. 62 | 63 | --- 64 | 65 | ### How These Nav Rules Work 66 | 67 | For each navigation element, you will add one of the following "rules" to the `class=" "` field of the HTML element. It is still your responsibility to style the element in your CSS. Many CSS frameworks have already done this for you. 68 | 69 | ##### Example: 70 | 71 | ``` 72 | Current Url - https://domain.com/posts/laravel-is-awesome 73 | --- 74 | 75 | 83 | ``` 84 | 85 | This example displays how you might interconnect 4 different "rules" to define when a certain navigational element should receive the "active" class. 86 | 87 | **REMEMBER: it is still up to you to style the element! This plugin simply adds an active class to the element dynamically based on rules you define."** 88 | 89 | Now that you see how this works in practice, lets take a look at each _rule_ individually to understand how to define it. 90 | 91 | --- 92 | 93 | ### isRoute() - Matches Named Routes 94 | 95 | This rule will mark an element as active if the current page matches a specified named route. 96 | 97 | ``` 98 | Nav::isRoute($routeName, $activeClass = "active") 99 | ``` 100 | 101 | **Parameters:** 102 | 103 | - `$routeName` - REQUIRED String 104 | This is the named route you wish to match. It must match the values registered in the "name" column when you run `php artisan route:list` 105 | - `$activeClass` - OPTIONAL String 106 | This defaults to the value defined under `default_class` in your config file or `"active"` if no config is generated 107 | 108 | **Example:** 109 | 110 | ``` 111 | Current Url - https://domain.com/contact 112 | --- 113 | 114 | Routes File: 115 | Route::get('contact', 'BaseController@contact')->name('contact'); 116 | --- 117 | 118 | {{ Nav::isRoute('contact') }} // returns "active" [1] 119 | {{ Nav::isRoute('contact', 'is-open') }} // returns "is-open" [2] 120 | {{ Nav::isRoute('about') }} // returns "" [3] 121 | ``` 122 | 123 | (1) string "contact" matches the named route which is also "contact", so returns default active class 124 | (2) "contact" matches the named route we are currently on, so returns the active class provided in the second parameter, "is-open" 125 | (3) "about" does not match the current route we are on, which is "contact", so it returns "" 126 | 127 | --- 128 | 129 | ### hasSegment() - Matches Defined Segments 130 | 131 | This rule will mark an element as active if the string(s) provided match the segment(s) provided. This is great for defining parent elements that you want marked active if any of its' children are also active. 132 | 133 | ``` 134 | Nav::hasSegment($slugs, $segments = 1, $activeClass = "active") 135 | ``` 136 | 137 | **Parameters:** 138 | 139 | - `$slug` - REQUIRED | String or Array of Strings 140 | This is the value that we try to match. If you want to match against several strings, pass an array of strings. Note that this works like an `OR`, `||` clause. If any of them match, it returns true. 141 | - `$segments` - OPTIONAL | Integer or Array of Ints 142 | This defines which segment to match the `$slug` against. Defaults to first segment if none is given. Use integers (starting at 1) to define segments. Segments values are representative as: `https://domainDoesntCount.com/1/2/3/4`. Due to limitations with Laravel's Request you can only define segments out to the 4th segment. If you want to scan multiple segments, pass an array of integers to check against any of those segments (works like an `OR`, `||` clause). 143 | - `$activeClass` - OPTIONAL | String 144 | This defaults to the value defined under `default_class` in your config file or `"active"` if no config is generated 145 | 146 | **Example:** 147 | 148 | ``` 149 | Current Url - https://domain.com/posts/created-by/devmarketer 150 | --- 151 | 152 | {{ Nav::hasSegment('posts') }} // returns "active" [1] 153 | {{ Nav::hasSegment('posts', 2) }} // returns "" [2] 154 | {{ Nav::hasSegment('devmarketer', [2,3], 'is-active') }} // returns "active" [3] 155 | {{ Nav::hasSegment(['devmarketer', 'jacurtis'], [2,3]) }} // returns "active" [4] 156 | {{ Nav::hasSegment('posts', [2,3]) }} // returns "" [5] 157 | ``` 158 | 159 | (1) "posts" is in the first segment (the default segment) so it returns the default active class 160 | (2) "posts" is not in the second segment so it returns nothing 161 | (3) checks if "devmarketer" is in the second OR third segments. It is in the 3rd segment, so it returns the active class provided, "is-active" 162 | (4) check if "devmarketer" or "jacurtis" are in either the 2nd or 3rd segments. "devmarketer" is in 3rd segment, so returns default active class 163 | (5) checks for "posts" in second or third segments, returns nothing. 164 | 165 | **Example 2:** 166 | 167 | It only matches whole segments. 168 | 169 | ``` 170 | Current Url - https://domain.com/example/text/segments 171 | --- 172 | 173 | {{ Nav::hasSegment('example') }} // returns "active" 174 | {{ Nav::hasSegment('exam') }} // returns "" 175 | ``` 176 | 177 | In the first one, it works because "example" is a full segment. But the second one does not work because even though "exam" is contained inside of the first segment "example", it doesn't match the entire segment. 178 | 179 | If you want to match part of a segment, look into the urlDoesContain rule, which would return true on the second sample even though it is a partial match. 180 | 181 | --- 182 | 183 | ### isResource() 184 | 185 | **Matches if a URL belongs to a specified resource.** 186 | This rule will mark an element as active if it is one of a given resource. Pass in the resource name and a prefix (if applicable). This allows you to match `https://domain.com/posts/create`, `https://domain.com/posts/1`, and `https://domain.com/posts/19/edit` with one rule. 187 | 188 | ``` 189 | Nav::isResource($resource, $prefix, $activeClass = "active", $strict) 190 | ``` 191 | 192 | **Parameters:** 193 | 194 | - `$resource` - REQUIRED | String 195 | The resource that you want to match. Must be equal to the value you provide in `Route::resource()` (but using this helper is not required or this to work). The resource in a url like `/posts/create` would be "posts" not "post". 196 | - `$prefix` - OPTIONAL | String 197 | This is the prefix if applicable. For example `/admin/posts/create`, would have a "admin" is the prefix. For deep prefixes like `/admin/manage/posts/create` you could submit _"admin.manage"_ or _"admin/manage"_ as a prefix. 198 | - `$activeClass` - OPTIONAL | String 199 | This defaults to the value defined under `default_class` in your config file or `"active"` if no config is generated 200 | - `$strict` - OPTIONAL | Boolean 201 | If set to **TRUE**, strict mode will be enabled, requiring that the search for this resource is at the beginning of the path. (See examples for more clarification) 202 | 203 | **Example 1:** 204 | 205 | ``` 206 | Current Url - https://domain.com/posts/1/edit 207 | --- 208 | 209 | {{ Nav::isResource('posts') }} // returns "active" [1] 210 | {{ Nav::isResource('posts', NULL, 'is-open') }} // returns "is-open" [2] 211 | {{ Nav::isResource('users') }} // returns "" [3] 212 | ``` 213 | 214 | (1) the current URL is of the "posts" resource, so returns default active class 215 | (2) current URL is of the "posts" resource, so returns the active class specified in third parameter. Second parameter of NULL tells it that no prefix exists for this resource. 216 | (3) Searching for the "users" resource, but the active URL is of the "posts" resource. So returns "". 217 | 218 | 219 | **Example 2:** 220 | 221 | Using prefixes 222 | 223 | ``` 224 | Current Url - https://domain.com/admin/posts/1/edit 225 | --- 226 | 227 | {{ Nav::isResource('posts') }} // returns "active", !IMPORTANT read notes [1] 228 | {{ Nav::isResource('posts', 'admin', 'is-active') }} // returns "is-active" [2] 229 | {{ Nav::isResource('posts', 'admin.manage') }} // returns "" [3] 230 | ``` 231 | 232 | (1) IMPORTANT just like without the prefix, this still returns the default active class. It still determines that this is a resource of "post". **However** this would also return true on a normal `domain.com/posts` or `domain.com/user/posts`. So if you want all of them to return as active, then do not use a prefix as in this example. But if you only want those with the "admin" prefix or the "users" prefix to return as active, then make sure the prefix is given in the second parameter to avoid these false positives. 233 | (2) current URL matches the "posts" resource with an "admin" prefix, so the active class provided in the 3rd parameter is returned, "is-active" 234 | (3) Even though this URL has the "admin" prefix, it will return "" because "admin.manage" or "admin/manage" is required. It doesn't matter if you use slashes or dots to denote layers. But the URL provided does not contain the "manage" layer, so this rule will return as not active. 235 | 236 | 237 | **Example 3:** 238 | 239 | Using Strict Mode can be tricky and confusing, but is very powerful if understood and used appropriately. 240 | 241 | ``` 242 | Current Url - https://domain.com/admin/manage/posts/1/edit 243 | --- 244 | 245 | {{ Nav::isResource('posts', NULL, NULL, TRUE) }} // returns "" [1] 246 | {{ Nav::isResource('posts', 'manage', 'is-active', TRUE) }} // returns "" [2] 247 | {{ Nav::isResource('posts', 'manage', NULL, FALSE) }} // returns "active" [3] 248 | {{ Nav::isResource('posts', 'admin.manage', NULL, TRUE) }} // returns "active" [4] 249 | ``` 250 | 251 | (1) returns as inactive, because while it is a "posts" resource, strict mode is enable. Meaning that the prefix has to match _AND_ it has to start at the beginning of the path (the part after the .com/). To enable strict mode, ensure that it is the 4th parameter. You might need to add NULL values, or fill in other values to get to a 4th parameter. 252 | (2) returns as inactive because _STRICT MODE_ indicates that the prefixes don't match perfectly from the start of the url path. (admin/manage is the strict prefix). 253 | (3) Exactly like (2) except that _STRICT MODE_ was disabled, meaning that it can now return as active. _STRICT MODE_ is disabled by default, so marking it as `FALSE` was unnecessary but achieves the same results. 254 | (4) Returns as active because both the resource _AND_ the prefix match _EXACTLY_, with _STRICT MODE_ enabled. 255 | 256 | --- 257 | 258 | ### urlDoesContain() 259 | 260 | This rule will match any existence of a string inside of the path. Be very careful with method as it can result in false positives if used inappropriately. 261 | 262 | ``` 263 | Nav::urlDoesContain($search, $activeClass = "active", $strict = FALSE) 264 | ``` 265 | 266 | **Parameters:** 267 | 268 | - `$search` - REQUIRED | String 269 | The value to search for inside of the URL, represented as a string. 270 | - `$activeClass` - OPTIONAL | String 271 | This defaults to the value defined under `default_class` in your config file or `"active"` if no config is generated 272 | - `$strict` - REQUIRED | Boolean 273 | If set to **TRUE**, strict mode will be enabled, requiring that the search from the beginning of the path. (See examples for more clarification) 274 | 275 | **Example:** 276 | 277 | ``` 278 | Current Url - https://domain.com/about/devmarketer/edit 279 | --- 280 | 281 | {{ Nav::hasSegment('about') }} // returns "active" [1] 282 | {{ Nav::hasSegment('devm', 'open') }} // returns "open" [2] 283 | {{ Nav::hasSegment('devmarketer', 'active', TRUE) }} // returns "" [3] 284 | {{ Nav::hasSegment('about/devmarketer', NULL, TRUE) }} // returns "active" [4] 285 | {{ Nav::hasSegment('about', NULL, TRUE) }} // returns "" [5] 286 | ``` 287 | 288 | (1) "about" is contained in the URL, so returns as active 289 | (2) "devm" is contained in the URL (even though its not a full segment). Be careful with this, as it can cause false positives if you are not careful. The active class provided is "open" so that is what is returned. 290 | (3) "devmarketer" is in the URL, but _STRICT MODE_ is also active and because the search term does not begin at the start of the path, it will return as inactive. 291 | (4) returns as active because _STRICT MODE_ is true, and "about/devmarketer" is at the start of the path even though the URL extends past the search term. 292 | (5) returns as active because "about" is contained in the url and with _STRICT MODE_ enabled, it still checks out because "about" is found at the start of the the url. 293 | 294 | ### Helper Functions 295 | 296 | In addition to the `Nav::method()` facade that we learned about, there are some helper functions you can use if you prefer to use helper functions. 297 | 298 | You can disable the helper functions if you do not want to load them, by changing the `enable_helper_functions` setting to `FALSE` in the `config/easynav.php` file. 299 | 300 | #### `navHasSegment($slugs, $segments, $activeClass)` 301 | 302 | This works exactly the same as `Nav::hasSegment()`. See the documentation above about how to use it. 303 | 304 | #### `navIsRoute($routeName, $activeClass)` 305 | 306 | This works exactly the same as `Nav::isRoute()`. See the documentation above about how to use it. 307 | 308 | #### `navIsResource($resource, $prefix, $activeClass, $strictMode)` 309 | 310 | This works exactly the same as `Nav::isResource()`. See the documentation above about how to use it. 311 | 312 | _Note: there is no helper function for the Nav::urlDoesContain() method. This method is too dangerous to be thrown around with a helper function._ 313 | 314 | --- 315 | 316 | ## Contribute 317 | 318 | I encourage you to contribute to this package to improve it and make it better. Even if you don't feel comfortable with coding or submitting a pull-request (PR), you can still support it by submitting issues with bugs or requesting new features, or simply helping discuss existing issues to give us your opinion and shape the progress of this package. 319 | 320 | [Read the full Contribution Guide](https://github.com/DevMarketer/LaraFlash/blob/master/CONTRIBUTING.md) 321 | 322 | ## Contact 323 | 324 | I would love to hear from you. I run the DevMarketer channel on YouTube, where we discuss how to _"Build and Grow Your Next Great Idea"_ please subscribe and check out the videos. 325 | 326 | I am always on Twitter, and it is a great way to communicate with me or follow me. [Check me out on Twitter](https://twitter.com/_jacurtis). 327 | 328 | You can also email me at hello@jacurtis.com for any other requests. 329 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "devmarketer/easynav", 3 | "description": "Making managing navigation in Laravel easy.", 4 | "keywords": ["nav", "easy", "laravel", "easynav", "helpers", "active"], 5 | "license": "MIT", 6 | "homepage": "https://github.com/DevMarketer/LaravelEasyNav", 7 | "support": { 8 | "issues": "https://github.com/DevMarketer/LaravelEasyNav/issues", 9 | "source": "https://github.com/DevMarketer/LaravelEasyNav" 10 | }, 11 | "authors": [ 12 | { 13 | "name": "J. Alexander Curtis", 14 | "email": "jalexandercurtis@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=5.5.0" 19 | }, 20 | "require-dev": { 21 | "mockery/mockery": "0.9.*", 22 | "phpunit/phpunit": "4.7.*" 23 | }, 24 | "autoload": { 25 | "psr-0": { 26 | "DevMarketer\\EasyNav": "src/" 27 | }, 28 | "files": [ 29 | "src/DevMarketer/EasyNav/functions.php" 30 | ] 31 | }, 32 | "extra": { 33 | "laravel": { 34 | "providers": [ 35 | "DevMarketer\\EasyNav\\EasyNavServiceProvider" 36 | ], 37 | "aliases": { 38 | "Nav": "DevMarketer\\EasyNav\\EasyNavFacade" 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DevMarketer/EasyNav/EasyNav.php: -------------------------------------------------------------------------------- 1 | request = $request; 39 | $this->or = false; 40 | } 41 | 42 | protected function dump() 43 | { 44 | dd($this->request); 45 | } 46 | 47 | /** 48 | * returns the active class if the defined segment exists 49 | * in the current request URI 50 | * 51 | * @param string|array $slugs 52 | * @param int|array $segments 53 | * @param string|NULL $active 54 | * @return string 55 | */ 56 | public function hasSegment($slugs, $segments = 1, $active = NULL) 57 | { 58 | $this->setActive($active); 59 | $segments = (!is_array($segments) ? [$segments] : $segments); 60 | $slugs = (!is_array($slugs) ? [$slugs] : $slugs); 61 | foreach ($slugs as $slug) { 62 | foreach ($segments as $segment) { 63 | if ($this->request->segment($segment) == $slug) return $this->active; 64 | } 65 | } 66 | return ''; 67 | } 68 | 69 | /** 70 | * Alias to $this->hasSegment() 71 | * 72 | * @param string|array $slugs 73 | * @param int|array $segments 74 | * @param string|NULL $active 75 | * @return string 76 | */ 77 | public function isSegment($slugs, $segments = 1, $active = NULL) 78 | { 79 | $this->hasSegment($slugs, $segments, $active); 80 | } 81 | 82 | /** 83 | * Receives a named route and returns true or false depending 84 | * if the current URL is equal to the named route provided. 85 | * 86 | * @param string $route 87 | * @param string|NULL $active 88 | * @return string 89 | */ 90 | public function isRoute($route, $active = NULL) 91 | { 92 | $this->setActive($active); 93 | return ($this->request->routeIs($route) ? $this->active : ''); 94 | } 95 | 96 | /** 97 | * Checks if current page is one of a specified resouce 98 | * provided in the function. Also accepts a prefix or strict 99 | * mode to optionally prevent false-positives 100 | * 101 | * @param string $resource 102 | * @param string|NULL $prefix 103 | * @param string $active 104 | * @param bool $strict 105 | * @return string 106 | */ 107 | public function isResource($resource, $prefix = NULL, $active = NULL, $strict = false) 108 | { 109 | $this->setActive($active); 110 | if ($prefix && is_string($prefix)) { 111 | $prefix = str_replace('.', '/', $prefix); 112 | $search = trim($prefix,'/').'/'.trim($resource, '/'); 113 | } else { 114 | $search = trim($resource, '/'); 115 | } 116 | return ($this->pathContains($search, $strict) ? $this->active : ''); 117 | } 118 | 119 | /** 120 | * This is basically an exposed (public) alias to $this->pathContains() 121 | * which checks a string inside the path 122 | * 123 | * @param string $route 124 | * @param string|NULL $active 125 | * @return string 126 | */ 127 | public function urlDoesContain($search, $active = NULL, $strict = false) 128 | { 129 | $this->setActive($active); 130 | return ($this->pathContains($search, $strict) ? $this->active : ''); 131 | } 132 | 133 | /** 134 | * Alias for $this->urlDoesContain() because URL is often spelled URI by mistake 135 | * 136 | * @param string $route 137 | * @param string|NULL $active 138 | * @return string 139 | */ 140 | public function uriDoesContain($search, $active = NULL, $strict = false) 141 | { 142 | return $this->urlDoesContain($search, $active, $strict); 143 | } 144 | 145 | 146 | 147 | /** 148 | * Does a needle in haystack search using the path (what comes after) 149 | * main domain and TLD. 150 | * 151 | * @param string $route 152 | * @param bool $strict // TRUE indicates that $needle must be found at the start of the path 153 | * @return bool 154 | */ 155 | private function pathContains($needle, $strict = false) 156 | { 157 | $needle = trim($needle, ' \\/'); //cleans up the needle in case someone passes in starting or trailing slashes 158 | $haystack = $this->request->path(); 159 | $existance = strpos($haystack, $needle); 160 | if ($existance !== false) { 161 | if ($strict) { 162 | return $existance === 0 ? true : false; 163 | } else { 164 | return true; 165 | } 166 | } else { 167 | return false; 168 | } 169 | } 170 | 171 | /** 172 | * Sets the active class to the value in the config file if 173 | * no value is passed with the function. 174 | * 175 | * @param string|NULL $active 176 | * @return $this 177 | */ 178 | private function setActive($active) 179 | { 180 | if ($active) { 181 | return $this->active = $active; 182 | } else { 183 | return $this->active = config('easynav.default_class'); 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/DevMarketer/EasyNav/EasyNavFacade.php: -------------------------------------------------------------------------------- 1 | publishes([ 25 | __DIR__.'/../../config/easynav.php' => config_path('easynav.php'), 26 | ], 'easynav'); 27 | } 28 | 29 | /** 30 | * Register the application services. 31 | * 32 | * @return void 33 | */ 34 | public function register() 35 | { 36 | $this->mergeConfigFrom( 37 | __DIR__.'/../../config/easynav.php', 'easynav' 38 | ); 39 | $this->app->bind('easynav', function($app) 40 | { 41 | return $this->app->make('DevMarketer\EasyNav\EasyNav'); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/DevMarketer/EasyNav/functions.php: -------------------------------------------------------------------------------- 1 | hasSegment($slugs, $segments, $active); 14 | } 15 | } 16 | 17 | if (! function_exists('navIsRoute')) { 18 | /** 19 | * Helper function to check if current page is equal to a 20 | * specified named route 21 | * 22 | * @param string $route 23 | * @param string|null $options 24 | * @return string 25 | */ 26 | function navIsRoute($route, $active = null) 27 | { 28 | $easynav = app('easynav'); 29 | return $easynav->isRoute($route, $active); 30 | } 31 | } 32 | 33 | if (! function_exists('navIsResource')) { 34 | /** 35 | * Helper function to check if current page is one of a 36 | * specified resource 37 | * 38 | * @param string $resource 39 | * @param string|NULL $prefix 40 | * @param string|NULL $active 41 | * @param bool $strict 42 | * @return string 43 | */ 44 | function navIsResource($resource, $prefix = NULL, $active = NULL, $strict = false) 45 | { 46 | $easynav = app('easynav'); 47 | return $easynav->isResource($resource, $prefix, $active, $strict); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/config/easynav.php: -------------------------------------------------------------------------------- 1 | 'active', 21 | 22 | ]; 23 | --------------------------------------------------------------------------------