I'm using hacksaw to display the first part of my article on a blog listing page.

{{ entry.body|hacksaw(chars='300',allow='<p>', append='...') }}

The issue I have is when an article starts with a heading in it's body it looks like the attached. I'd ideally like to remove any headings from the excerpts.

enter image description here

enter image description here

As you can see the headings 'Reducing the size...' and 'Scaling' come through as plain text and the rest continues with my allowed

The only way I can think to do this is to allow their headings (h2 and h3) and then hide them in CSS, but I'm hoping there's a better way.

3 Answers 3


You could use the Twig replace filter with a regular expression, this'll remove the tag and it's content.

{{ entry.body | replace('/<h([1-6])>.*?<\\/h([1-6])>/', '') | raw | hacksaw(chars='300',allow='<p>', append='...') }} 

The only limitation is regular expressions aren't fantastic with nested html tags, so your mileage my vary!

You might need to play around with the Regex a bit if you want to just limit it to a few headings, this will strip all h1, h2, h3, h4, h5, h6. You also might not need the | raw filter, it seemed to escape everything after the replace when I quickly tested it.


You could consider replacing all of your heading tags manually with the replace twig filter.

This would replace all headings with a paragraph: {{ entry.body|replace({'h1': 'p', 'h2': 'p', 'h3': 'p', 'h4': 'p', 'h5': 'p', 'h6': 'p'})|hacksaw(chars='300', allow='<p>', append='...') }}

  • Thanks. I actually want to remove the headings rather than have them display as paragraph text. Having the heading text as part of the body doesn't really work
    – sarah3585
    Mar 1, 2016 at 14:41
  • You could like to remove the contents of whatever is in the heading tags? Mar 1, 2016 at 14:42
  • Yes, remove the content with heading tags rather than just the tags.
    – sarah3585
    Mar 1, 2016 at 14:50
  • 1
    One lazy way of doing that is allowing headings and after that via the power of CSS display:none it. Mar 1, 2016 at 14:54
  • Yes that was my initial thought but agree it's a bit lazy so thought I'd see if there was a better option.
    – sarah3585
    Mar 1, 2016 at 15:24

I wrote a plugin called Retcon which uses DOMDocument to re-write HTML content. There's a couple of ways you could achieve your goal easily using Retcon:

Remove all header tags (and their content), using the retconRemove filter:

{{ entry.body|retconRemove(['h1','h2','h3','h4','h5','h6']) }}

Remove everything except paragraphs, using the retconOnly filter:

{{ entry.body|retconOnly('p') }}

Remove everything except paragraphs and images:

{{ entry.body|retconOnly(['p', 'img']) }}

As for truncating the content, I'd probably add the hacksaw filter after using Retcon, i.e.

{{ entry.body|retconOnly('p')|hacksaw(chars='300',allow='<p>', append='...') }}

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.