Skip to content

Commit 8726107

Browse files
author
Emmanuel Campait
committed
Initial release
0 parents  commit 8726107

8 files changed

Lines changed: 524 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/vendor/
2+
/composer.lock

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) domProjects
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.

README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# domprojects/codeigniter4-breadcrumb
2+
3+
Breadcrumb builder and controller integration for CodeIgniter 4 projects.
4+
5+
## Features
6+
7+
- Reusable breadcrumb builder service
8+
- Ordered breadcrumb items with a single active item
9+
- Named templates for different application areas
10+
- Optional trait for controller integration
11+
- Compatible with CodeIgniter 4.7.2+
12+
13+
## Installation
14+
15+
Install the package with Composer:
16+
17+
```bash
18+
composer require domprojects/codeigniter4-breadcrumb
19+
```
20+
21+
## Basic Usage
22+
23+
Create and render a breadcrumb manually:
24+
25+
```php
26+
<?php
27+
28+
$breadcrumb = single_service('breadcrumb');
29+
30+
$breadcrumb
31+
->add('Home', url_to('home'))
32+
->add('Blog', url_to('blog.index'))
33+
->add('Article');
34+
35+
echo $breadcrumb->render();
36+
```
37+
38+
## Controller Integration
39+
40+
The package includes a `HasBreadcrumb` trait to simplify breadcrumb handling in controllers.
41+
42+
```php
43+
<?php
44+
45+
namespace App\Controllers;
46+
47+
use domProjects\CodeIgniterBreadcrumb\Traits\HasBreadcrumb;
48+
use CodeIgniter\Controller;
49+
50+
abstract class BaseController extends Controller
51+
{
52+
use HasBreadcrumb;
53+
}
54+
```
55+
56+
Example in a controller:
57+
58+
```php
59+
<?php
60+
61+
$this
62+
->breadcrumbRoot('Home', url_to('home'))
63+
->breadcrumbController('Blog', 'blog.index')
64+
->breadcrumbAppend('Article');
65+
66+
$data['breadcrumb'] = $this->renderBreadcrumb();
67+
```
68+
69+
## Templates
70+
71+
Default config ships with three template names:
72+
73+
- `default`
74+
- `frontend`
75+
- `backend`
76+
77+
Get a configured template in a controller:
78+
79+
```php
80+
<?php
81+
82+
$data['breadcrumb'] = $this->renderBreadcrumb(
83+
$this->getBreadcrumbTemplate('backend')
84+
);
85+
```
86+
87+
## Package Structure
88+
89+
```text
90+
src/
91+
Breadcrumb.php
92+
Config/
93+
Breadcrumb.php
94+
Services.php
95+
Traits/
96+
HasBreadcrumb.php
97+
```
98+
99+
## License
100+
101+
MIT

composer.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "domprojects/codeigniter4-breadcrumb",
3+
"description": "Breadcrumb builder and controller integration for CodeIgniter 4 projects.",
4+
"type": "library",
5+
"license": "MIT",
6+
"keywords": [
7+
"codeigniter4",
8+
"codeigniter",
9+
"breadcrumb",
10+
"navigation",
11+
"ui"
12+
],
13+
"homepage": "https://github.com/domProjects/codeigniter4-breadcrumb",
14+
"support": {
15+
"issues": "https://github.com/domProjects/codeigniter4-breadcrumb/issues",
16+
"source": "https://github.com/domProjects/codeigniter4-breadcrumb"
17+
},
18+
"authors": [
19+
{
20+
"name": "domProjects",
21+
"homepage": "https://github.com/domProjects",
22+
"role": "Maintainer"
23+
}
24+
],
25+
"require": {
26+
"php": "^8.2",
27+
"codeigniter4/framework": "^4.7.2"
28+
},
29+
"autoload": {
30+
"psr-4": {
31+
"domProjects\\CodeIgniterBreadcrumb\\": "src/"
32+
}
33+
},
34+
"extra": {
35+
"branch-alias": {
36+
"dev-main": "1.x-dev"
37+
}
38+
}
39+
}

