{"id":15046418,"url":"https://github.com/tattersoftware/codeigniter4-menus","last_synced_at":"2025-10-26T20:32:32.425Z","repository":{"id":39970657,"uuid":"356740576","full_name":"tattersoftware/codeigniter4-menus","owner":"tattersoftware","description":"Dynamic menus for CodeIgniter 4","archived":false,"fork":false,"pushed_at":"2024-01-18T13:45:05.000Z","size":103,"stargazers_count":14,"open_issues_count":3,"forks_count":4,"subscribers_count":4,"default_branch":"develop","last_synced_at":"2025-02-01T00:26:40.170Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/tattersoftware.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null}},"created_at":"2021-04-11T01:38:51.000Z","updated_at":"2024-02-16T20:01:15.000Z","dependencies_parsed_at":"2022-08-20T15:20:07.028Z","dependency_job_id":null,"html_url":"https://github.com/tattersoftware/codeigniter4-menus","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tattersoftware%2Fcodeigniter4-menus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tattersoftware%2Fcodeigniter4-menus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tattersoftware%2Fcodeigniter4-menus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tattersoftware%2Fcodeigniter4-menus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tattersoftware","download_url":"https://codeload.github.com/tattersoftware/codeigniter4-menus/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238397257,"owners_count":19465145,"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":[],"created_at":"2024-09-24T20:53:05.181Z","updated_at":"2025-10-26T20:32:32.008Z","avatar_url":"https://github.com/tattersoftware.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tatter\\Menus\nDynamic menus for CodeIgniter 4\n\n[![](https://github.com/tattersoftware/codeigniter4-menus/workflows/PHPUnit/badge.svg)](https://github.com/tattersoftware/codeigniter4-menus/actions?query=workflow%3A%22PHPUnit%22)\n[![](https://github.com/tattersoftware/codeigniter4-menus/workflows/PHPStan/badge.svg)](https://github.com/tattersoftware/codeigniter4-menus/actions?query=workflow%3A%PHPStan%22)\n[![Coverage Status](https://coveralls.io/repos/github/tattersoftware/codeigniter4-menus/badge.svg?branch=develop)](https://coveralls.io/github/tattersoftware/codeigniter4-menus?branch=develop)\n\n## Quick Start\n\n1. Install with Composer: `\u003e composer require tatter/menus`\n2. Create your menus by extending `Tatter\\Menus\\Menu`\n3. Add your menu aliases to `Config\\Menus`\n4. Apply `MenuFilter` to all routes that need menus\n\n## Features\n\n**Menus** provides dynamic menus across your application. **Menus** organizes and injects the\nmenu content, so you can focus on building.\n\n## Installation\n\nInstall easily via Composer to take advantage of CodeIgniter 4's autoloading capabilities\nand always be up-to-date:\n* `\u003e composer require tatter/menus`\n\nOr, install manually by downloading the source files and adding the directory to\n`app/Config/Autoload.php`.\n\n## Configuration (optional)\n\nThe library's default behavior can be altered by extending its config file. Copy\n**examples/Menus.php** to **app/Config/** and follow the instructions\nin the comments. If no config file is found in app/Config the library will use its own.\n\n## Usage\n\n### Building\n\n**Menus** is built on `Spatie\\Menu` with all of its wonderful, dynamic and fluent functionality.\nUse their documentation to craft your menus as simple or complex as you like:\n* [Version 2](https://spatie.be/docs/menu/v2)\n* [Version 3](https://spatie.be/docs/menu/v3) (PHP 8 only)\n\nCreate your menus by extending `Tatter\\Menus\\Menu`. You will notice in the source code that\n`Menu` requires you to provide one method: `public function __toString(): string;`. You may use the\nsupplied `$builder` property to access the underlying `Spatie\\Menu` to build your menu,\nor provide your own HTML code or `view()` return. Some examples:\n```\nclass MainMenu extends \\Tatter\\Menus\\Menu\n{\n\tpublic function __toString(): string\n\t{\n\t\treturn $this-\u003ebuilder\n\t\t\t-\u003elink(site_url('/'), 'Home')\n\t\t\t-\u003elink(site_url('/about'), 'About')\n\t\t\t-\u003ehtml('\u003chr\u003e')\n\t\t\t-\u003elink(site_url('/contact'), 'Contact')\n\t\t\t-\u003erender();\n\t}\n}\n\nclass FruitMenu extends \\Tatter\\Menus\\Menu\n{\n\tpublic function __toString(): string\n\t{\n\t\treturn view('menus/fruit', ['active' =\u003e 'banana']);\n\t}\n}\n```\n\nNote: `$builder` is initialized with \"set active\" to the current URL. You may call `setActive()`\nagain to remove or change the active menu item. Due to a limitation in `Spatie\\Menu` with mixing\nrelative and absolute URLs you must supply full URL values (e.g. with `site_url()`) to your\n`Menu` if you want to use this default \"active\" URL.\n\n### Deploying\n\nSince `Menu` is `Stringable` it can be used in your view or layout files as is.\nHowever, **Menus** also comes with a [Controller Filter](https://codeigniter4.github.io/CodeIgniter4/incoming/filters.html)\nthat you can use to inject menu content directly into your responses. First you need to create\nan alias for each `Menu` class you would like to use. Create **app/Config/Menus.php** (or\nstart with a copy from the **examples** folder) and add your menu classes to the `$aliases`\narray. For example:\n```\nclass Menus extends \\Tatter\\Menus\\Config\\Menus\n{\n\t/**\n\t * Menu class aliases.\n\t *\n\t * @var array\u003cstring, string\u003e\n\t */\n\tpublic $aliases = [\n\t\t'main'  =\u003e \\App\\Menus\\MainMenu::class,\n\t\t'fruit' =\u003e \\ShopModule\\FruitMenu::class,\n\t];\n}\n```\n\nOnce aliases are set up you can pass them as an argument to the `MenuFilter` for any route:\n```\n$routes-\u003eadd('shop/(:any)', 'ShopModule\\ShopController::show/$1', ['filter' =\u003e 'menus:fruit']);\n```\n\nThen in your view or layout put the placeholder token with the name of the alias target in\ndouble curly braces:\n```\n\u003chtml\u003e\n\t\u003cbody\u003e\n\t\t{{main}}\n\t\t\u003ch1\u003eFruit Shop\u003c/h1\u003e\n\t\t{{fruit}}\n...\n```\n\nNote that sometimes it is preferable to apply the filter in bulk using **app/Config/Filters.php**.\nUnfortunately parameters are [not yet supported](https://github.com/codeigniter4/CodeIgniter4/issues/2078)\nin `Config\\Filters`, but you can work around this by creating your own parameter-specific Filter:\n```\n\u003c?php namespace App\\Filters;\n\nuse CodeIgniter\\HTTP\\RequestInterface;\nuse CodeIgniter\\HTTP\\ResponseInterface;\nuse Tatter\\Menus\\Filters\\MenusFilter;\n\nclass MainMenuFilter extends MenusFilter\n{\n\tpublic function after(RequestInterface $request, ResponseInterface $response, $arguments = null): ?ResponseInterface\n\t{\n\t\treturn parent::after($request, $response, ['main', 'fruit']);\n\t}\n}\n```\n\n## Packaged Menus\n\n`Menus` comes with some pre-made menus which can be used immediately or built on to create\nyour own variants. All menus are in the `Tatter\\Menus\\Menus` namespace and extend the `Menu`\nclass so can be used with the Filter or as any other menu you would make.\n\n### Breadcrumbs\n\nThe `BreadcrumbsMenu` is a special menu, using horizontal-style navigation links for nested\ncontent. This menu comes pre-styled for [Bootstrap](https://getbootstrap.com/docs/4.3/components/breadcrumb/)\nand defaults to the segments retrieved from the framework's `IncomingRequest::$uri`, but\nyou may provide your own using the static methods `set`, `get`, `push`, and `pop`. Additionally,\n`BreadcrumbsMenu::discover()` will attempt to create a default menu. All these methods use\nthe `Breadcrumb` class, a simple wrapper for the URL and display value.\nFor example:\n```\nuse Tatter\\Menus\\Breadcrumb;\nuse Tatter\\Menus\\Menus\\BreadcrumbsMenu;\n\nclass Users extends Controller\n{\n\tpublic function show(int $userId)\n\t{\n\t\t// Get the User\n\t\t$user = model('UserModel')-\u003efind($userId);\n\n\t\t// Start with the default breadcrumbs\n\t\tBreadcrumbsMenu::discover();\n\n\t\t// Pop off the numeric last segment\n\t\tBreadcrumbsMenu::pop();\n\n\t\t// Replace it with the user's name\n\t\tBreadcrumbsMenu::push(new Breadcrumb(current_url(), $user-\u003ename));\n\n\t\treturn view('users/show', ['user' =\u003e $user]);\n\t}\n}\n```\n... if you have the filter in place the rest is handled for you.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftattersoftware%2Fcodeigniter4-menus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftattersoftware%2Fcodeigniter4-menus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftattersoftware%2Fcodeigniter4-menus/lists"}