Now that we have the block added to our page, let’s start copying the HTML from the projects page in our HTML template into the block view. If I open up the HTML for the Projects page, here’s the relevant section that powers the entire Project Grid area:
(Note: I have collapsed some of the sections in my editor in order to make the HTML more readable.)
Let’s copy this entire section, and then comment out the portfolio tab content, so that we just see the header title and the filter categories. Take this HTML and copy it into view.php, replacing the test content. Here’s view.php:
A quick refresh of the page and we have this:
This isn’t great. There must be something about the styles in the HTML that we commented out that makes this render more nicely. Let’s get around this problem by adding some artificial height to the block view template. Eventually we’ll remove this but it will help us work on this portion of the block without it being cut off by the rest of the page:
Now when we reload the page things look better; we can get to work.
Now that we have the beginning of our block view template, let’s work on the title. We’ve provided a title for our block type, but we’re not using it in the template. Let’s swap out the hard-coded template for the title we provided. This can be done by replacing the contents of the <h2>
tag in the view template with our $projectGridHeadline
value:
<h2><?=$projectGridHeadline?></h2>
Now things look like this:
This is good, but notice the styling is off? That’s because our template assumes that one of these words is going to be wrapped in a <span>
tag. So let’s update the project grid headline with the proper HTML from our template:
This looks better:
Sanitize HTML against XSS
This approach raises some questions, however: are we really going to allow our editors to put whatever they want in this box? That’s basically what we have here. We are fully trusting our editors with this content, and outputting whatever they enter into the page. In general, this is the approach that Concrete CMS takes: we guard against XSS attacks for guests and basic registered users, but much of the editing interface allows editors free reign to place what they want into blocks and page attributes.
For this block type, however, let’s lock it down a bit. If we wanted to fully sanitize the output against XSS, we could simply wrap $projectGridHeadline
in an h()
function. h()
is a global function that turns all HTML tags within it into HTML entities, so that they won’t be embedded as HTML. Employing this is just a matter of changing the echoing statement to
<?=h($projectGridHeadline)?>
However, doing that here results in a problem:
We don’t want to sanitize all tags. We want to allow editors to specify <span>
and <br>
tags, because our template relies on them. So let’s operate with a little more precision.
htmlawed
Concrete includes htmlawed, a simple library for sanitizing HTML with greater precision. Let’s use this library within our view()
method, and sanitize the $projectGridHeadline
before it even makes its way into the page.
First, undo the h()
method in the view.php file. Next, open your block controller and move to the empty view()
method. There, we’re going to use the block controller to set an updated version of $projectGridHeadline
after it has been run through htmlawed. Since htmlawed()
is just a global function, you don’t even need to import the class. Just run it on $this->projectGridHeadline
, which is automatically populated within the block controller:
If we refresh the page, everything still looks good:
But if we add something malicious into our block using the edit controls...
It is sanitized and output, and not run:
Now that we have the project grid headline outputting in the proper way, let’s move on to the project categories below it.