In Drupal 7, I used bbcode style markup and a function in my php template file to add styling to the titles of certain pages. The function was called from page.tpl.php. For example, sample pages from books might be titled something like "Sample pages from [em]A Book Title[/em]" and then transformed to actual <em> tags.

Is this more-or-less still the right way to do it in Backdrop? 

Thanks.

Accepted answer

Hi @leeksoup. 

First, keep in mind that, if not done well, this is a big security risk, as someone could insert malicious tags in titles (unless the function you refer to takes care of sanitizing and filtering those).

In Backdrop, page titles are handled by the layout and block systems. You can choose to insert "Page title combo" blocks in your default (or any other specific) layout, and the block system will take care of rendering the page title (and tabs, etc). 

While I've never tinkered with this, looking at the code for that block, the theming of the "Page title combo" output is done in  page-components.tpl.php (which is located under core/modules/system/templates) so you can override that tpl file in your front theme and insert your function somewhere there before the title is output. Just be sure the layout uses that combo block. 

EDIT:

Another way to do that (which may be better in terms of coding) is to create another template preprocess function and take care of calling your function there and sending the correctly formatted title to the template file. For example, you can create a function called MY_THEME_preprocess_page_components(&variables) {} in your front theme's template.php file. Take a look at system_preprocess_page_components()

Comments

Hi @leeksoup. 

First, keep in mind that, if not done well, this is a big security risk, as someone could insert malicious tags in titles (unless the function you refer to takes care of sanitizing and filtering those).

In Backdrop, page titles are handled by the layout and block systems. You can choose to insert "Page title combo" blocks in your default (or any other specific) layout, and the block system will take care of rendering the page title (and tabs, etc). 

While I've never tinkered with this, looking at the code for that block, the theming of the "Page title combo" output is done in  page-components.tpl.php (which is located under core/modules/system/templates) so you can override that tpl file in your front theme and insert your function somewhere there before the title is output. Just be sure the layout uses that combo block. 

EDIT:

Another way to do that (which may be better in terms of coding) is to create another template preprocess function and take care of calling your function there and sending the correctly formatted title to the template file. For example, you can create a function called MY_THEME_preprocess_page_components(&variables) {} in your front theme's template.php file. Take a look at system_preprocess_page_components()

Thank you, @argiepiano. I will give that a try.

@argiepiano

First, keep in mind that, if not done well, this is a big security risk, as someone could insert malicious tags in titles (unless the function you refer to takes care of sanitizing and filtering those).

The function only transforms a few specific markups into tags and removes any others. Is that sufficiently sanitized?

Hard to tell without looking at the function...

Ha, fair enough. The code is like this:

function bbcodeToHtml($text) {
  $bbcode = array(
                  "[b]",  "[/b]",
                  "[u]",  "[/u]",
                  "[i]", "[/i]"
                );
  $htmltag = array(
                "<b>", "</b>",
                "<u>", "</u>",
                "<i>", "</i>",
              );
  $text = str_replace($bbcode, $htmltag, $text);
  return preg_replace('#\[.+/\S+\]#', '', $text);
}

My thought with the last regexp replace is that this will remove any remaining open-close bbcode-style tag pair but leave any actual [comment].

Thank you.

That seems safe. But you have a syntax error in the regular expression. It should be (there is an extra "/" before "\S"):

return preg_replace('#\[.+\S+\]#', '', $text);

And even then, it won't remove things that are only one letter, like [p]

Thanks for reviewing it!

The / before the \S was intentional. I wanted to catch paired tags but allow words within square brackets to remain. So it should catch things like:

[tag]Something something[/tag]

but should leave things like

[this is a comment]

It's still a syntax error that gets ignored. The / alone is a reserved character in regexp. You have to escape it. 

You can see this if you try any of the only regexp testers (e.g. https://regex101.com/). I've tried a couple and both are indicating that the "/" alone there is an error, and it's ignored.

 

Interesting ... I tried it as a tiny script

<?php
echo preg_replace('#\[.+/\S+\]#', '', "Testing [tag]Items[/tag] removal and [comments]");

and the result is

Testing  removal and [comments]

Without that '/' the result is

Testing 

So clearly the '/' is syntactically significant. I used '#' for the regexp delimiter, so that I don't need to escape the '/'. 

Aha!! I just learned something new about regexp! Thanks.