cakephp-sluggable
Plugin for CakePHP 3.x that enables automatic, configurable slugging of database fields, (*1)
WHY?, (*2)
Because slugs are great for human-readable yet seo-friendly page titles, urls, image urls, etc! They're pretty much the standard nowadays and CakePHP makes it super easy to give your app the power to create them for you., (*3)
HOW?, (*4)
Just add the Sluggable.Sluggable behaviour to any model whose field(s) you need to slug. See the usage section for customization., (*5)
Requirements
TOC
- Plugin Installation
-
Usage
- Examples
- Contributing
Plugin Installation
- Composer Install
-
Manual Install
- Loading the plugin in your app
- Setting up the namespace / autoloader
Composer Install
This plugin is on Packagist which means it can be easily installed with Composer., (*6)
composer require cwbit/cakephp-sluggable
Then simply load the plugin normally in your config/bootstrap.php file, (*7)
# in ../config/bootstrap.php - right after Plugin::load('Migrations') is fine!
Plugin::load('Sluggable');
Manual Install
You can also manually load this plugin in your App, (*8)
loading the plugin in your app
Add the source code in this project into plugins/Sluggable, (*9)
Then configure your App to actually load this plugin, (*10)
# in ../config/bootstrap.php
Plugin::load('Sluggable');
setting up the namespace / autoloader
Tell the autoloader where to find your namespace in your composer.json file, (*11)
(..)
"autoload": {
"psr-4": {
(..)
"Sluggable\\": "./plugins/Sluggable/src"
}
},
(..)
Then you need to issue the following command on the commandline, (*12)
php composer.phar dumpautoload
If you are unable to get composer autoloading to work, add 'autoload' => true line in your bootstrap.php Plugin::load(..) command (see loading section), (*13)
Slug Behavior
The sluggable behavior is extremely easy to implement, simply add it, like any other behavior, to your Table, (*14)
class PostsTable extends Table
{
public function initialize(array $options)
{
parent::initialize($options);
$this->addBehavior('Sluggable.Sluggable');
}
}
By default the plugin will automatically generate a slug based on name, will store it in a column called slug and will use a dash - replacement, and will NOT automatically overwrite the slug field whenever name changes., (*15)
All of these settings are, of course, configurable., (*16)
-
pattern
-
:name (default)
- a
\Cake\Utility\Text::insert()-friendly tokenized string. any of the entity fields are valid options
-
field
-
slug (default)
- field in the entity to store the slug
-
replacement
-
- (default)
- string used to replace spaces when building the slug
-
overwrite
-
false (default)
-
true, if the slug should ALWAYS be re-generated on save. false, to generate once
Examples
Generate a slug based on the title field instead of name, (*17)
class PostsTable extends Table
{
public function initialize(array $options)
{
parent::initialize($options);
$this->addBehavior('Sluggable.Sluggable', [
'pattern' => ':title',
]);
}
}
Generate a slug based on id and title, (*18)
class PostsTable extends Table
{
public function initialize(array $options)
{
parent::initialize($options);
$this->addBehavior('Sluggable.Sluggable', [
'pattern' => ':id-:title',
]);
}
}
Generate a slug based on the latest version of the title (always), (*19)
class PostsTable extends Table
{
public function initialize(array $options)
{
parent::initialize($options);
$this->addBehavior('Sluggable.Sluggable', [
'pattern' => ':title',
'overwrite' => true,
]);
}
}
Generate a slug normally, but store it in the foo column, (*20)
class PostsTable extends Table
{
public function initialize(array $options)
{
parent::initialize($options);
$this->addBehavior('Sluggable.Sluggable', [
'field' => 'foo',
]);
}
}
Generate a slug using . dots instead of - dashes, (*21)
class PostsTable extends Table
{
public function initialize(array $options)
{
parent::initialize($options);
$this->addBehavior('Sluggable.Sluggable', [
'replacement' => '.',
]);
}
}
Slug Utility
The Sluggable Plugin adds a Utility class Slug that can be called statically. This is the function used by the Behavior to actually generate the slug., (*22)
It is capable of handling a string, array, or entity in conjunction with a simple string or Text::insert-friendly pattern., (*23)
To use the Utility, simply add the following to your class header, (*24)
use Sluggable\Utility\Slug;
The Utility provides the following function, (*25)
/**
* Turns a string (and optionally a dynamic, data-injected string) into a slugged value
* @param $pattern string a simple string (e.g. 'slug me')
* or Text::insert-friendly string (e.g. ':id-:name')
* @param $data mixed an Array or Entity of data to Text::insert inject into $pattern
* @param $replacement string the character to replace non-slug-friendly characters with (default '-')
* @return string the slugged string
*/
Slug::generate($pattern, $data = [], $replacement = '-');
Examples
use Sluggable\Utility\Slug;
echo Slug::generate('slug me');
# 'slug-me'
echo Slug::generate('SLUG(!@#(ME');
# 'slug-me'
echo Slug::generate('a really long slug that i just made');
# 'a-really-long-slug-that-i-just-made'
To Text::insert via an array..., (*26)
$data = [
'id' => 123,
'name' => 'abc',
'description' => 'Hello, World!',
];
$slug = Slug::generate(':id-:name', $data);
# '123-abc'
$slug = Slug::generate(':description', $data);
# 'hello-world'
To Text::insert via Entity properties..., (*27)
$data = new Entity([
'id' => 123,
'name' => 'abc',
'description' => 'Hello, World!',
]);
$slug = Slug::generate(':id-:name', $data);
# '123-abc'
$slug = Slug::generate(':description', $data);
# 'hello-world'
Contributing
If you'd like to contribute, please submit a PR with your changes!, (*28)
Requests will be accepted more readily if they come complete with TESTS :D, (*29)