src/Breadcrumb.php

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
3+
/**
4+
* (c) domProjects (https://domprojects.com)
5+
*
6+
* For the full copyright and license information, please view
7+
* the LICENSE file that was distributed with this source code.
8+
*/
9+
10+
namespace domProjects\CodeIgniterBreadcrumb;
11+
12+
class Breadcrumb
13+
{
14+
public const VERSION = '1.0.0';
15+
16+
/**
17+
* @var list<array{label: string, url: string|null}>
18+
*/
19+
protected array $items = [];
20+
21+
/**
22+
* @var array<string, string>
23+
*/
24+
protected array $template = [];
25+
26+
protected string $newline = "\n";
27+
28+
/**
29+
* @param array<string, string> $template
30+
*/
31+
public function __construct(array $template = [])
32+
{
33+
helper(['url', 'html']);
34+
35+
$this->template = $template;
36+
}
37+
38+
/**
39+
* @param array<string, string> $template
40+
*/
41+
public function setTemplate(array $template): self
42+
{
43+
$this->template = $template;
44+
45+
return $this;
46+
}
47+
48+
public function add(string $label, ?string $url = null): self
49+
{
50+
$label = trim($label);
51+
52+
if ($label === '') {
53+
return $this;
54+
}
55+
56+
$this->items[] = [
57+
'label' => $label,
58+
'url' => $url !== null && $url !== '' ? $url : null,
59+
];
60+
61+
return $this;
62+
}
63+
64+
/**
65+
* @param array<int|string, mixed> $items
66+
*/
67+
public function addMany(array $items): self
68+
{
69+
foreach ($items as $key => $value) {
70+
if (is_array($value) && isset($value['label'])) {
71+
$this->add(
72+
(string) $value['label'],
73+
isset($value['url']) ? (string) $value['url'] : null
74+
);
75+
76+
continue;
77+
}
78+
79+
if (is_string($key) && ! is_array($value)) {
80+
$this->add($key, (string) $value);
81+
}
82+
}
83+
84+
return $this;
85+
}
86+
87+
/**
88+
* @return list<array{label: string, url: string|null}>
89+
*/
90+
public function getItems(): array
91+
{
92+
return $this->items;
93+
}
94+
95+
public function clear(): self
96+
{
97+
$this->items = [];
98+
99+
return $this;
100+
}
101+
102+
public function render(): string
103+
{
104+
if ($this->items === []) {
105+
return '';
106+
}
107+
108+
$template = $this->resolveTemplate();
109+
$output = $template['tag_open'] . $this->newline;
110+
$last = array_key_last($this->items);
111+
112+
foreach ($this->items as $index => $item) {
113+
$label = esc($item['label']);
114+
$url = $item['url'];
115+
116+
if ($index === $last || $url === null) {
117+
$output .= $template['crumb_active']
118+
. $label
119+
. $template['crumb_close']
120+
. $this->newline;
121+
122+
continue;
123+
}
124+
125+
$output .= $template['crumb_open']
126+
. anchor($url, $label)
127+
. $template['crumb_close']
128+
. $this->newline;
129+
}
130+
131+
$output .= $template['tag_close'] . $this->newline;
132+
133+
return $output;
134+
}
135+
136+
/**
137+
* @return array<string, string>
138+
*/
139+
protected function resolveTemplate(): array
140+
{
141+
$template = $this->template;
142+
143+
foreach ($this->defaultTemplate() as $key => $value) {
144+
if (! isset($template[$key])) {
145+
$template[$key] = $value;
146+
}
147+
}
148+
149+
return $template;
150+
}
151+
152+
/**
153+
* @return array<string, string>
154+
*/
155+
protected function defaultTemplate(): array
156+
{
157+
return [
158+
'tag_open' => '<ol>',
159+
'tag_close' => '</ol>',
160+
'crumb_open' => '<li>',
161+
'crumb_close' => '</li>',
162+
'crumb_active' => '<li class="active" aria-current="page">',
163+
];
164+
}
165+
}

src/Config/Breadcrumb.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace domProjects\CodeIgniterBreadcrumb\Config;
4+
5+
use CodeIgniter\Config\BaseConfig;
6+
7+
class Breadcrumb extends BaseConfig
8+
{
9+
public string $defaultTemplate = 'default';
10+
public string $frontendTemplate = 'frontend';
11+
public string $backendTemplate = 'backend';
12+
13+
/**
14+
* @var array<string, array<string, string>>
15+
*/
16+
public array $templates = [
17+
'default' => [
18+
'tag_open' => '<ol class="breadcrumb">',
19+
'tag_close' => '</ol>',
20+
'crumb_open' => '<li class="breadcrumb-item">',
21+
'crumb_close' => '</li>',
22+
'crumb_active' => '<li class="breadcrumb-item active" aria-current="page">',
23+
],
24+
'frontend' => [
25+
'tag_open' => '<ol class="breadcrumb">',
26+
'tag_close' => '</ol>',
27+
'crumb_open' => '<li class="breadcrumb-item">',
28+
'crumb_close' => '</li>',
29+
'crumb_active' => '<li class="breadcrumb-item active" aria-current="page">',
30+
],
31+
'backend' => [
32+
'tag_open' => '<ol class="breadcrumb d-flex align-items-center">',
33+
'tag_close' => '</ol>',
34+
'crumb_open' => '<li class="breadcrumb-item">',
35+
'crumb_close' => '</li>',
36+
'crumb_active' => '<li class="breadcrumb-item active" aria-current="page">',
37+
],
38+
];
39+
}

src/Config/Services.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace domProjects\CodeIgniterBreadcrumb\Config;
4+
5+
use CodeIgniter\Config\BaseService;
6+
use domProjects\CodeIgniterBreadcrumb\Breadcrumb;
7+
8+
class Services extends BaseService
9+
{
10+
/**
11+
* Returns a breadcrumb instance.
12+
*
13+
* Breadcrumb is mutable, so shared instances are disabled by default.
14+
*
15+
* @param array<string, string> $template
16+
*/
17+
public static function breadcrumb(array $template = [], bool $getShared = false): Breadcrumb
18+
{
19+
if ($getShared) {
20+
return static::getSharedInstance('breadcrumb', $template);
21+
}
22+
23+
return new Breadcrumb($template);
24+
}
25+
}

0 commit comments

Comments
 (0)