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)