---
title: A better title filter for twig using Craft CMS
date: 2024-08-02T12:38:00+01:00
author: John Henry Donovan
canonical_url: "https://johnhenry.ie/blog/2024/08/a-better-title-filter-for-twig-using-craft-cms"
section: Blog
---
Browse by categoryAll PostsWeb DevelopmentDesignLifestyleMusic &amp; FilmTutorialsSpottedSpeakingReviewsFound FoodRecipesIreland

[](/blog)

# A Better Title Filter For Twig Using Craft CMS

Posted on 02nd August, 2024

The default Twig title filter lacked the necessary flexibility for this site. To address this limitation, I developed a custom Craft CMS Twig Extension, which provided enhanced functionality and greater control over title formatting.

A [Twig filter for titles](https://twig.symfony.com/doc/3.x/filters/title.html) currently exists that converts a string to capitalize it.

```twig
{{ entry.title|title }}
```

The above craft variable and twig filter changes

> craft web development in ireland

to

> Craft Web Development In Ireland

While the Twig filter for titles works great in 99% of cases, it’s important to be aware of its limitations.

But what if your string already contains capitals or other variants that must remain in the current format?

**Example**

> craft CMS web development using AI in ireland

This becomes

> Craft Cms Web Development Using Ai In Ireland

This doesn’t achieve what we want. So, a custom Twig extension to the rescue.

## Strict Title Twig Extension

The original title filter from Twig uses PHP’s [mb\_​convert\_​case](https://www.php.net/manual/en/function.mb-convert-case.php)

```php
public static function titleCase(string $charset, $string): string
    {
        return mb_convert_case($string ?? '', \MB_CASE_TITLE, $charset);
    }
```

Lets create our own function. This is where [unicode character properties in regex](http://www.regular-expressions.info/unicode.html) can save us.

A reproduction of `mb_convert_case` without the problematic conversion to lowercase becomes:

```php
public function mb_convert_case_utf8_variation($s): string
    {
        $arr = preg_split("//u", $s, -1, PREG_SPLIT_NO_EMPTY);
        $result = "";
        $mode = false;
        foreach ($arr as $char) {
            $res = preg_match(
                    '/\\p{Mn}|\\p{Me}|\\p{P}|\\p{Cf}|\\p{Lm}|\\p{Sk}|\\p{Lu}|\\p{Ll}|' .
                    '\\p{Lt}|\\p{Sk}|\\p{Cs}/u', $char) == 1;
            if ($mode) {
                if (!$res) {
                    $mode = false;
                }
            } elseif ($res) {
                $mode = true;
                $char = mb_convert_case($char, MB_CASE_TITLE, "UTF-8");
            }
            $result .= $char;
        }

        return $result;
    }
```

### Explanation

For each character, a regular expression is used to check if the character belongs to any of several unicode character classes. If the character is from one of these classes, `$res` will be true.

The rest of the code inside the loop checks the `$res` value. If `$res` is true, and `$mode` is false, that means we’re transitioning from a non-matching character to a matching character, so `mb_convert_case(`) is used to convert the character to title case and `$mode` is set to true. If `$res` is false and `$mode` is true, then we’re transitioning from a matching character to a non-matching one, so `$mode` is turned off.

At the end of each loop iteration, whether the character was transformed to title case or not, it’s appended to `$result`.

Props to user [Artefacto](https://stackoverflow.com/users/127724/artefacto) on this [Stack Exchange post](https://stackoverflow.com/questions/3296086/php-mb-convert-case-keep-words-that-are-in-uppercase)

## How to Install

I have a custom module on my site where I have integrated this twig extension. I won’t review that here, but you can read [Soft Limit Function on a Craft CMS Text Field Using a Module](https://johnhenry.ie/blog/2022/10/soft-limit-function-on-a-craft-cms-text-field-using-a-module) for more info.

You can grab the full code for this Twig Extension

- [StrictTitle Twig Extension for Craft](https://gist.github.com/john-henry/16ac7b65dc86aa887e2037922358a81f)

### Share this link via

###### Or copy link

Copy

[ Previous Blog Post

Error Reporting With Rollbar And …](https://johnhenry.ie/blog/2024/08/error-reporting-with-rollbar-and-craft-cms "Previous Blog Post")

[Next Blog Post

Illustrated Guides To Olympic Spo…](https://johnhenry.ie/blog/2024/07/illustrated-guides-to-olympic-sports "Next Blog Post")
