glhd/gretel

1.8.0 2024-03-12 20:05 UTC

This package is auto-updated.

Last update: 2024-09-12 21:13:38 UTC


README

Gretel from the story 'Hansel and Gretel' holding bread behind her back

Build Status Coverage Status Latest Stable Release MIT Licensed Follow @inxilpro on Twitter

Gretel

像童话故事一样的Laravel面包屑。

Gretel是一个Laravel包,用于向您的应用程序添加基于路由的面包屑。

安装

composer require glhd/gretel

用法

定义面包屑

Gretel添加了一个新的路由宏,您可以在定义路由时使用它

单个面包屑

在简单的情况下,将 breadcrumb() 函数链到您现有的路由上以定义一个面包屑

Route::get('/', HomeController::class)
  ->name('home')
  ->breadcrumb('Home');

Homepage Example

如果您需要动态控制标题,请传递一个闭包

Route::get('/dashboard', DashboardController::class)
  ->name('dashboard')
  ->breadcrumb(fn() => Auth::user()->name.'’s dashboard');

Dashboard Example

嵌套面包屑

除非将它们串联起来,否则面包屑并不很有用。Gretel通过指向之前定义的父面包屑来处理嵌套面包屑

Route::get('/users', [UserController::class, 'index'])
  ->name('users.index')
  ->breadcrumb('Users');
  
Route::get('/users/{user}', [UserController::class, 'show'])
  ->name('users.show')
  ->breadcrumb(fn(User $user) => $user->name, 'users.index');

Route::get('/users/{user}/edit', [UserController::class, 'edit'])
  ->name('users.edit')
  ->breadcrumb('Edit', 'users.show');

Nested Route Example

在这里,您可以看到我们的 users.show 路由引用了 users.index 作为其父级。这样,当您为 users.show 渲染面包屑时,它也会显示 users.index 的面包屑。

Gretel假设嵌套路由中的参数可以安全地用于其父路由。在这个例子中,users.edit 将使用为编辑操作解析的 User 值渲染 users.show 面包屑。在大多数情况下,这正是您想要的。如果不这样做,您可以覆盖此行为(见下文)。

父级缩写

通常,子路由会引用具有相同名称前缀的父级。在我们的上述示例中,users.show 引用了 users.index,而 users.edit 引用了 users.show。在这种情况下,您可以使用父级缩写

Route::get('/admin/users/{user}/notes/create', [NotesController::class, 'create'])
  ->name('admin.users.notes.create')
  ->breadcrumb('Add Note', '.index'); // shorthand for "admin.users.notes.index"

这对于具有许多深层嵌套路由的大型应用程序非常有用。

浅层嵌套路由

如果您的嵌套路由不包含父路由所需的必要路由参数,您需要向Gretel提供这些值。您可以通过使用第三个回调来实现这一点

Route::get('/companies/{company}', [CompanyController::class, 'show'])
  ->name('companies.show')
  ->breadcrumb(fn(Company $company) => $company->name);

Route::get('/users/{user}', [UserController::class, 'show'])
  ->name('users.show')
  ->breadcrumb(fn(User $user) => $user->name, 'companies.show', fn(User $user) => $user->company);

Shallow Nested Example

资源路由

您还可以为资源控制器定义面包屑。index()create()show()edit() 方法的行为与常规面包屑辅助函数完全一样,只是如果您没有提供父级,它们会自动为您设置父级。

Route::resource('users', UserController::class)
  ->breadcrumbs(function(ResourceBreadcrumbs $breadcrumbs) {
    $breadcrumbs
      ->index('Users')
      ->create('New User')
      ->show(fn(User $user) => $user->name)
      ->edit('Edit');
  });

如果您愿意,您还可以使用数组语法来表示简单的资源路由

Route::resource('users', UserController::class)
  ->breadcrumbs([
    'index' => 'Users',
    'create' => 'New User',
    'show' => fn(User $user) => $user->name,
    'edit' => 'Edit',
  ]);

供应商路由

有时您想为定义在第三方包中的路由注册面包屑。在这种情况下,您可以直接使用 Gretel 门面。API与 Route::breadcrumb() 方法完全相同,但您必须将路由名称作为第一个参数传递

Gretel::breadcrumb(
  'teams.show', // Route name
  fn(Team $team) => $team->name, // Title callback
  'profile.show', // Parent
);

显示面包屑

您可以使用 <x-breadcrumbs /> Blade组件来显示当前路由的面包屑。Blade组件接受一些可选属性

支持的框架

Gretel支持大多数常见的CSS框架。我们已经为CSS框架的文档标记添加了额外的 aria- 标签,以提供更好的可访问性。当前支持的框架

Tailwind 使用 "tailwind"(默认)

Tailwind theme

Materialize 使用 "materialize"

Materialize theme

Bootstrap 5 使用 "bootstrap5"

Bootstrap 5 theme

Bulma 使用 "bulma"

Bulma theme

