{"id":15027853,"url":"https://github.com/mimmi20/mezzio-navigation","last_synced_at":"2025-07-05T19:05:30.656Z","repository":{"id":45434314,"uuid":"299284485","full_name":"mimmi20/mezzio-navigation","owner":"mimmi20","description":"a Navigation component for Mezzio","archived":false,"fork":false,"pushed_at":"2025-07-01T05:51:32.000Z","size":1070,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-01T06:30:33.069Z","etag":null,"topics":["mezzio","mezzio-navigation","php83"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mimmi20.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-09-28T11:18:54.000Z","updated_at":"2025-07-01T05:51:36.000Z","dependencies_parsed_at":"2024-11-07T04:27:52.002Z","dependency_job_id":"3cde0db0-5ae8-4585-a422-eb0e31e5e26d","html_url":"https://github.com/mimmi20/mezzio-navigation","commit_stats":{"total_commits":212,"total_committers":3,"mean_commits":70.66666666666667,"dds":"0.37264150943396224","last_synced_commit":"4469e9765cd0a092c0ddeb1280ceadfe689a0729"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":"mimmi20/template","purl":"pkg:github/mimmi20/mezzio-navigation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimmi20%2Fmezzio-navigation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimmi20%2Fmezzio-navigation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimmi20%2Fmezzio-navigation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimmi20%2Fmezzio-navigation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mimmi20","download_url":"https://codeload.github.com/mimmi20/mezzio-navigation/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mimmi20%2Fmezzio-navigation/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262915676,"owners_count":23383847,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mezzio","mezzio-navigation","php83"],"created_at":"2024-09-24T20:07:11.121Z","updated_at":"2025-07-05T19:05:30.620Z","avatar_url":"https://github.com/mimmi20.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mezzio-navigation\n\n[![Latest Stable Version](https://poser.pugx.org/mimmi20/mezzio-navigation/v/stable?format=flat-square)](https://packagist.org/packages/mimmi20/mezzio-navigation)\n[![Latest Unstable Version](https://poser.pugx.org/mimmi20/mezzio-navigation/v/unstable?format=flat-square)](https://packagist.org/packages/mimmi20/mezzio-navigation)\n[![License](https://poser.pugx.org/mimmi20/mezzio-navigation/license?format=flat-square)](https://packagist.org/packages/mimmi20/mezzio-navigation)\n\n## Code Status\n\n[![codecov](https://codecov.io/gh/mimmi20/mezzio-navigation/branch/master/graph/badge.svg)](https://codecov.io/gh/mimmi20/mezzio-navigation)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/3d4958aa28643e3646ec/test_coverage)](https://codeclimate.com/github/mimmi20/mezzio-navigation/test_coverage)\n[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/mimmi20/mezzio-navigation.svg)](https://isitmaintained.com/project/mimmi20/mezzio-navigation \"Average time to resolve an issue\")\n[![Percentage of issues still open](https://isitmaintained.com/badge/open/mimmi20/mezzio-navigation.svg)](https://isitmaintained.com/project/mimmi20/mezzio-navigation \"Percentage of issues still open\")\n[![Mutation testing badge](https://img.shields.io/endpoint?style=flat\u0026url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fmimmi20%2Fmezzio-navigation%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/mimmi20/mezzio-navigation/master)\n[![Maintainability](https://api.codeclimate.com/v1/badges/3d4958aa28643e3646ec/maintainability)](https://codeclimate.com/github/mimmi20/mezzio-navigation/maintainability)\n\n## Introduction\n\nThis component provides a component for managing trees of pointers to web pages.\nSimply put: It can be used for creating menus, breadcrumbs, links, and sitemaps,\nor serve as a model for other navigation related purposes.\n\nUnlike in [laminas-navigation](https://github.com/laminas/laminas-navigation) \nthis library provides a middleware which is required to prepare the navigation.\n\n## Installation\n\nYou can install the mezzio-navigation library with\n[Composer](https://getcomposer.org):\n\n```bash\ncomposer require mimmi20/mezzio-navigation\n```\n\n## Pages and Containers\n\nThere are two main concepts in mezzio-navigation: pages and containers.\n\n### Pages\n\nA page in mezzio-navigation, in its most basic\nform, is an object that holds a pointer to a web page. In addition to the\npointer itself, the page object contains a number of other properties that are\ntypically relevant for navigation, such as `label`, `title`, etc.\n\nRead more about pages in the [pages](#pages) section.\n\n### Containers\n\nA navigation container holds pages. It has\nmethods for adding, retrieving, deleting and iterating pages. It implements the\n[SPL](http://php.net/spl) interfaces `RecursiveIterator` and `Countable`, and\ncan thus be iterated with SPL iterators such as `RecursiveIteratorIterator`.\n\nRead more about containers in the [containers](#containers) section.\n\n\u003e ### Pages are containers\n\u003e\n\u003e `Mezzio\\Navigation\\PageInterface` extends `Mezzio\\Navigation\\ContainerInterface`,\n\u003e which means that a page can have sub pages.\n\n## View Helpers\n\n### Separation of data (model) and rendering (view)\n\nClasses in the mezzio-navigation namespace do not deal with rendering of\nnavigational elements.  Rendering is done with navigational view helpers.\nHowever, pages contain information that is used by view helpers when rendering,\nsuch as `label`, `class` (CSS), `title`, `lastmod`, and `priority` properties\nfor sitemaps, etc.\n\nWe provide one rendering libary.\n\n- The Renderer using Laminas View is provided by [mezzio-navigation-laminasviewrenderer](https://github.com/mimmi20/mezzio-navigation-laminasviewrenderer/).\n\nThe renderer is installable via [Composer](https://getcomposer.org):\n\n```bash\ncomposer require mimmi20/mezzio-navigation-laminasviewrenderer\n```\n\n## Containers\n\nContainers have methods for adding, retrieving, deleting, and iterating pages.\nContainers implement the [SPL](http://php.net/spl) interfaces\n`RecursiveIterator` and `Countable`, meaning that a container can be iterated\nusing the SPL `RecursiveIteratorIterator` class.\n\n### Creating containers\n\n`Mezzio\\Navigation\\ContainerInterface` can not be instantiated directly. Use\n`Mezzio\\Navigation\\Navigation` if you want to instantiate a container.\n\n`Mezzio\\Navigation\\Navigation` can be constructed entirely empty, or take an array\nor a `Traversable` object with pages to put in the container. Each page provided\nvia options will eventually be passed to the `addPage()` method of the container\nclass, which means that each element in the options can be also be an array,\nTraversable object, or a `Mezzio\\Navigation\\Page\\PageInterface` instance.\n\n#### Creating a container using an array\n\n\u003e Unlike in [Laminas Navigation](https://github.com/laminas/laminas-navigation) it is not possible\n\u003e to add an arrray config to Mezzio Navigation directly. Converting an array config into a list of\n\u003e Page objects is made in the Navigation Factories.\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Navigation;\nuse Mimmi20\\Mezzio\\Navigation\\Config\\NavigationConfigInterface;\n\n/*\n * Create a container from an array\n */\n$navigationConfig = $serviceLocator-\u003eget(NavigationConfigInterface::class);\n$navigationConfig-\u003esetPages([\n    [\n        'label' =\u003e 'Page 1',\n        'id' =\u003e 'home-link',\n        'uri' =\u003e '/',\n    ],\n    [\n        'label' =\u003e 'Laminas',\n        'uri' =\u003e 'http://www.laminas-project.com/',\n        'order' =\u003e 100,\n    ],\n    [\n        'label' =\u003e 'Page 2',\n        'route' =\u003e 'page2',\n    ],\n]);\n$container = $serviceLocator-\u003eget(Navigation::class);\n```\n\n### Adding pages\n\nAdding pages to a container can be done with the methods `addPage()`,\n`addPages()`, or `setPages()`.  See examples below for explanation.\n\n\u003e Unlike in [Laminas Navigation](https://github.com/laminas/laminas-navigation) only objects implementing\n\u003e the PageInterface are allowed. The PageFactory may be used to use an array config.\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Navigation;\nuse Mimmi20\\Mezzio\\Navigation\\Page\\PageFactory;\n\n// create container\n$container = new Navigation();\n\n// add page by giving a page instance\n$container-\u003eaddPage(new Class implements PageInterface{});\n\n// add page by giving a page instance using the PageFactory\n$container-\u003eaddPage((new PageFactory())-\u003efactory([\n    'uri' =\u003e 'http://www.example.com/',\n]));\n\n$pages = [\n    new Class implements PageInterface{},\n    new Class implements PageInterface{},\n];\n\n// add two pages\n$container-\u003eaddPages($pages);\n\n// remove existing pages and add the given pages\n$container-\u003esetPages($pages);\n```\n\n### Removing pages\n\nRemoving pages can be done with `removePage()` or `removePages()`.\n`removePage()` accepts an instance of a page or an integer. Integer arguments\ncorrespond to the `order` a page has. `removePages()` will remove all pages in\nthe container.\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Navigation;\n\n$navigationConfig = $serviceLocator-\u003eget(NavigationConfigInterface::class);\n$navigationConfig-\u003esetPages([\n    [\n        'label'  =\u003e 'Page 1',\n        'action' =\u003e 'page1',\n    ],\n    [\n        'label'  =\u003e 'Page 2',\n        'action' =\u003e 'page2',\n        'order'  =\u003e 200,\n    ],\n    [\n        'label'  =\u003e 'Page 3',\n        'action' =\u003e 'page3',\n    ],\n]);\n$container = $serviceLocator-\u003eget(Navigation::class);\n\n// remove page by implicit page order\n$container-\u003eremovePage(0);      // removes Page 1\n\n// remove page by instance\n$page3 = $container-\u003efindOneByAction('page3');\n$container-\u003eremovePage($page3); // removes Page 3\n\n// remove page by explicit page order\n$container-\u003eremovePage(200);    // removes Page 2\n\n// remove all pages\n$container-\u003eremovePages();      // removes all pages\n```\n\n#### Remove a page recursively\n\nRemoving a page recursively can be done with the second parameter of\nthe `removePage()` method, which expects a `boolean` value.\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Navigation;\n\n$navigationConfig = $serviceLocator-\u003eget(NavigationConfigInterface::class);\n$navigationConfig-\u003esetPages(\n    [\n        [\n            'label' =\u003e 'Page 1',\n            'route' =\u003e 'page1',\n            'pages' =\u003e [\n                [\n                    'label' =\u003e 'Page 1.1',\n                    'route' =\u003e 'page1/page1-1',\n                    'pages' =\u003e [\n                        [\n                            'label' =\u003e 'Page 1.1.1',\n                            'route' =\u003e 'page1/page1-1/page1-1-1',\n                        ],\n                    ],\n                ],\n            ],\n        ],\n    ]\n);\n$container = $serviceLocator-\u003eget(Navigation::class);\n\n// Removes Page 1.1.1\n$container-\u003eremovePage(\n    $container-\u003efindOneBy('route', 'page1/page1-1/page1-1-1'),\n    true\n);\n```\n\n### Finding pages\n\nContainers have two finder methods for retrieving pages. Each recursively\nsearches the container testing for properties with values that match the one\nprovided.\n\n- `findOneBy($property, $value) : PageInterface|null`: Returns the first page\n  found matching the criteria, or `null` if none was found.\n- `findAllBy($property, $value) : array\u003cPageInterface\u003e`: Returns an array of all\n  page instances matching the criteria.\n\n\u003e Unlike in [Laminas Navigation](https://github.com/laminas/laminas-navigation) the `findBy` is not available.\n\nThe finder methods can also be used magically by appending the property name to\n`findBy`, `findOneBy`, or `findAllBy`. As an example, `findOneByLabel('Home')`\nwill return the first matching page with label 'Home'.\n\nOther combinations include `findByLabel(...)`, `findOneByTitle(...)`,\n`findAllByController(...)`, etc. Finder methods also work on custom properties,\nsuch as `findByFoo('bar')`.\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Navigation;\n\n$navigationConfig = $serviceLocator-\u003eget(NavigationConfigInterface::class);\n$navigationConfig-\u003esetPages([\n    [\n        'label' =\u003e 'Page 1',\n        'uri'   =\u003e 'page-1',\n        'foo'   =\u003e 'bar',\n        'pages' =\u003e [\n            [\n                'label' =\u003e 'Page 1.1',\n                'uri'   =\u003e 'page-1.1',\n                'foo'   =\u003e 'bar',\n            ],\n            [\n                'label' =\u003e 'Page 1.2',\n                'uri'   =\u003e 'page-1.2',\n                'class' =\u003e 'my-class',\n            ],\n            [\n                'type'   =\u003e 'uri',\n                'label'  =\u003e 'Page 1.3',\n                'uri'    =\u003e 'page-1.3',\n            ],\n        ],\n    ],\n    [\n        'label'      =\u003e 'Page 2',\n        'id'         =\u003e 'page_2_and_3',\n        'class'      =\u003e 'my-class',\n        'route'      =\u003e 'index1',\n    ],\n    [\n        'label'      =\u003e 'Page 3',\n        'id'         =\u003e 'page_2_and_3',\n        'route'      =\u003e 'index2',\n    ],\n]);\n$container = $serviceLocator-\u003eget(Navigation::class);\n\n// The 'id' is not required to be unique, but be aware that\n// having two pages with the same id will render the same id attribute\n// in menus and breadcrumbs.\n\n// Returns \"Page 2\":\n$found = $container-\u003efindBy('id', 'page_2_and_3');\n\n// Returns \"Page 2\":\n$found = $container-\u003efindOneBy('id', 'page_2_and_3');\n\n// Returns \"Page 2\":\n$found = $container-\u003efindOneById('page_2_and_3');\n\n// Returns \"Page 2\" AND \"Page 3\":\n$found = $container-\u003efindAllById('page_2_and_3');\n\n// Find all pages matching the CSS class \"my-class\":\n// Returns \"Page 1.2\" and \"Page 2\":\n$found = $container-\u003efindAllBy('class', 'my-class');\n$found = $container-\u003efindAllByClass('my-class');\n\n// Find first page matching CSS class \"my-class\":\n// Returns \"Page 1.2\":\n$found = $container-\u003efindOneByClass('my-class');\n\n// Find all pages matching the CSS class \"non-existent\":\n// Returns an empty array.\n$found = $container-\u003efindAllByClass('non-existent');\n\n// Find first page matching the CSS class \"non-existent\":\n// Returns null.\n$found = $container-\u003efindOneByClass('non-existent');\n\n// Find all pages with custom property 'foo' = 'bar':\n// Returns \"Page 1\" and \"Page 1.1\":\n$found = $container-\u003efindAllBy('foo', 'bar');\n\n// To achieve the same magically, 'foo' must be in lowercase.\n// This is because 'foo' is a custom property, and thus the\n// property name is not normalized to 'Foo':\n$found = $container-\u003efindAllByfoo('bar');\n\n// Find all with controller = 'index':\n// Returns \"Page 2\" and \"Page 3\":\n$found = $container-\u003efindAllByController('index');\n```\n\n### Iterating containers\n\n`Mezzio\\Navigation\\ContainerInterface` extends `RecursiveIterator`.  iterate a\ncontainer recursively, use the `RecursiveIteratorIterator` class.\n\n```php\nuse RecursiveIteratorIterator;\nuse Mimmi20\\Mezzio\\Navigation\\Navigation;\n\n/*\n * Create a container from an array\n */\n$navigationConfig = $serviceLocator-\u003eget(NavigationConfigInterface::class);\n$navigationConfig-\u003esetPages([\n    [\n        'label' =\u003e 'Page 1',\n        'uri'   =\u003e '#',\n    ],\n    [\n        'label' =\u003e 'Page 2',\n        'uri'   =\u003e '#',\n        'pages' =\u003e [\n            [\n                'label' =\u003e 'Page 2.1',\n                'uri'   =\u003e '#',\n            ],\n            [\n                'label' =\u003e 'Page 2.2',\n                'uri'   =\u003e '#',\n            ],\n        ],\n    ],\n    [\n        'label' =\u003e 'Page 3',\n        'uri'   =\u003e '#',\n    ],\n]);\n$container = $serviceLocator-\u003eget(Navigation::class);\n\n// Iterate flat using regular foreach:\n// Output: Page 1, Page 2, Page 3\nforeach ($container as $page) {\n    echo $page-\u003elabel;\n}\n\n// Iterate recursively using RecursiveIteratorIterator\n$it = new RecursiveIteratorIterator(\n    $container,\n    RecursiveIteratorIterator::SELF_FIRST\n);\n\n// Output: Page 1, Page 2, Page 2.1, Page 2.2, Page 3\nforeach ($it as $page) {\n    echo $page-\u003elabel;\n}\n```\n\n### Other operations\n\n#### hasPage\n\n```php\nhasPage(PageInterface $page) : bool\n```\n\nCheck if the container has the given page.\n\n#### hasPages\n\n```php\nhasPages() : bool\n```\n\nChecks if there are any pages in the container, and is equivalent to\n`count($container) \u003e 0`.\n\n#### toArray\n\n```php\ntoArray() : array\n```\n\nConverts the container and the pages in it to a (nested) array. This can be useful\nfor serializing and debugging.\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Navigation;\n\n$navigationConfig = $serviceLocator-\u003eget(NavigationConfigInterface::class);\n$navigationConfig-\u003esetPages([\n    [\n        'label' =\u003e 'Page 1',\n        'uri'   =\u003e '#',\n    ],\n    [\n        'label' =\u003e 'Page 2',\n        'uri'   =\u003e '#',\n        'pages' =\u003e [\n            [\n                'label' =\u003e 'Page 2.1',\n                'uri'   =\u003e '#',\n            ],\n            [\n                'label' =\u003e 'Page 2.2',\n                'uri'   =\u003e '#',\n            ],\n        ],\n    ],\n]);\n$container = $serviceLocator-\u003eget(Navigation::class);\n\nvar_dump($container-\u003etoArray());\n\n/* Output:\narray(2) {\n  [0]=\u003e array(15) {\n    [\"label\"]=\u003e string(6) \"Page 1\"\n    [\"id\"]=\u003e NULL\n    [\"class\"]=\u003e NULL\n    [\"title\"]=\u003e NULL\n    [\"target\"]=\u003e NULL\n    [\"rel\"]=\u003e array(0) {\n    }\n    [\"rev\"]=\u003e array(0) {\n    }\n    [\"order\"]=\u003e NULL\n    [\"resource\"]=\u003e NULL\n    [\"privilege\"]=\u003e NULL\n    [\"active\"]=\u003e bool(false)\n    [\"visible\"]=\u003e bool(true)\n    [\"type\"]=\u003e string(23) \"Mezzio\\Navigation\\Page\\Uri\"\n    [\"pages\"]=\u003e array(0) {\n    }\n    [\"uri\"]=\u003e string(1) \"#\"\n  }\n  [1]=\u003e array(15) {\n    [\"label\"]=\u003e string(6) \"Page 2\"\n    [\"id\"]=\u003e NULL\n    [\"class\"]=\u003e NULL\n    [\"title\"]=\u003e NULL\n    [\"target\"]=\u003e NULL\n    [\"rel\"]=\u003e array(0) {\n    }\n    [\"rev\"]=\u003e array(0) {\n    }\n    [\"order\"]=\u003e NULL\n    [\"resource\"]=\u003e NULL\n    [\"privilege\"]=\u003e NULL\n    [\"active\"]=\u003e bool(false)\n    [\"visible\"]=\u003e bool(true)\n    [\"type\"]=\u003e string(23) \"Mezzio\\Navigation\\Page\\Uri\"\n    [\"pages\"]=\u003e array(2) {\n      [0]=\u003e array(15) {\n        [\"label\"]=\u003e string(8) \"Page 2.1\"\n        [\"id\"]=\u003e NULL\n        [\"class\"]=\u003e NULL\n        [\"title\"]=\u003e NULL\n        [\"target\"]=\u003e NULL\n        [\"rel\"]=\u003e array(0) {\n        }\n        [\"rev\"]=\u003e array(0) {\n        }\n        [\"order\"]=\u003e NULL\n        [\"resource\"]=\u003e NULL\n        [\"privilege\"]=\u003e NULL\n        [\"active\"]=\u003e bool(false)\n        [\"visible\"]=\u003e bool(true)\n        [\"type\"]=\u003e string(23) \"Mezzio\\Navigation\\Page\\Uri\"\n        [\"pages\"]=\u003e array(0) {\n        }\n        [\"uri\"]=\u003e string(1) \"#\"\n      }\n      [1]=\u003e\n      array(15) {\n        [\"label\"]=\u003e string(8) \"Page 2.2\"\n        [\"id\"]=\u003e NULL\n        [\"class\"]=\u003e NULL\n        [\"title\"]=\u003e NULL\n        [\"target\"]=\u003e NULL\n        [\"rel\"]=\u003e array(0) {\n        }\n        [\"rev\"]=\u003e array(0) {\n        }\n        [\"order\"]=\u003e NULL\n        [\"resource\"]=\u003e NULL\n        [\"privilege\"]=\u003e NULL\n        [\"active\"]=\u003e bool(false)\n        [\"visible\"]=\u003e bool(true)\n        [\"type\"]=\u003e string(23) \"Mezzio\\Navigation\\Page\\Uri\"\n        [\"pages\"]=\u003e array(0) {\n        }\n        [\"uri\"]=\u003e string(1) \"#\"\n      }\n    }\n    [\"uri\"]=\u003e string(1) \"#\"\n  }\n}\n*/\n```\n\n## Pages\n\nmezzio-navigation ships with two page types:\n\n- [Route pages](#route-pages), using the class `Mezzio\\Navigation\\Page\\Route`\n- [URI pages](#uri-pages), using the class `Mezzio\\Navigation\\Page\\Uri`\n\nRoute pages link to on-site web pages, and are defined using Route parameters\n(`route`, `params`). URI pages are defined by a single\nproperty `uri`, which give you the full flexibility to link off-site pages or do\nother things with the generated links (e.g. a URI that turns into `\u003ca href=\"#\"\u003efoo\u003ca\u003e`).\n\n\u003e Route Pages replace the MVC Pages from [Laminas Navigation](https://github.com/laminas/laminas-navigation).\n\u003e \n\u003e Unlike in [Laminas Navigation](https://github.com/laminas/laminas-navigation) the options `controller` and `action`\n\u003e are not supported, \n\n### Common page features\n\nAll page classes must extend `Mezzio\\Navigation\\Page\\PageInterface`, and will thus\nshare a common set of features and properties. Most notably, they share the\noptions in the table below and the same initialization process.\n\nOption keys are mapped to `set*()` methods. This means that the option `order` maps to the method\n`setOrder()`, and `reset_params` maps to the method `setResetParams()`. If there is no setter\nmethod for the option, it will be set as a custom property of the page.\n\nRead more on extending `Mezzio\\Navigation\\Page\\PageInterface` in the section\n[\"Creating custom page types\"](#creating-custom-page-types).\n\n### Common page options\n\n| Key       | Type                        | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                 |\n|-----------|-----------------------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| label     | `string`                    | `NULL`  | A page label, such as 'Home' or 'Blog'.                                                                                                                                                                                                                                                                                                                                                                                                                     |\n| fragment  | `string\\|null`              | `NULL`  | A fragment identifier (anchor identifier) pointing to an anchor within a resource that is subordinate to another, primary resource. The fragment identifier introduced by a hash mark \"#\". Example: ``http://www.example.org/foo.html#bar`` (*bar* is the fragment identifier)                                                                                                                                                                              |\n| id        | `string\\|integer`           | `NULL`  | An *id* tag/attribute that may be used when rendering the page, typically in an anchor element.                                                                                                                                                                                                                                                                                                                                                             |\n| class     | `string`                    | `NULL`  | A *CSS* class that may be used when rendering the page, typically in an anchor element.                                                                                                                                                                                                                                                                                                                                                                     |\n| liClass   | `string`                    | `NULL`  | A *CSS* class that may be used when rendering the page, typically in an li element around the anchor element.                                                                                                                                                                                                                                                                                                                                               |\n| title     | `string`                    | `NULL`  | A short page description, typically for using as the title attribute in an anchor.                                                                                                                                                                                                                                                                                                                                                                          |\n| target    | `string`                    | `NULL`  | Specifies a target that may be used for the page, typically in an anchor element.                                                                                                                                                                                                                                                                                                                                                                           |\n| rel       | `array`                     | `[]`    | Specifies forward relations for the page. Each element in the array is a key-value pair, where the key designates the relation/link type, and the value is a pointer to the linked page. An example of a key-value pair is ``'alternate' =\u003e 'format/plain.html'``. To allow full flexibility, there are no restrictions on relation values. The value does not have to be a string. Read more about ``rel`` and ``rev`` in the section on the Links helper. |\n| rev       | `array`                     | `[]`    | Specifies reverse relations for the page. Works exactly like rel.                                                                                                                                                                                                                                                                                                                                                                                           |\n| order     | `string\\|integer\\|null`     | `NULL`  | Works like order for elements in ``Laminas\\Form``. If specified, the page will be iterated in a specific order, meaning you can force a page to be iterated before others by setting the order attribute to a low number, e.g. -100. If a String is given, it must parse to a valid int. If ``NULL`` is given, it will be reset, meaning the order in which the page was added to the container will be used.                                               |\n| privilege | `string\\|null`              | `NULL`  | privilege to associate with the page. Read more in the section on ACL integration in view helpers.                                                                                                                                                                                                                                                                                                                                                          |\n| active    | `boolean`                   | `FALSE` | Whether the page should be considered active for the current request. If active is FALSE or not given, MVC pages will check its properties against the request object upon calling ``$page-\u003eisActive()``.                                                                                                                                                                                                                                                   |\n| visible   | `boolean`                   | `TRUE`  | Whether page should be visible for the user, or just be a part of the structure. Invisible pages are skipped by view helpers.                                                                                                                                                                                                                                                                                                                               |\n| pages     | `array\\|Travsersable\\|null` | `NULL`  | Child pages of the page. This could be an array or `Traversable` object containing either page options that can be passed to the `factory()` method, `PageInterface` instances, or a mixture of both.                                                                                                                                                                                                                                                       |\n\n\u003e #### Custom properties\n\u003e\n\u003e All pages support setting and retrieval of custom properties by use of the\n\u003e magic methods `__set($name, $value)`, `__get($name)`, `__isset($name)` and\n\u003e `__unset($name)`. Custom properties may have any value, and will be included\n\u003e in the array that is returned from `$page-\u003etoArray()`, which means that pages\n\u003e can be serialized/deserialized successfully even if the pages contains\n\u003e properties that are not native in the page class.\n\u003e\n\u003e Both native and custom properties can be set using `$page-\u003eset($name, $value)`\n\u003e and retrieved using `$page-\u003eget($name)`, or by using magic methods.\n\u003e \n\u003e The following example demonstrates custom properties:\n\u003e\n\u003e ```php\n\u003e $page = new Mimmi20\\Mezzio\\Navigation\\Page\\Route();\n\u003e $page-\u003efoo     = 'bar';\n\u003e $page-\u003emeaning = 42;\n\u003e\n\u003e echo $page-\u003efoo;\n\u003e\n\u003e if ($page-\u003emeaning != 42) {\n\u003e     // action should be taken\n\u003e }\n\u003e ```\n\n### Route pages\n\nRoutes can be used with Route pages. If a page has a route, this route will be\nused in `getHref()` to generate `href` attributes, and the `isActive()` method will compare the\n`Mezzio\\Router\\RouteResult` params with the page's params to determine if the page\nis active.\n\n#### useRouteMatch flag\n\nIf you want to re-use any matched route parameters\nwhen generating a link, you can do so via the `useRouteMatch` flag. This is\nparticularly useful when creating segment routes that include the currently\nselected language or locale as an initial segment, as it ensures the links\ngenerated all include the matched value.\n\n#### Route page options\n\n| Key           | Type                            | Default | Description                                                                                    |\n|---------------|---------------------------------|---------|------------------------------------------------------------------------------------------------|\n| params        | `array`                         | `[]`    | User params to use when generating `href` to the page.                                         |\n| route         | `string`                        | `NULL`  | Route name to use when generating `href` to the page.                                          |\n| routeMatch    | `Mezzio\\Router\\RouteResult`     | `NULL`  | `RouteInterface` matches used for routing parameters and testing validity.                     |\n| useRouteMatch | `boolean`                       | `FALSE` | If true, then the `getHref()` method will use the `routeMatch` parameters to assemble the URI. |\n| router        | `Mezzio\\Router\\RouterInterface` | `NULL`  | Router for assembling URLs.                                                                    |\n| query         | `array`                         | `[]`    | Query string arguments to use when generating `href` to page.                                  |\n\n#### isActive() determines if page is active\n\nThis example demonstrates that Route pages determine whether they are active by\nusing the params found in the route match object.\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Page;\n\n/**\n * Dispatched request:\n * - route:     index\n */\n$page1 = new Page\\Route([\n    'route' =\u003e 'index',\n]);\n\n$page2 = new Page\\Route([\n    'route' =\u003e 'edit',\n]);\n\n$page1-\u003eisActive(); // returns true\n$page2-\u003eisActive(); // returns false\n\n/**\n * Dispatched request:\n * - route:      edit\n * - id:         1337\n */\n$page = new Page\\Route([\n    'route'  =\u003e 'edit',\n    'params' =\u003e ['id' =\u003e 1337],\n]);\n\n// returns true, because request has the same route\n$page-\u003eisActive();\n\n/**\n * Dispatched request:\n * - route:     edit\n */\n$page = new Page\\Route([\n    'route'  =\u003e 'edit',\n    'params' =\u003e ['id' =\u003e null],\n]);\n\n// returns false, because page requires the id param to be set in the request\n$page-\u003eisActive(); // returns false\n```\n\n### URI Pages\n\nPages of type `Mezzio\\Navigation\\Page\\Uri` can be used to link to pages on other\ndomains or sites, or to implement custom logic for the page. In addition to the\ncommon page options, a URI page takes only one additional option, a `uri`. The\n`uri` will be returned when calling `$page-\u003egetHref()`, and may be a `string` or\n`null`.\n\n\u003e ### No auto-determination of active status\n\u003e\n\u003e `Mezzio\\Navigation\\Page\\Uri` will not try to determine whether it should be\n\u003e active when calling `$page-\u003eisActive()`; it merely returns what currently is\n\u003e set. In order to make a URI page active, you must manually call\n\u003e `$page-\u003esetActive()` or specify the `active` as a page option during\n\u003e instantiation.\n\n#### URI page options\n\n| Key      | Type           | Default | Description                                                                                   |\n|----------|----------------|---------|-----------------------------------------------------------------------------------------------|\n| uri      | `string`       | `NULL`  | URI to page. This can be any string or `NULL`.                                                |\n| resource | `string\\|null` | `NULL`  | resource to associate with the page. Read more in the section on integration in view helpers. |\n\n### Creating custom page types\n\nWhen implementing `Mezzio\\Navigation\\Page\\PageInterface` and using the `Mezzio\\Navigation\\Page\\PageTrait`, there is usually no need to\noverride the constructor or the `setOptions()` method. The page constructor\ntakes a single parameter, an `iterable`, which is then\npassed to `setOptions()`. That method will in turn call the appropriate `set*()`\nmethods based on the options provided, which in turn maps the option to native\nor custom properties. If the option `internal_id` is given, the method will\nfirst look for a method named `setInternalId()`, and pass the option to this\nmethod if it exists. If the method does not exist, the option will be set as a\ncustom property of the page, and be accessible via `$internalId =\n$page-\u003einternal_id;` or `$internalId = $page-\u003eget('internal_id');`.\n\n#### Basic custom page example\n\nThe only thing a custom page class needs to implement is the `getHref()` method.\n\n```php\nnamespace My;\n\nuse Mimmi20\\Mezzio\\Navigation\\Page\\PageInterface;\nuse Mimmi20\\Mezzio\\Navigation\\Page\\PageTrait;\n\nclass Page implements PageInterface\n{\n    use PageTrait;\n    public function getHref(): string\n    {\n        return 'something-completely-different';\n    }\n}\n```\n\n#### A custom page with properties\n\nWhen adding properties to an extended page, there is no need to override/modify\n`setOptions()`.\n\n```php\nnamespace My\\Navigation;\n\nuse Mimmi20\\Mezzio\\Navigation\\Page\\PageInterface;\n\nclass Page implements PageInterface\n{\n    protected $foo;\n    protected $fooBar;\n\n    public function setFoo($foo)\n    {\n        $this-\u003efoo = $foo;\n    }\n\n    public function getFoo()\n    {\n        return $this-\u003efoo;\n    }\n\n    public function setFooBar($fooBar)\n    {\n        $this-\u003efooBar = $fooBar;\n    }\n\n    public function getFooBar()\n    {\n        return $this-\u003efooBar;\n    }\n\n    public function getHref(): string\n    {\n        return sprintf('%s/%s', $this-\u003efoo, $this-\u003efooBar);\n    }\n}\n\n// Instantiation:\n$page = new Page([\n    'label'   =\u003e 'Property names are mapped to setters',\n    'foo'     =\u003e 'bar',\n    'foo_bar' =\u003e 'baz',\n]);\n```\n\n### Creating pages using the page factory\n\nAll pages (also custom classes), can be created using the page factory,\n`Mezzio\\Navigation\\Page\\PageFactory`. The factory accepts either an\n`iterable` set of options.  Each key in the options corresponds to a\npage option, as seen earlier.  If the option `uri` is given and no Route options\nare provided (`route`), a URI page will be\ncreated. If any of the Route options are given, an Route page will be created.\n\nIf `type` is given, the factory will assume the value to be the name of the\nclass that should be created. If the value is `route` or `uri`, an Route or URI page\nwill be created, respectively.\n\n#### Creating an Route page using the page factory\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Page\\PageInterface;\n\n// Route page, as \"route\" is defined\n$page = (new PageFactory())-\u003efactory([\n    'label' =\u003e 'Home',\n    'route' =\u003e 'home',\n]);\n\n// Route page, as \"type\" is \"route\"\n$page = (new PageFactory())-\u003efactory([\n    'type'   =\u003e 'route',\n    'label'  =\u003e 'My Route page',\n]);\n```\n\n#### Creating a URI page using the page factory\n\n```php\nuse Mimmi20\\Mezzio\\Navigation\\Page\\PageInterface;\n\n// URI page, as \"uri\" is present, with now MVC options\n$page = (new PageFactory())-\u003efactory([\n    'label' =\u003e 'My URI page',\n    'uri'   =\u003e 'http://www.example.com/',\n]);\n\n// URI page, as \"uri\" is present\n$page = (new PageFactory())-\u003efactory([\n    'label'  =\u003e 'Search',\n    'uri'    =\u003e 'http://www.example.com/search',\n    'active' =\u003e true,\n]);\n\n// URI page, as \"uri\" is present\n$page = (new PageFactory())-\u003efactory([\n    'label' =\u003e 'My URI page',\n    'uri'   =\u003e '#',\n]);\n\n// URI page, as \"type\" is \"uri\"\n$page = (new PageFactory())-\u003efactory([\n    'type'  =\u003e 'uri',\n    'label' =\u003e 'My URI page',\n]);\n```\n\n#### Creating a custom page type using the page factory\n\nTo create a custom page type using the factory, use the option `type` to specify\na class name to instantiate.\n\n```php\nnamespace My\\Navigation;\n\nuse Mimmi20\\Mezzio\\Navigation\\Page\\PageInterface;\n\nclass Page extends PageInterface\n{\n    protected $fooBar = 'ok';\n\n    public function setFooBar($fooBar)\n    {\n        $this-\u003efooBar = $fooBar;\n    }\n}\n\n// Creates Page instance, as \"type\" refers to its class.\n$page = (new PageFactory())-\u003efactory([\n    'type'    =\u003e Page::class,\n    'label'   =\u003e 'My custom page',\n    'foo_bar' =\u003e 'foo bar',\n]);\n```\n\n## Quick Start\n\n### Usage in a mezzio-based application\n\nThe fastest way to get up and running with mezzio-navigation is:\n\n- Register mezzio-navigation or use the Component Installer.\n- Add the Middleware to the Pipeline.\n- Define navigation container configuration under the top-level `navigation` key\n  in your application configuration.\n- Render your container using a navigation view helper within your view scripts.\n\n#### Register mezzio-navigation\n\nEdit the application configuration file `config/config.php`:\n\n```php\n\u003c?php\n// ...\n$aggregator = new ConfigAggregator(\n    [\n        // ...\n        \\Mimmi20\\Mezzio\\Navigation\\ConfigProvider::class, // \u003c-- Add this line\n        // ...\n    ],\n    $cacheConfig['config_cache_path'],\n);\n```\n\n#### Add the NavigationMiddleware to the pipeline\n\n```php\n\u003c?php\nreturn [\n    'middleware' =\u003e [\n        'Mezzio\\Authentication\\AuthenticationMiddleware', // \u003c-- not required\n        'Mimmi20\\Mezzio\\Navigation\\NavigationMiddleware', // \u003c-- Add this line\n        // ...\n    ],\n];\n```\n\nIf you need the Navigation inside the Layout, and the Layout is used also for the Not-Found-Page, you have to add the Middleware in the Pipeline before the Routing.\n\n```php\n    $app-\u003epipe(\\Mimmi20\\Mezzio\\Navigation\\NavigationMiddleware::class); // \u003c-- Add this line\n\n    // Register the routing middleware in the middleware pipeline.\n    // This middleware registers the Mezzio\\Router\\RouteResult request attribute.\n    $app-\u003epipe(RouteMiddleware::class);\n```\n\n#### Navigation container configuration\n\nAdd the container definition to your configuration file, e.g.\n`config/autoload/global.php`:\n\n```php\n\u003c?php\nreturn [\n    // ...\n\n    'navigation' =\u003e [\n        'default' =\u003e [\n            [\n                'label' =\u003e 'Home',\n                'route' =\u003e 'home',\n            ],\n            [\n                'label' =\u003e 'Page #1',\n                'route' =\u003e 'page-1',\n                'pages' =\u003e [\n                    [\n                        'label' =\u003e 'Child #1',\n                        'route' =\u003e 'page-1-child',\n                    ],\n                ],\n            ],\n            [\n                'label' =\u003e 'Page #2',\n                'route' =\u003e 'page-2',\n            ],\n        ],\n    ],\n    // ...\n];\n```\n\n#### Render the navigation\n\nMezzio support multiple view renders. \n\nOne renderer is available:\n\n- [mezzio-navigation-laminasviewrenderer](https://github.com/mimmi20/mezzio-navigation-laminasviewrenderer/),\n  which implements ([Mezzios LaminasViewRenderer](https://github.com//mezzio/mezzio-laminasviewrenderer))\n\n## License\n\nThis package is licensed using the MIT License.\n\nPlease have a look at [`LICENSE.md`](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmimmi20%2Fmezzio-navigation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmimmi20%2Fmezzio-navigation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmimmi20%2Fmezzio-navigation/lists"}