I'm working on a Craft CMS website and I need help with formatting the H1 tag.

I would like to be able to easily outline some parts of the title, like in the example below.

Ideally by adding an asterisk (*) to the actual title, like so:

Website laten maken *Amsterdam*

I already have the HTML set up, which just uses a span with a class:

<h1>Website laten maken <span class="text-outline">Amsterdam</span></h1>

I've already tried to replace the asterisks with the span by using Twig's replace but this didn't work with replacing the closing tag.

Is there a way (for example a regex) that allows me to do this? And is there a way to wrap this in a function so I can reuse it?

Many thanks!

Example of what I want to do

2 Answers 2


There are several possibilites to solve this. The fastest, as you said, is a regular expression, but those always come with limitations and potential performance issues. You can make this very simple or very complicated – it depends on how many of those special formatting options you want to include for your fields, and how often they will be used.

For a 'full' solution, you're looking at something like WordPress shortcodes. Those come with start and end tags, shortocde attributes and nested shortcodes. But you're probably not gonna need that much.

Let's consider a simple solution. For a start, I highly recommend using different symbols to denote start and end of the highlighting. Otherwise, you're entering a world of pain – the regex is gonna break if your editors want to highlight multiple phrases in the same field. I would suggest something like this:

Website laten maken {Amsterdam}

Given this syntax, you don't even need RegEx:

{% set text = '<h1>Website</h1> laten maken {Amsterdam}' %}
{{ text|replace({
    '{': '<span class="text-outline">',
    '}': '</span>',
})|striptags('<span>') }}

Note the striptags at the end that only allows <span> tags – this prevents your editors from entering raw HTML (otherwise you'd have to use the raw filter to prevent the span tags from being escaped).

If at some point you need to allow literal brackets ({, }) in the text, you can just use multiple brackets as delimiters instead: {{{, }}}

For comparison, here's the same replacement done with RegEx, which allows you to better handle some edge-cases (like start delimiters without a matching end delimiter or vice-versa):

{% set text = 'Website laten maken {Amsterdam}' %}
{{ text|replace(
    '<span class="text-outline">$1</span>',
)|striptags('<span>') }}

To make this reusable, I would put that function in a custom Twig extension so it can be used everywhere.


You can use replace with regex also, maybe like this :

{{ "Website laten maken *Amsterdam*"|replace('/\\*([^\\s][^*\\n]+[^\\s])\\*/', '<span class="text-outline">$1</span>')|raw }}

You can wrap this code inside macro, so you can reuse the code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.