Semantic UI 使用 "semantic-ui"

Semantic UI theme

Primer 使用 "primer"

Primer theme

Foundation 6 使用 "foundation6"

Foundation 6 theme

UIKit 使用 "uikit"

UIKit theme

旧框架

一些框架的旧版本也是可用的

您通常需要在应用程序布局的某个位置包含 <x-breadcrumbs /> 标签(如果您使用 JSON-LD,可能需要两次)

layouts/app.blade.php:

<!DOCTYPE html>
<html>
<head>
    <title>{{ $title }}</title>
    <x-breadcrumbs jsonld />
</head>
<body>
<div class="container mx-auto">
    <x-breadcrumbs framework="tailwind" />
    ...
</div>
</body>
</html>

自定义面包屑视图

您可以通过发布 gretel.php 配置文件通过 php artisan vendor:publish 或通过向 Blade 组件传递一个 view 属性来渲染自定义视图

<x-breadcrumbs view="app.breadcrumbs" />

以其他方式使用面包屑

如果您需要以其他方式使用面包屑——例如,通过一个 Gretel 没有集成的客户端框架进行渲染——您可以从路由中获取当前的面包屑作为 Collectionarray

Route::breadcrumbs()->toCollection();  // Collection of `Breadcrumb` objects
Route::breadcrumbs()->toArray();       // Array of `Breadcrumb` objects
Route::breadcrumbs()->jsonSerialize(); // Array of breadcrumb arrays (title, url, is_current_page)
Route::breadcrumbs()->toJson();        // JSON string of breadcrumbs matching jsonSerialize

例如,我们的 Inertia.js 集成 可以很容易地实现

Inertia::share('breadcrumbs', function(Request $request) {
    return $request->route()->breadcrumbs()->jsonSerialize();
});
可访问性

如果您选择渲染自己的视图,请确保遵循当前 WAI-ARIA 可访问性最佳实践。Gretel 提供了一些助手使这变得更容易

@unless ($breadcrumbs->isEmpty())
  <!-- Wrap your breadcrumbs in a <nav> element with an aria-label attribute -->
  <nav aria-label="Breadcrumb">
    <!-- Use an <ol> (ordered list) for the breadcrumb items -->
    <ol>
      @foreach ($breadcrumbs as $breadcrumb)
        <!-- You can use $activeClass() or $inactiveClass() to conditionally apply classes -->
        <li class="{{ $activeClass('active-breadcrumb') }}">
          <!-- Use $ariaCurrent() to apply aria-current="page" to the active breadcrumb -->
            <a href="{{ $breadcrumb->url }}" {{ $ariaCurrent() }}>
              {{ $breadcrumb->title }}
            </a>
        </li>
      @endforeach
    </ol>
  </nav>
@endunless

缓存面包屑

由于 Gretel 面包屑与您的路由一起注册,因此如果您缓存了路由,则需要缓存您的面包屑。您可以使用以下两个命令来完成此操作

# Cache breadcrumbs
php artisan breadcrumbs:cache

# Clear cached breadcrumbs
php artisan breadcrumbs:clear

请注意,您必须在缓存路由之前缓存面包屑

处理错误

有时您可能会错误配置面包屑或忘记定义它们。您可以在 Gretel 门面注册处理程序来处理这些情况

// Log or report a missing breadcrumb (will always receive a MissingBreadcrumbException instance)
Gretel::handleMissingBreadcrumbs(function(MissingBreadcrumbException $exception) {
  Log::warning($exception->getMessage());
});

// Throw an exception locally if there's a missing breadcrumb
Gretel::throwOnMissingBreadcrumbs(! App::environment('production'));

// Log or report a mis-configured breadcrumb (i.e. a parent route that doesn't exist).
// This handler will pick up any other exception that is triggered while trying to configure
// or render your breadcrumbs, so the type is unknown.
Gretel::handleMisconfiguredBreadcrumbs(function(Throwable $exception) {
  Log::warning($exception->getMessage());
});

// Throw an exception locally if there's a mis-configured breadcrumb
Gretel::throwOnMisconfiguredBreadcrumbs(! App::environment('production'));

与第三方包集成

如果您安装了该包,Gretel 将自动 与 Inertia.js 共享您的面包屑。您不需要进行任何操作即可启用此集成。(如果出于某种原因您不希望此行为,您可以通过发布 Gretel 配置来禁用它。)

您的面包屑将在客户端代码中作为 breadcrumbs 提供,并看起来像这样

const breadcrumbs = [
  {
    title: 'Home',
    url: 'https://www.yourapp.com',
    is_current_page: false,
  }, {
    title: 'Users',
    url: 'https://www.yourapp.com/users',
    is_current_page: false,
  }, {
    title: 'Add a User',
    url: 'https://www.yourapp.com/users/create',
    is_current_page: true,
  }
];

然后您可以根据需要以客户端渲染面包屑。请务必查看 自定义面包屑 部分,了解如何确保客户端面包屑完全可访问。