builtbybuilder / easynavplus
让 Laravel 的导航管理变得简单。
Requires
- php: >=5.5.0
Requires (Dev)
- mockery/mockery: 0.9.*
- phpunit/phpunit: 4.7.*
README
每当我构建另一个 Laravel 应用时,我都会发现自己正在重复使用我多年来一直在完善的相同自定义导航助手。这些工具允许您根据当前页面准确简洁地更改导航元素上的类。这样的工具可以让您的导航自我管理,加快开发进度,但同时也适用于长期的生产使用。
安装
安装简单,设置与其它 Laravel 包类似。
1. 使用 Composer 安装
首先通过 Composer 引入包。
composer require builtbybuilder/easynavplus
2. 定义服务提供者和别名
接下来我们需要引入别名和服务提供者。
注意: 此包支持 Laravel 5.5 的新 自动发现 功能,因此如果您正在使用 Laravel 5.5 项目,则安装已完成,您可以跳到步骤 3。
如果您使用 Laravel 5.0 - 5.4,则需要添加提供者和别名。在您的 config/app.php
文件中定义一个新的服务提供者
'providers' => [
// other providers
BuiltByBuilder\EasyNavPlus\EasyNavPlusServiceProvider::class,
];
然后在同一 config/app.php
文件中定义一个别名。
'aliases' => [
// other aliases
'Nav' => BuiltByBuilder\EasyNavPlus\EasyNavPlusFacade::class,
];
3. 发布配置文件(可选)
配置文件允许您覆盖此包的默认设置以满足您的特定需求。它是可选的,允许您设置默认的活动类名以输出到活动导航元素。您可以在每个函数中覆盖此值,但设置默认值可以使您的代码更简洁。默认为 "active"
,这是许多开发者常用的类名,并且 支持 Bootstrap。如果您使用像 Bulma 这样的框架,则希望将此值更改为 "is-active"
。许多 CSS 框架可能需要 "--active"
。设置一次即可。
在终端中输入以下命令以生成配置文件
php artisan vendor:publish --tag=easynavplus
这将在 config/easynavplus.php
生成一个配置文件。
使用方法
此包易于使用。它提供了一组有助于导航的有用函数。将每个方法视为定义导航元素规则的“工具”。一旦为该导航元素设置了 “规则”,您就不必担心它。如果用户根据规则访问该页面,则它将输出您定义的 CSS 类(通常是 "active"
或 "is-active"
),这将使导航显示活动状态。
[重要] 此包不做什么
此包不生成导航的 HTML。它仅根据您定义的规则向 HTML 元素添加“活动”CSS 类。您需要在 CSS 中自定义活动菜单/导航链接的外观。
导航规则是如何工作的
对于每个导航元素,您将在 HTML 元素的 class=" "
字段中添加以下“规则”之一。您仍需负责在 CSS 中设置元素样式。许多 CSS 框架已经为您完成了这项工作。
示例
Current Url - https://domain.com/posts/laravel-is-awesome
---
<nav>
<ul class="navigation">
<li class="{{ Nav::isRoute('home') }}">Home</li>
<li class="{{ Nav::isResource('posts') }}">Posts</li> // This one will render a class of "active" to the <li></li>
<li class="{{ Nav::hasSegment('about')}}">About</li>
<li class="{{ Nav::urlContains('contact') }}">Contact</li>
</ul>
</nav>
此示例显示了如何将 4 个不同的“规则”相互连接来定义何时某个导航元素应该接收“活动”类。
记住:您仍需负责设置元素的样式!此插件仅根据您定义的规则动态地向元素添加活动类。
现在您已经看到这个在实际中的工作方式,让我们分别查看每个 规则,以了解如何定义它。
isRoute() - 匹配命名路由
此规则会将元素标记为活动状态,如果当前页面匹配指定的命名路由。
Nav::isRoute($routeName, $activeClass = "active")
参数
$routeName
- 必需的字符串
这是您希望匹配的命名路由。它必须与运行php artisan route:list
时注册在 "name" 列中的值匹配。$activeClass
- 可选的字符串
默认值为您的配置文件中default_class
下定义的值或未生成配置时的"active"
。
示例
Current Url - https://domain.com/contact
---
Routes File:
Route::get('contact', 'BaseController@contact')->name('contact');
---
{{ Nav::isRoute('contact') }} // returns "active" [1]
{{ Nav::isRoute('contact', 'is-open') }} // returns "is-open" [2]
{{ Nav::isRoute('about') }} // returns "" [3]
(1) 字符串 "contact" 与也是 "contact" 的命名路由匹配,因此返回默认活动类
(2) "contact" 与我们目前所在的命名路由匹配,因此返回第二个参数中提供的活动类,"is-open" (3) "about" 与我们目前所在的 "contact" 路由不匹配,因此返回 ""
hasSegment() - 匹配定义的段
此规则会将元素标记为活动状态,如果提供的字符串与提供的段匹配。这对于定义父元素非常有用,如果您希望标记任何子元素为活动状态。
Nav::hasSegment($slugs, $segments = 1, $activeClass = "active")
参数
$slug
- 必需的 | 字符串或字符串数组
这是我们尝试匹配的值。如果您想匹配多个字符串,请传递一个字符串数组。注意,这类似于一个OR
,||
子句。如果其中任何一个匹配,它就返回 true。$segments
- 可选的 | 整数或整数数组
这定义了将$slug
与哪个段匹配。如果没有提供,默认为第一个段。使用整数(从 1 开始)来定义段。段的值表示为:https://domainDoesntCount.com/1/2/3/4
。由于 Laravel 请求的限制,您只能定义到第 4 个段的段。如果您想扫描多个段,请传递一个整数数组以检查任何这些段(类似于一个OR
,||
子句)。$activeClass
- 可选的 | 字符串
默认值为您的配置文件中default_class
下定义的值或未生成配置时的"active"
。
示例
Current Url - https://domain.com/posts/created-by/builtbybuilder
---
{{ Nav::hasSegment('posts') }} // returns "active" [1]
{{ Nav::hasSegment('posts', 2) }} // returns "" [2]
{{ Nav::hasSegment('builtbybuilder', [2,3], 'is-active') }} // returns "active" [3]
{{ Nav::hasSegment(['builtbybuilder', 'jacurtis'], [2,3]) }} // returns "active" [4]
{{ Nav::hasSegment('posts', [2,3]) }} // returns "" [5]
(1) "posts" 在第一个段(默认段)中,因此返回默认活动类
(2) "posts" 不在第二个段中,因此返回 nothing
(3) 检查 "builtbybuilder" 是否在第二个或第三个段中。它在第三个段中,因此返回提供的活动类,"is-active"
(4) 检查 "builtbybuilder" 或 "jacurtis" 是否在第二个或第三个段中。 "builtbybuilder" 在第三个段中,因此返回默认活动类
(5) 检查 "posts" 是否在第二个或第三个段中,返回 nothing。
示例 2
它只匹配整个段。
Current Url - https://domain.com/example/text/segments
---
{{ Nav::hasSegment('example') }} // returns "active"
{{ Nav::hasSegment('exam') }} // returns ""
在第一个示例中,它工作是因为 "example" 是一个完整的段。但是第二个示例不工作,因为尽管 "exam" 包含在第一个段 "example" 中,但它不匹配整个段。
如果您想匹配段的某个部分,请查看 urlDoesContain 规则,它会在第二个示例中返回 true,即使它是一个部分匹配。
isResource()
如果 URL 属于指定的资源,则匹配。
此规则会将元素标记为活动状态,如果它是给定资源之一。传递资源名称和(如果适用)前缀。这允许您使用一个规则匹配 https://domain.com/posts/create
,https://domain.com/posts/1
和 https://domain.com/posts/19/edit
。
Nav::isResource($resource, $prefix, $activeClass = "active", $strict)
参数
$resource
- 必需的 | 字符串
您要匹配的资源。必须等于您在Route::resource()
中提供的值(但使用此辅助器不是必需的,以便此规则工作)。在类似/posts/create
的 URL 中的资源是 "posts" 而不是 "post"。$prefix
- 可选的 | 字符串
如果适用,这是前缀。例如,对于/admin/posts/create
,"admin" 就是前缀。对于深层前缀如/admin/manage/posts/create
,你可以提交 "admin.manage" 或 "admin/manage" 作为前缀。$activeClass
- 可选的 | 字符串
默认值为您的配置文件中default_class
下定义的值或未生成配置时的"active"
。$strict
- 可选 | 布尔类型
如果设置为 TRUE,则将启用严格模式,要求对资源的搜索必须位于路径的开头。(见示例以了解更多说明)
示例 1
Current Url - https://domain.com/posts/1/edit
---
{{ Nav::isResource('posts') }} // returns "active" [1]
{{ Nav::isResource('posts', NULL, 'is-open') }} // returns "is-open" [2]
{{ Nav::isResource('users') }} // returns "" [3]
(1) 当前 URL 是 "posts" 资源,因此返回默认活动类
(2) 当前 URL 是 "posts" 资源,因此返回第三参数中指定的活动类。第二个参数为 NULL 表示该资源不存在前缀。
(3) 搜索 "users" 资源,但活动 URL 是 "posts" 资源。因此返回 ""。
示例 2
使用前缀
Current Url - https://domain.com/admin/posts/1/edit
---
{{ Nav::isResource('posts') }} // returns "active", !IMPORTANT read notes [1]
{{ Nav::isResource('posts', 'admin', 'is-active') }} // returns "is-active" [2]
{{ Nav::isResource('posts', 'admin.manage') }} // returns "" [3]
(1) 重要:就像没有前缀一样,这仍然返回默认活动类。它仍然确定这是一个 "posts" 资源。但是,这也会在正常 domain.com/posts
或 domain.com/user/posts
上返回 true。所以如果你希望所有这些都返回活动状态,则不要使用前缀,如本示例所示。但是,如果你只想让带有 "admin" 前缀或 "users" 前缀的资源返回活动状态,则确保在第二个参数中提供前缀,以避免这些假阳性。
(2) 当前 URL 与带有 "admin" 前缀的 "posts" 资源匹配,因此返回第三参数中提供的活动类,即 "is-active"。
(3) 即使此 URL 有 "admin" 前缀,因为它需要 "admin.manage" 或 "admin/manage",所以它将返回 ""。无论您使用斜杠还是点来表示层级都没有关系。但是,提供的 URL 不包含 "manage" 层,因此此规则将返回非活动状态。
示例 3
使用严格模式可能会很棘手且令人困惑,但如果我们理解和正确使用,它将非常强大。
Current Url - https://domain.com/admin/manage/posts/1/edit
---
{{ Nav::isResource('posts', NULL, NULL, TRUE) }} // returns "" [1]
{{ Nav::isResource('posts', 'manage', 'is-active', TRUE) }} // returns "" [2]
{{ Nav::isResource('posts', 'manage', NULL, FALSE) }} // returns "active" [3]
{{ Nav::isResource('posts', 'admin.manage', NULL, TRUE) }} // returns "active" [4]
(1) 返回非活动状态,因为虽然它是 "posts" 资源,但严格模式已启用。这意味着前缀必须匹配并且必须位于路径的开头(.com/后面的部分)。要启用严格模式,请确保它是第四个参数。您可能需要添加 NULL 值或填充其他值以到达第四个参数。
(2) 返回非活动状态,因为 严格模式 指示前缀与 URL 路径的起始部分不完美匹配(admin/manage 是严格前缀)。
(3) 与 (2) 完全相同,除了 严格模式 已禁用,这意味着它可以现在返回活动状态。《严格模式》默认禁用,因此将其标记为 FALSE
是不必要的,但达到了相同的结果。
(4) 返回活动状态,因为资源 和 前缀与 完全 匹配,并且已启用 严格模式。
urlDoesContain()
此规则将匹配路径中字符串的存在。请务必小心使用此方法,因为它如果使用不当可能会导致假阳性。
Nav::urlDoesContain($search, $activeClass = "active", $strict = FALSE)
参数
$search
- 必需 | 字符串
要在 URL 中搜索的值,表示为字符串。$activeClass
- 可选的 | 字符串
默认值为您的配置文件中default_class
下定义的值或未生成配置时的"active"
。$strict
- 必需 | 布尔类型
如果设置为 TRUE,则将启用严格模式,要求从路径的开始进行搜索。(见示例以了解更多说明)
示例
Current Url - https://domain.com/about/builtbybuilder/edit
---
{{ Nav::hasSegment('about') }} // returns "active" [1]
{{ Nav::hasSegment('devm', 'open') }} // returns "open" [2]
{{ Nav::hasSegment('builtbybuilder', 'active', TRUE) }} // returns "" [3]
{{ Nav::hasSegment('about/builtbybuilder', NULL, TRUE) }} // returns "active" [4]
{{ Nav::hasSegment('about', NULL, TRUE) }} // returns "" [5]
(1) "about" 包含在 URL 中,因此返回活动状态
(2) "devm" 包含在 URL 中(即使它不是一个完整的段)。请小心,因为这可能会在不小心的情况下导致假阳性。提供的活动类是 "open",因此返回的就是这个。
(3) "builtbybuilder" 在 URL 中,但 严格模式 也已启用,因为搜索词没有从路径的开始部分开始,所以将返回非活动状态。
(4) 返回为激活状态,因为 严格模式 为 true,并且尽管 URL 超出了搜索词,但 "about/builtbybuilder" 仍在路径的开头。
(5) 返回为激活状态,因为 URL 中包含 "about",并且启用 严格模式 后,仍然进行检查,因为 "about" 被发现在 URL 的开头。
辅助函数
除了我们所学到的 Nav::method()
门面之外,还有一些辅助函数您可以使用,如果您更喜欢使用辅助函数。
如果您不想加载辅助函数,可以更改 config/easynavplus.php
文件中的 enable_helper_functions
设置为 FALSE
以禁用辅助函数。
navHasSegment($slugs, $segments, $activeClass)
这与 Nav::hasSegment()
完全相同。请参阅上面的文档了解如何使用它。
navIsRoute($routeName, $activeClass)
这与 Nav::isRoute()
完全相同。请参阅上面的文档了解如何使用它。
navIsResource($resource, $prefix, $activeClass, $strictMode)
这与 Nav::isResource()
完全相同。请参阅上面的文档了解如何使用它。
注意:没有为 Nav::urlDoesContain() 方法提供辅助函数。这个方法太危险,不适合与辅助函数一起使用。
贡献
我鼓励您为此包做出贡献,以改进它并使其变得更好。即使您不擅长编码或提交拉取请求(PR),您仍然可以通过提交有关错误的报告、请求新功能或简单地帮助讨论现有问题来支持它,以提供您的意见并塑造此包的进步。
联系
我非常乐意收到您的来信。我在 YouTube 上运营 DevMarketer 频道,我们讨论如何 "构建和扩展您的下一个伟大想法" 请订阅并查看视频。
我在 Twitter 上也总是活跃的,这是与我沟通或关注我的好方法。 在 Twitter 上查看我。
您也可以通过 hello@jacurtis.com 发送电子邮件,提出其他请求。