A CakePHP behavior to automatically create and store slugs.
| Key | Default | Description |
|---|---|---|
| label | `null` |
|
| field | `'slug'` | The slug field name |
| overwriteField | 'overwrite_slug' | The boolean field/property to trigger overwriting if "overwrite" is false |
| mode | `'url'` |
|
| separator | `-` | The separator to use |
| length | `null` | Set to 0 for no length. Will be auto-detected if possible via schema. |
| overwrite | `false` |
has the following values
|
| unique | `false` |
has the following values
|
| case | `null` |
has the following values
|
| replace | see code | Custom replacements as array. `Set to null` to disable. |
| on | `'beforeRules'` | `beforeSave` or `beforeMarshal` or `beforeRules`. |
| scope | `[]` | Certain conditions to use as scope. |
| tidy | `true` | If cleanup should be run on slugging. |
Attach it to your models in initialize() like so:
$this->addBehavior('Tools.Slugged');
We want to store categories and we need a slug for nice SEO URLs like /category/[slugname]/.
$this->addBehavior('Tools.Slugged',
['label' => 'name', 'unique' => true, 'mode' => 'ascii']
);
Upon creating and storing a new record it will look for content in "name" and create a slug in "slug" field.
With the above config on "edit" the slug will not be modified if you alter the name. That is important to know. You cannot just change the slug, as the URL is most likely indexed by search engines now.
If you want to do that, you would also need a .htaccess rewrite rule to 301 redirect from the old to the new slug. So if that is the case, you could add an "overwrite field" to your form.
echo $this->Form->field('overwrite_slug', ['type' => 'checkbox']);
Once that boolean checkbox is clicked it will then perform the slug update on save.
If we just append the slug to the URL, such as /category/123-[slugname], then we don't need to persist the slug.
$this->addBehavior('Tools.Slugged',
['label' => 'name', 'overwrite' => true, 'mode' => 'ascii', 'unique' => true]
);
Note that we don't need "unique" either then.
Each save now re-triggers the slug generation.
You can pass your own callable for slugging into the mode config.
And you can even use a static method on any class this way (given it has a static slug() method):
$this->addBehavior('Tools.Slugged', ['mode' => [MySlugger::class, 'slug']]);
Tip: Use 'mode' => [Text::class, 'slug'] if you want to avoid using the deprecated Inflector::slug() method.
Don't forget the use statement at the top of the file, though (use Tools\Utility\Text;).