├── LICENSE ├── composer.json ├── src ├── Facades │ └── Navigation.php ├── Navigation.php └── NavigationServiceProvider.php └── views └── bootstrap.blade.php /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2015 Graham Campbell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graham-campbell/navigation", 3 | "description": "Navigation Is A Navigation Bar Generator For Laravel 5", 4 | "keywords": ["laravel", "framework", "navigation generator", "navigation", "navigation bar", "Navigation", "Laravel Navigation", "Laravel-Navigation", "Graham Campbell", "GrahamCampbell"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Graham Campbell", 9 | "email": "graham@alt-three.com" 10 | } 11 | ], 12 | "require": { 13 | "php": ">=5.5.9", 14 | "illuminate/contracts": "5.0.*|5.1.*", 15 | "illuminate/http": "5.0.*|5.1.*", 16 | "illuminate/support": "5.0.*|5.1.*" 17 | }, 18 | "require-dev": { 19 | "graham-campbell/testbench": "~3.0", 20 | "mockery/mockery": "^0.9.4", 21 | "phpunit/phpunit": "^4.7.6" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "GrahamCampbell\\Navigation\\": "src/" 26 | } 27 | }, 28 | "autoload-dev": { 29 | "psr-4": { 30 | "GrahamCampbell\\Tests\\Navigation\\": "tests/" 31 | } 32 | }, 33 | "config": { 34 | "preferred-install": "dist" 35 | }, 36 | "extra": { 37 | "branch-alias": { 38 | "dev-master": "2.2-dev" 39 | } 40 | }, 41 | "minimum-stability": "dev", 42 | "prefer-stable": true 43 | } 44 | -------------------------------------------------------------------------------- /src/Facades/Navigation.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace GrahamCampbell\Navigation\Facades; 13 | 14 | use Illuminate\Support\Facades\Facade; 15 | 16 | /** 17 | * This is the navigation facade class. 18 | * 19 | * @author Graham Campbell 20 | */ 21 | class Navigation extends Facade 22 | { 23 | /** 24 | * Get the registered name of the component. 25 | * 26 | * @return string 27 | */ 28 | protected static function getFacadeAccessor() 29 | { 30 | return 'navigation'; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Navigation.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace GrahamCampbell\Navigation; 13 | 14 | use Illuminate\Contracts\Events\Dispatcher; 15 | use Illuminate\Contracts\Routing\UrlGenerator; 16 | use Illuminate\Contracts\View\Factory; 17 | use Illuminate\Http\Request; 18 | 19 | /** 20 | * This is the navigation class. 21 | * 22 | * @author Graham Campbell 23 | */ 24 | class Navigation 25 | { 26 | /** 27 | * The items in the main nav bar. 28 | * 29 | * @var array 30 | */ 31 | protected $main = []; 32 | 33 | /** 34 | * The items in the bar nav bar. 35 | * 36 | * @var array 37 | */ 38 | protected $bar = []; 39 | 40 | /** 41 | * The request instance. 42 | * 43 | * @var \Illuminate\Http\Request 44 | */ 45 | protected $request; 46 | 47 | /** 48 | * The events instance. 49 | * 50 | * @var \Illuminate\Contracts\Events\Dispatcher 51 | */ 52 | protected $events; 53 | 54 | /** 55 | * The url instance. 56 | * 57 | * @var \Illuminate\Contracts\Routing\UrlGenerator 58 | */ 59 | protected $url; 60 | 61 | /** 62 | * The view instance. 63 | * 64 | * @var \Illuminate\Contracts\View\Factory 65 | */ 66 | protected $view; 67 | 68 | /** 69 | * The view name. 70 | * 71 | * @var string 72 | */ 73 | protected $name; 74 | 75 | /** 76 | * Create a new instance. 77 | * 78 | * @param \Illuminate\Http\Request $request 79 | * @param \Illuminate\Contracts\Events\Dispatcher $events 80 | * @param \Illuminate\Contracts\Routing\UrlGenerator $url 81 | * @param \Illuminate\Contracts\View\Factory $view 82 | * @param string $name 83 | * 84 | * @return void 85 | */ 86 | public function __construct(Request $request, Dispatcher $events, UrlGenerator $url, Factory $view, $name) 87 | { 88 | $this->request = $request; 89 | $this->events = $events; 90 | $this->url = $url; 91 | $this->view = $view; 92 | $this->name = $name; 93 | } 94 | 95 | /** 96 | * Add an item to the main navigation array. 97 | * 98 | * @param array $item 99 | * @param string $name 100 | * @param bool $first 101 | * 102 | * @return $this 103 | */ 104 | public function addToMain(array $item, $name = 'default', $first = false) 105 | { 106 | // check if the name exists in the main array 107 | if (!array_key_exists($name, $this->main)) { 108 | // add it if it doesn't exists 109 | $this->main[$name] = []; 110 | } 111 | 112 | // check if we are forcing the item to the start 113 | if ($first) { 114 | // add the item to the start of the array 115 | $this->main[$name] = array_merge([$item], $this->main[$name]); 116 | } else { 117 | // add the item to the end of the array 118 | $this->main[$name][] = $item; 119 | } 120 | 121 | return $this; 122 | } 123 | 124 | /** 125 | * Add an item to the bar navigation array. 126 | * 127 | * @param array $item 128 | * @param string $name 129 | * @param bool $first 130 | * 131 | * @return $this 132 | */ 133 | public function addToBar(array $item, $name = 'default', $first = false) 134 | { 135 | // check if the name exists in the bar array 136 | if (!array_key_exists($name, $this->bar)) { 137 | // add it if it doesn't exists 138 | $this->bar[$name] = []; 139 | } 140 | 141 | // check if we are forcing the item to the start 142 | if ($first) { 143 | // add the item to the start of the array 144 | $this->bar[$name] = array_merge([$item], $this->bar[$name]); 145 | } else { 146 | // add the item to the end of the array 147 | $this->bar[$name][] = $item; 148 | } 149 | 150 | return $this; 151 | } 152 | 153 | /** 154 | * Get the navigation bar html. 155 | * 156 | * @param string $mainName 157 | * @param string|bool $barName 158 | * @param array|null $data 159 | * 160 | * @return string 161 | */ 162 | public function render($mainName = 'default', $barName = false, array $data = null) 163 | { 164 | // set the default value if nothing was passed 165 | if ($data === null) { 166 | $data = ['title' => 'Navigation', 'side' => 'dropdown', 'inverse' => true]; 167 | } 168 | 169 | // get the nav bar arrays 170 | $main = $this->getMain($mainName); 171 | if (is_string($barName)) { 172 | $bar = $this->getBar($barName); 173 | if (empty($bar)) { 174 | $bar = false; 175 | } 176 | } else { 177 | $bar = false; 178 | } 179 | 180 | // return the html nav bar 181 | return $this->view->make($this->name, array_merge($data, ['main' => $main, 'bar' => $bar]))->render(); 182 | } 183 | 184 | /** 185 | * Get the main navigation array. 186 | * 187 | * @param string $name 188 | * 189 | * @return array 190 | */ 191 | protected function getMain($name = 'default') 192 | { 193 | // fire event that can be hooked to add items to the nav bar 194 | $this->events->fire('navigation.main', [['name' => $name]]); 195 | 196 | // check if the name exists in the main array 197 | if ($name !== 'default' && !array_key_exists($name, $this->main)) { 198 | // use the default name 199 | $name = 'default'; 200 | } 201 | 202 | if (!array_key_exists($name, $this->main)) { 203 | // add it if it doesn't exists 204 | $this->main[$name] = []; 205 | } 206 | 207 | // apply active keys 208 | $nav = $this->active($this->main[$name]); 209 | 210 | // fix up and spit out the nav bar 211 | return $this->process($nav); 212 | } 213 | 214 | /** 215 | * Get the bar navigation array. 216 | * 217 | * @param string $name 218 | * 219 | * @return array 220 | */ 221 | protected function getBar($name = 'default') 222 | { 223 | // fire event that can be hooked to add items to the nav bar 224 | $this->events->fire('navigation.bar', [['name' => $name]]); 225 | 226 | // check if the name exists in the bar array 227 | if ($name !== 'default' && !array_key_exists($name, $this->bar)) { 228 | // use the default name 229 | $name = 'default'; 230 | } 231 | 232 | if (!array_key_exists($name, $this->bar)) { 233 | // add it if it doesn't exists 234 | $this->bar[$name] = []; 235 | } 236 | 237 | // don't apply active keys 238 | $nav = $this->bar[$name]; 239 | 240 | // fix up and spit out the nav bar 241 | return $this->process($nav); 242 | } 243 | 244 | /** 245 | * Check if each item is active. 246 | * 247 | * @param array $nav 248 | * 249 | * @return array 250 | */ 251 | protected function active(array $nav) 252 | { 253 | // check if each item is active 254 | foreach ($nav as $key => $value) { 255 | // check if it is local 256 | if (isset($value['slug'])) { 257 | // if the request starts with the slug 258 | if ($this->request->is($value['slug']) || $this->request->is($value['slug'].'/*')) { 259 | // then the navigation item is active, or selected 260 | $nav[$key]['active'] = true; 261 | } else { 262 | // then the navigation item is not active or selected 263 | $nav[$key]['active'] = false; 264 | } 265 | } else { 266 | // then the navigation item is not active or selected 267 | $nav[$key]['active'] = false; 268 | } 269 | } 270 | 271 | // spit out the nav bar array at the end 272 | return $nav; 273 | } 274 | 275 | /** 276 | * Convert slugs to urls. 277 | * 278 | * @param array $nav 279 | * 280 | * @return array 281 | */ 282 | protected function process(array $nav) 283 | { 284 | // convert slugs to urls 285 | foreach ($nav as $key => $value) { 286 | // if the url is not set 287 | if (!isset($value['url'])) { 288 | // set the url based on the slug 289 | $nav[$key]['url'] = $this->url->to($value['slug']); 290 | } 291 | // remove any remaining slugs 292 | unset($nav[$key]['slug']); 293 | } 294 | 295 | // spit out the nav bar array at the end 296 | return $nav; 297 | } 298 | 299 | /** 300 | * Get the request instance. 301 | * 302 | * @return \Illuminate\Http\Request 303 | */ 304 | public function getRequest() 305 | { 306 | return $this->request; 307 | } 308 | 309 | /** 310 | * Set the request instance. 311 | * 312 | * @param \Illuminate\Http\Request $request 313 | * 314 | * @return void 315 | */ 316 | public function setRequest(Request $request) 317 | { 318 | $this->request = $request; 319 | } 320 | 321 | /** 322 | * Get the events instance. 323 | * 324 | * @return \Illuminate\Contracts\Events\Dispatcher 325 | */ 326 | public function getEvents() 327 | { 328 | return $this->events; 329 | } 330 | 331 | /** 332 | * Get the url instance. 333 | * 334 | * @return \Illuminate\Contracts\Routing\UrlGenerator 335 | */ 336 | public function getUrl() 337 | { 338 | return $this->url; 339 | } 340 | 341 | /** 342 | * Get the view instance. 343 | * 344 | * @return \Illuminate\Contracts\View\Factory 345 | */ 346 | public function getView() 347 | { 348 | return $this->view; 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /src/NavigationServiceProvider.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace GrahamCampbell\Navigation; 13 | 14 | use Illuminate\Support\ServiceProvider; 15 | 16 | /** 17 | * This is the navigation service provider class. 18 | * 19 | * @author Graham Campbell 20 | */ 21 | class NavigationServiceProvider extends ServiceProvider 22 | { 23 | /** 24 | * Boot the service provider. 25 | * 26 | * @return void 27 | */ 28 | public function boot() 29 | { 30 | $this->loadViewsFrom(realpath(__DIR__.'/../views'), 'navigation'); 31 | } 32 | 33 | /** 34 | * Register the service provider. 35 | * 36 | * @return void 37 | */ 38 | public function register() 39 | { 40 | $this->registerNavigation(); 41 | } 42 | 43 | /** 44 | * Register the navigation class. 45 | * 46 | * @return void 47 | */ 48 | protected function registerNavigation() 49 | { 50 | $this->app->singleton('navigation', function ($app) { 51 | $request = $app['request']; 52 | $events = $app['events']; 53 | $url = $app['url']; 54 | $view = $app['view']; 55 | $name = 'navigation::bootstrap'; 56 | 57 | $navigation = new Navigation($request, $events, $url, $view, $name); 58 | $app->refresh('request', $navigation, 'setRequest'); 59 | 60 | return $navigation; 61 | }); 62 | 63 | $this->app->alias('navigation', Navigation::class); 64 | } 65 | 66 | /** 67 | * Get the services provided by the provider. 68 | * 69 | * @return string[] 70 | */ 71 | public function provides() 72 | { 73 | return [ 74 | 'navigation', 75 | ]; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /views/bootstrap.blade.php: -------------------------------------------------------------------------------- 1 | 46 | --------------------------------------------------------------------------------