├── .editorconfig ├── .gitignore ├── LICENSE.md ├── README.md ├── composer.json ├── composer.lock ├── config └── breadcrumb.php └── src ├── Crumb.php ├── CrumbServiceProvider.php └── Facades └── Crumb.php /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.php] 15 | indent_size = 4 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Brandon Nifong 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Crumb 2 | 3 | ![Latest Stable Version](https://img.shields.io/packagist/v/log1x/crumb?style=flat-square) 4 | ![Build Status](https://img.shields.io/github/actions/workflow/status/log1x/crumb/main.yml?branch=master&style=flat-square) 5 | ![Total Downloads](https://img.shields.io/packagist/dt/log1x/crumb?style=flat-square) 6 | 7 | A simple breadcrumb package for Sage 10. 8 | 9 | ## Requirements 10 | 11 | - [Sage](https://github.com/roots/sage) >= 10.0 12 | - [PHP](https://secure.php.net/manual/en/install.php) >= 7.4 13 | - [Composer](https://getcomposer.org/download/) 14 | 15 | ## Installation 16 | 17 | Install via Composer: 18 | 19 | ```bash 20 | $ composer require log1x/crumb 21 | ``` 22 | 23 | ## Usage 24 | 25 | Publish the breadcrumb configuration file using Acorn: 26 | 27 | ```sh 28 | $ wp acorn vendor:publish --provider="Log1x\Crumb\CrumbServiceProvider" 29 | ``` 30 | 31 | ### Example 32 | 33 | ```php 34 | # app/View/Components/Breadcrumb.php 35 | 36 | toArray(); 63 | } 64 | 65 | /** 66 | * Get the view / contents that represent the component. 67 | * 68 | * @return \Illuminate\View\View|string 69 | */ 70 | public function render() 71 | { 72 | return $this->view('components.breadcrumb'); 73 | } 74 | } 75 | ``` 76 | 77 | ```php 78 | # views/components/breadcrumb.blade.php 79 | 80 | @if (! empty($items)) 81 | 131 | @endif 132 | ``` 133 | 134 | ## Bug Reports 135 | 136 | If you discover a bug in Crumb, please [open an issue](https://github.com/log1x/crumb/issues). 137 | 138 | ## Contributing 139 | 140 | Contributing whether it be through PRs, reporting an issue, or suggesting an idea is encouraged and appreciated. 141 | 142 | ## License 143 | 144 | Crumb is provided under the [MIT License](https://github.com/log1x/crumb/blob/master/LICENSE.md). 145 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "log1x/crumb", 3 | "type": "package", 4 | "license": "MIT", 5 | "description": "A simple WordPress breadcrumb for Sage 10.", 6 | "authors": [ 7 | { 8 | "name": "Brandon Nifong", 9 | "email": "brandon@tendency.me" 10 | } 11 | ], 12 | "keywords": [ 13 | "wordpress", 14 | "sage", 15 | "roots", 16 | "breadcrumb" 17 | ], 18 | "support": { 19 | "issues": "https://github.com/log1x/crumb/issues" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "Log1x\\Crumb\\": "src/" 24 | } 25 | }, 26 | "require": { 27 | "php": ">=7.3" 28 | }, 29 | "require-dev": { 30 | "squizlabs/php_codesniffer": "^3.5" 31 | }, 32 | "extra": { 33 | "acorn": { 34 | "providers": [ 35 | "Log1x\\Crumb\\CrumbServiceProvider" 36 | ], 37 | "aliases": { 38 | "Crumb": "Log1x\\Crumb\\Facades\\Crumb" 39 | } 40 | } 41 | }, 42 | "scripts": { 43 | "lint": [ 44 | "phpcs --ignore=vendor --extensions=php --standard=PSR12 ." 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "60e3c8066b73ffe0aa2e4d1afbae46ce", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "squizlabs/php_codesniffer", 12 | "version": "3.7.2", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 16 | "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", 21 | "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "ext-simplexml": "*", 26 | "ext-tokenizer": "*", 27 | "ext-xmlwriter": "*", 28 | "php": ">=5.4.0" 29 | }, 30 | "require-dev": { 31 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 32 | }, 33 | "bin": [ 34 | "bin/phpcs", 35 | "bin/phpcbf" 36 | ], 37 | "type": "library", 38 | "extra": { 39 | "branch-alias": { 40 | "dev-master": "3.x-dev" 41 | } 42 | }, 43 | "notification-url": "https://packagist.org/downloads/", 44 | "license": [ 45 | "BSD-3-Clause" 46 | ], 47 | "authors": [ 48 | { 49 | "name": "Greg Sherwood", 50 | "role": "lead" 51 | } 52 | ], 53 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 54 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", 55 | "keywords": [ 56 | "phpcs", 57 | "standards", 58 | "static analysis" 59 | ], 60 | "support": { 61 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", 62 | "source": "https://github.com/squizlabs/PHP_CodeSniffer", 63 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" 64 | }, 65 | "time": "2023-02-22T23:07:41+00:00" 66 | } 67 | ], 68 | "aliases": [], 69 | "minimum-stability": "stable", 70 | "stability-flags": [], 71 | "prefer-stable": false, 72 | "prefer-lowest": false, 73 | "platform": { 74 | "php": ">=7.3" 75 | }, 76 | "platform-dev": [], 77 | "plugin-api-version": "2.3.0" 78 | } 79 | -------------------------------------------------------------------------------- /config/breadcrumb.php: -------------------------------------------------------------------------------- 1 | get_bloginfo('name', 'display'), 16 | 17 | /* 18 | |-------------------------------------------------------------------------- 19 | | Blog 20 | |-------------------------------------------------------------------------- 21 | | 22 | | This option controls the label used when displaying the posts page on the 23 | | breadcrumb. If a posts page is not configured, this option can be 24 | | disregarded. 25 | | 26 | | If a posts page is configured but you would not like it shown in the 27 | | breadcrumb, you may explicitly set this option to `false`. 28 | | 29 | */ 30 | 31 | 'blog' => get_the_title( 32 | get_option('page_for_posts') 33 | ), 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Author 38 | |-------------------------------------------------------------------------- 39 | | 40 | | This option controls the label used when displaying the author archive 41 | | page on the breadcrumb. 42 | | 43 | | The `%s` identifier represents the authors configured display name. 44 | | 45 | */ 46 | 47 | 'author' => __('Posts by %s', 'sage'), 48 | 49 | /* 50 | |-------------------------------------------------------------------------- 51 | | Search 52 | |-------------------------------------------------------------------------- 53 | | 54 | | This option controls the label used when displaying the search results 55 | | page on the breadcrumb. 56 | | 57 | | The `%s` identifier represents the current search query. 58 | | 59 | */ 60 | 61 | 'search' => __('Search results for "%s"', 'sage'), 62 | 63 | /* 64 | |-------------------------------------------------------------------------- 65 | | Not Found 66 | |-------------------------------------------------------------------------- 67 | | 68 | | This option controls the label used when displaying the 404 error page 69 | | on the breadcrumb. 70 | | 71 | */ 72 | 73 | 'not_found' => __('Page not found', 'sage'), 74 | ]; 75 | -------------------------------------------------------------------------------- /src/Crumb.php: -------------------------------------------------------------------------------- 1 | config = $config; 33 | $this->breadcrumb = collect(); 34 | } 35 | 36 | /** 37 | * Add an item to the breadcrumb collection. 38 | * 39 | * @param string $key 40 | * @param string $value 41 | * @param int $id 42 | * @param bool $blog 43 | * @return $this 44 | */ 45 | protected function add($key, $value = null, $id = null, $blog = false) 46 | { 47 | if ( 48 | $blog === true && 49 | get_option('show_on_front') === 'page' && 50 | ! empty($blog = get_option('page_for_posts')) && 51 | ! empty($this->config['blog']) 52 | ) { 53 | $this->add( 54 | $this->config['blog'], 55 | get_permalink($blog), 56 | $blog 57 | ); 58 | } 59 | 60 | $this->breadcrumb->push([ 61 | 'id' => $id, 62 | 'label' => $key, 63 | 'url' => $value, 64 | ]); 65 | 66 | return $this->breadcrumb; 67 | } 68 | 69 | /** 70 | * Build the breadcrumb collection. 71 | * 72 | * @return \Illuminate\Support\Collection 73 | */ 74 | public function build() 75 | { 76 | if (is_front_page()) { 77 | return $this->breadcrumb; 78 | } 79 | 80 | $this->add( 81 | $this->config['home'], 82 | home_url() 83 | ); 84 | 85 | if ( 86 | is_home() && 87 | ! empty($this->config['blog']) 88 | ) { 89 | return $this->add( 90 | $this->config['blog'] 91 | ); 92 | } 93 | 94 | if (is_page()) { 95 | $ancestors = collect( 96 | get_ancestors(get_the_ID(), 'page') 97 | )->reverse(); 98 | 99 | if ($ancestors->isNotEmpty()) { 100 | $ancestors->each(function ($item) { 101 | $this->add( 102 | get_the_title($item), 103 | get_permalink($item), 104 | $item 105 | ); 106 | }); 107 | } 108 | 109 | return $this->add( 110 | get_the_title(), 111 | null, 112 | get_the_ID() 113 | ); 114 | } 115 | 116 | if (is_category()) { 117 | $category = single_cat_title('', false); 118 | 119 | return $this->add( 120 | $category, 121 | null, 122 | get_cat_ID($category), 123 | true 124 | ); 125 | } 126 | 127 | if (is_tag()) { 128 | $tag = single_tag_title('', false); 129 | 130 | return $this->add( 131 | $tag, 132 | null, 133 | get_term_by('name', $tag, 'post_tag')->term_id, 134 | true 135 | ); 136 | } 137 | 138 | if (is_date()) { 139 | if (is_month()) { 140 | return $this->add( 141 | get_the_date('F Y'), 142 | null, 143 | null, 144 | true 145 | ); 146 | } 147 | 148 | if (is_year()) { 149 | return $this->add( 150 | get_the_date('Y'), 151 | null, 152 | null, 153 | true 154 | ); 155 | } 156 | 157 | return $this->add( 158 | get_the_date(), 159 | null, 160 | null, 161 | true 162 | ); 163 | } 164 | 165 | if (is_tax()) { 166 | $term = single_term_title('', false); 167 | 168 | return $this->add( 169 | $term, 170 | null, 171 | get_term_by('name', $term, get_query_var('taxonomy'))->term_id 172 | ); 173 | } 174 | 175 | if (is_search()) { 176 | return $this->add( 177 | sprintf($this->config['search'], get_search_query()) 178 | ); 179 | } 180 | 181 | if (is_author()) { 182 | return $this->add( 183 | sprintf($this->config['author'], get_the_author()), 184 | null, 185 | get_the_author_meta('ID'), 186 | true 187 | ); 188 | } 189 | 190 | if (is_post_type_archive()) { 191 | return $this->add( 192 | post_type_archive_title('', false) 193 | ); 194 | } 195 | 196 | if (is_404()) { 197 | return $this->add( 198 | $this->config['not_found'] 199 | ); 200 | } 201 | 202 | if (is_singular('post')) { 203 | $categories = get_the_category(get_the_ID()); 204 | 205 | if (! empty($categories)) { 206 | foreach ($categories as $index => $category) { 207 | $this->add( 208 | $category->name, 209 | get_category_link($category), 210 | $category->term_id, 211 | $index === 0 212 | ); 213 | } 214 | 215 | return $this->add( 216 | get_the_title(), 217 | null, 218 | get_the_ID() 219 | ); 220 | } 221 | 222 | return $this->add( 223 | get_the_title(), 224 | null, 225 | get_the_ID(), 226 | true 227 | ); 228 | } 229 | 230 | $type = get_post_type_object( 231 | get_post_type() 232 | ); 233 | 234 | if (! empty($type)) { 235 | $this->add( 236 | $type->label, 237 | get_post_type_archive_link($type->name), 238 | get_queried_object_id() 239 | ); 240 | } 241 | 242 | return $this->add( 243 | get_the_title(), 244 | null, 245 | get_the_ID() 246 | ); 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /src/CrumbServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->singleton('crumb', function () { 17 | return new Crumb( 18 | $this->app['config']->get('breadcrumb') 19 | ); 20 | }); 21 | } 22 | 23 | /** 24 | * Register any application services. 25 | * 26 | * @return void 27 | */ 28 | public function register() 29 | { 30 | $this->publishes([ 31 | __DIR__ . '/../config/breadcrumb.php' => $this->app->configPath('breadcrumb.php'), 32 | ], 'config'); 33 | 34 | $this->mergeConfigFrom( 35 | __DIR__ . '/../config/breadcrumb.php', 36 | 'breadcrumb' 37 | ); 38 | 39 | add_filter('after_setup_theme', function () { 40 | return $this->app->make('crumb'); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Facades/Crumb.php: -------------------------------------------------------------------------------- 1 |