Skip to content

Commit

Permalink
chore: added a how to use to the readme
Browse files Browse the repository at this point in the history
  • Loading branch information
red-freak committed Oct 6, 2023
1 parent e32b1f1 commit 8309ac4
Show file tree
Hide file tree
Showing 6 changed files with 260 additions and 9 deletions.
131 changes: 124 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Laravel Menu
Larvel Menu is a package to create menus for laravel applications. It's a package to also solve the problem for module based applications (see [red-freak/laravel-modules](https://github.com/red-freak/laravel-modules)).
Laravel Menu is a package to create menus for laravel applications. It's a package to also solve the problem for module based applications (see [red-freak/laravel-modules](https://github.com/red-freak/laravel-modules)).

[![Latest Version](https://img.shields.io/github/release/red-freak/laravel-menu.svg)](https://github.com/red-freak/laravel-menu/releases)
[![MIT Licensed](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE.md)
Expand All @@ -10,20 +10,137 @@ Larvel Menu is a package to create menus for laravel applications. It's a packag
![Supported PHP Version](https://img.shields.io/badge/8.0%2C%208.1%2C%208.2-555?logo=php)
![Supported Laravel Version](https://img.shields.io/badge/8.x%2C%209.x%2C%2010.x-555?logo=laravel)

## Installation

## coming up
Simply install the package via composer:

```bash
composer require red-freak/laravel-menu
```

## changelog
## How to use

### 0.0.0-alpha (current development)
#### Features
### Basic usage
The base idea is to be able to create or add items via a `Menu`-Facade. It can be accessed from anywhere. So you are able to have different (e.g. module-bases) ServiceProviders to do so.
```php
Menu::add('home')
->add(new Item('Home', '/'))
->add(new Item('About', '/about'))
->add(new Item('Login', '/login'));
```

#### Fixes
```html
<ul class="menu menu-level-0">
<li class="menu-item menu-level-1">
<a href="/">Home</a>
</li>
<li class="menu-item menu-level-1">
<a href="/about">About</a>
</li>
<li class="menu-item menu-level-1">
<a href="/login">Login</a>
</li>
</ul>
```

### Add items to a menu
You can define the menus in the config file for later use in your project and can also add items to a menu via the `Menu`-Facade. And of course it can work with labels.
```php
// define the menu anywhere to use translation keys as labels (or do it by config)
Menu::add('home', [
RenderOptions::KEY_USE_LABELS_AS_TRANSLATION_KEYS => true
]);

...

// have the corresponding translation keys via files (or in this case via the `Translator`-Facade)
app()->translator->addLines([
'menu.label.home' => 'Home',
'menu.label.about' => 'About',
'menu.label.login' => 'Login',
], 'en');

...

// Now you can add items via the `Item` class ...
Menu::get('home')
->add(new Item('menu.label.home', 'http://localhost'))
->add(new Item('menu.label.about', 'http://localhost/about'))
->add(new Item('menu.label.login', 'http://localhost/login'));

// ... or add them via key-value ...
Menu::get('home')
->add([
Menu::KEY_ITEM_LABEL => 'Home',
Menu::KEY_ITEM_LINK => 'http://localhost',
])
->add([
Menu::KEY_ITEM_LABEL => 'About',
Menu::KEY_ITEM_LINK => 'http://localhost/about',
])
->add([
Menu::KEY_ITEM_LABEL => 'Login',
Menu::KEY_ITEM_LINK => 'http://localhost/login',
]);

// ... or add them via routes ...
// Route::get('/', fn() => 'home')->name('home');
// Route::get('/about', fn() => 'about')->name('about');
// Route::get('/login', fn() => 'login')->name('login');
Menu::get('home')
->add([Menu::KEY_ITEM_ROUTE => 'home'])
->add([Menu::KEY_ITEM_ROUTE => 'about'])
->add([Menu::KEY_ITEM_ROUTE => 'login']);
```
If you now call `Menu::home()` via the automatically create macro, you will get the following result:
```html
<ul class="menu menu-level-0">
<li class="menu-item menu-level-1">
<a href="http://localhost">Home</a>
</li>
<li class="menu-item menu-level-1">
<a href="http://localhost/about">About</a>
</li>
<li class="menu-item menu-level-1">
<a href="http://localhost/login">Login</a>
</li>
</ul>
```

### Add a submenu for a Model
```php
// define the route and the translation keys
Route::resource('users', Controller::class);
app()->translator->addLines([
'menu.label.users.index' => 'Users',
'menu.label.users.create' => 'create User',
], 'en');
```
```php
// define the menu and add a submenu by a model
Menu::add('home', [RenderOptions::KEY_USE_LABELS_AS_TRANSLATION_KEYS => true])->add([
Menu::KEY_ITEM_MODEL => User::class,
]);
```
If you now call `Menu::home()` via the automatically create macro, you will get the following result:
```html
<ul class="menu menu-level-0">
<li class="sub-menu menu-item menu-level-1">
Users
<ul class="sub-menu menu-item menu-level-2">
<li class="menu-item menu-level-3">
<a href="http://localhost/users">Users</a>
</li>
<li class="menu-item menu-level-3">
<a href="http://localhost/users/create">create User</a>
</li>
</ul>
</li>
</ul>
```

## run tests
`vendor/bin/pest --coverage-html ./tests/reports/pest`


## special thanks
- [Spatie](https://github.com/spatie) for general inspiration on package development and their workflows
1 change: 1 addition & 0 deletions src/Facades/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/**
* @method static MenuDto add(string $menuName, array $menuData = [])
* @method static self flush(string $menuName)
* @method static MenuDto get(string $menuName)
* @method static bool hasMenu(string $menuName)
* @method static array menus()
Expand Down
16 changes: 15 additions & 1 deletion src/MenuManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ public function add(string $menuName, array $menuData = []): Menu
return $menu;
}

/**
* Forget a menu (mainly for testing purposes).
*
* @param string $menuName
*
* @return $this
*/
public function flush(string $menuName): self
{
$this->menus->forget($menuName);

return $this;
}

public function get(string $menuName): Menu
{
return $this->menus->get($menuName);
Expand All @@ -48,7 +62,7 @@ protected function registerMenu(string $menuName, $menuData = []): Menu

protected function registerMacro(Item $item): void
{
self::macro($item->label(), static function() use ($item) {
self::macro($item->label(), function() use ($item) {
return $item->render();
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/ResourceItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ private function getRouteLabel(string $route): string
{
$label = config('menus.default_translation_prefix', 'menu.label.') . $route;

return config('menus.use_labels_as_translation_keys', false) ? __($label) : $label;
return $this->renderOptions()->useLabelsAsTranslationKeys() ? __($label) : $label;
}
}
12 changes: 12 additions & 0 deletions tests/Models/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace RedFreak\Menu\Tests\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
protected $attributes = [
'id' => 1,
];
}
107 changes: 107 additions & 0 deletions tests/Unit/ReadmeExamplesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

use Illuminate\Foundation\Auth\User;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Route;
use RedFreak\Menu\Facades\Menu;
use RedFreak\Menu\Item;
use RedFreak\Menu\MenuServiceProvider;
use RedFreak\Menu\RenderOptions;

const EXPECTED_RENDER_OUTPUT = '<ul class="menu menu-level-0">'.PHP_EOL
.' <li class="menu-item menu-level-1">'.PHP_EOL
.' <a href="http://localhost">Home</a>'.PHP_EOL
.' </li>'.PHP_EOL
.' <li class="menu-item menu-level-1">'.PHP_EOL
.' <a href="http://localhost/about">About</a>'.PHP_EOL
.' </li>'.PHP_EOL
.' <li class="menu-item menu-level-1">'.PHP_EOL
.' <a href="http://localhost/login">Login</a>'.PHP_EOL
.' </li>'.PHP_EOL
.'</ul>'.PHP_EOL;

beforeEach(function() {
app()->register(MenuServiceProvider::class);
app()->translator->addLines([
'menu.label.home' => 'Home',
'menu.label.about' => 'About',
'menu.label.login' => 'Login',
], 'en');
});

it('can fulfill the basic usage example', function () {
Menu::add('home', [RenderOptions::KEY_USE_LABELS_AS_TRANSLATION_KEYS => true])
->add(new Item('menu.label.home', 'http://localhost'))
->add(new Item('menu.label.about', 'http://localhost/about'))
->add(new Item('menu.label.login', 'http://localhost/login'));

expect(Menu::get('home')->render())->toBe(EXPECTED_RENDER_OUTPUT);
});

it('can fulfill the add items examples', function () {
// Item class
Menu::flush('home')->add('home', [RenderOptions::KEY_USE_LABELS_AS_TRANSLATION_KEYS => true])
->add(new Item('menu.label.home', 'http://localhost'))
->add(new Item('menu.label.about', 'http://localhost/about'))
->add(new Item('menu.label.login', 'http://localhost/login'));
expect(Menu::get('home')->render())->toBe(EXPECTED_RENDER_OUTPUT);

// key-value
Menu::flush('home')->add('home', [RenderOptions::KEY_USE_LABELS_AS_TRANSLATION_KEYS => true])
->add([
Menu::KEY_ITEM_LABEL => 'Home',
Menu::KEY_ITEM_LINK => 'http://localhost',
])
->add([
Menu::KEY_ITEM_LABEL => 'About',
Menu::KEY_ITEM_LINK => 'http://localhost/about',
])
->add([
Menu::KEY_ITEM_LABEL => 'Login',
Menu::KEY_ITEM_LINK => 'http://localhost/login',
]);
expect(Menu::get('home')->render())->toBe(EXPECTED_RENDER_OUTPUT);

// route
Route::group(['as' => 'home'], function() {
Route::get('/', fn() => 'home');
});
Route::group(['as' => 'about'], function() {
Route::get('/about', fn() => 'about');
});
Route::group(['as' => 'login'], function() {
Route::get('/login', fn() => 'login');
});
Menu::flush('home')->add('home', [RenderOptions::KEY_USE_LABELS_AS_TRANSLATION_KEYS => true])
->add([Menu::KEY_ITEM_ROUTE => 'home'])
->add([Menu::KEY_ITEM_ROUTE => 'about'])
->add([Menu::KEY_ITEM_ROUTE => 'login']);
expect(Menu::get('home')->render())->toBe(EXPECTED_RENDER_OUTPUT);
});

it('can fulfill the add by model example', function () {
Route::resource('users', Controller::class);
app()->translator->addLines([
'menu.label.users.index' => 'Users',
'menu.label.users.create' => 'create User',
], 'en');

Menu::add('home', [RenderOptions::KEY_USE_LABELS_AS_TRANSLATION_KEYS => true])->add([
Menu::KEY_ITEM_MODEL => User::class,
]);

expect(Menu::home())->toBe('<ul class="menu menu-level-0">'.PHP_EOL
.' <li class="sub-menu menu-item menu-level-1">'.PHP_EOL
.' Users'.PHP_EOL
.' <ul class="sub-menu menu-item menu-level-2">'.PHP_EOL
.' <li class="menu-item menu-level-3">'.PHP_EOL
.' <a href="http://localhost/users">Users</a>'.PHP_EOL
.' </li>'.PHP_EOL
.' <li class="menu-item menu-level-3">'.PHP_EOL
.' <a href="http://localhost/users/create">create User</a>'.PHP_EOL
.' </li>'.PHP_EOL
.' </ul>'.PHP_EOL
.' </li>'.PHP_EOL
.'</ul>'.PHP_EOL
);
});

0 comments on commit 8309ac4

Please sign in to comment.