Tag: Templating

What ya need there is a bit of templating

I had a fella write in to me the other day. He had some HTML, CSS, and JavaScript, and it just wasn’t behaving like he thought it ought to. The HTML had some placeholders in it and the JavaScript had some data in it, and the assumption was that the data would fill the placeholders.

To those of us with some degree of web knowledge, we can look at this and see why it’s not working like he thought it would. But I think it’s also valuable to try to see things from that perspective and then look at solutions that are hopefully as simple as the original problem seems to be.

The HTML was something like this…

<!DOCTYPE html> <html lang="en"> <head>   <meta charset="utf-8">   <title>Test</title>   <link rel="stylesheet" href="test.css">   <script src="data.js"></script> </head> <body>   <section>     <div>{company_name}</div>   </section> </body> </html>

The JavaScript was like this…

var company_data = {   "{company_name}" : "SOME COMPANY", };

There is nothing invalid going on here.

That’s all perfectly valid code. It is linked up right. It will run. It just doesn’t do anything besides render {company_name} to the screen. The expectation is that it would render SOME COMPANY to the screen instead, replacing the {company_name} placeholder with the data from the JavaScript file.

Let’s fix it with a one-liner.

In this exact scenario, to display the correct company name, we need to select that element in the DOM and replace its content with our data. We could do that by adding this one extra line to the JavaScript:

var company_data = {   "{company_name}": "SOME COMPANY" };  document.querySelector("div").innerHTML = company_data["{company_name}"];

That’s not particularly re-usable or resiliant, but hey, it’s also not over-thinking or over-tooling it.

The expectation was templating

I think we can see at this point that what he hoped would happen is that this sort of templating would automatically happen. Provide an object with keys that match what is in the HTML, the content in that HTML is automatically swapped out. It just doesn’t work that way with raw web technologies.

No joke, there are hundreds of ways to go about handling this. Here’s a few off the top of my head:

  • Use a templating language like Handlebars or Mustache
  • Use a static site generator like Eleventy, which uses Liquid by default
  • Make an HTML <template> and write your own script to use it
  • Make a Web Component
  • Use a back-end language instead, or a language like Nunjucks to process ahead of time
  • Use a preprocessor like Pug

As a general preference, I’d say doing the templating server-side or during a build is ideal — why mess with the DOM if you don’t need to?

But just to ignore that advice for a second, here’s an example of doing it client-side with Handlebars, just so the fella from the original email has a working example of how that can work:

The post What ya need there is a bit of templating appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.


, ,

A Follow-Up to PHP Templating

Not long ago, I posted about PHP templating in just PHP (which is basically HEREDOC syntax). I’m literally using that technique for some super basic templating I needed to do on this very WordPress site. The main pushback was that this kind of thing can be an XSS vulnerability. In my case, it’s not, because I’m not using it for anything other than an abstraction convenience for my own hand-written strings.

Since then, we’ve had a couple of good articles about templating and I’ve seen some other approaches. I thought I’d make a quick link dump of them.

  • Chris Geelhoed took a different approach than I did, passing data to a functio then using a require statement for a template file that expects global variables you set right before the require.
  • If you’re into the idea of using Twig as a PHP templating engine on your WordPress site, check out Timber. TJ Fogarty has written about this for us.
  • If Timber is a little heavy-handed, check out Sprig from Russell Heimlich. I really like this approach!
  • Jonathan Land shared how you can use Vue (inline) templates to do your templating, even in WordPress-land.
  • Charlie Walter wrote about many ways to approach PHP templating in WordPress, like in Jade, Mustache, and Twig, as well as some interesting combinations.
  • It was the first I’ve heard of this, but a templating language called TinyButStrong seems to fit the bill and looks like it’s actively developed.

The post A Follow-Up to PHP Templating appeared first on CSS-Tricks.



PHP is A-OK for Templating

PHP templating often gets a bad rap for facilitating subpar code — but that doesn’t have to be the case. Let’s look at how PHP projects can enforce a basic Model, View, Controller (MVC) structure without depending on a purpose-built templating engine.

But first, a very brief PHP history lesson

The history of PHP as a tool for HTML templating is full of twists and turns.

One of the first programming languages used for HTML templating was C, but it was quickly found to be tedious to use and generally ill-suited for the task.

Rasmus Lerdorf created PHP with this in mind. He wasn’t opposed to using C to handle back-end business logic but wanted a better way to generate dynamic HTML for the front end. PHP was originally designed as a templating language, but adopted more features over time and eventually became a full programming language in its own right.

PHP’s unique ability to switch between programming mode and HTML mode was found to be quite convenient, but also made it tempting for programmers to write unmaintainable code — code that mixed business logic and templating logic. A PHP file could begin with some HTML templating and then suddenly dive into an advanced SQL query without warning. This structure is confusing to read and makes reusing HTML templates difficult.

As time passed, the web development community found more and more value enforcing a strict MVC structure for PHP projects. Templating engines were created as a way to effectively separate views from their controllers.

To accomplish this task, templating engines typically have the following characteristics:

  1. The engine is purposely underpowered for business logic. If a developer wants to perform a database query, for example, they need to make that query in the controller and then pass the result to the template. Making a query in the middle of the template’s HTML is not an option.
  2. The engine takes care of common security risks behind the scenes. Even if a developer fails to validate user input and passes it directly into the template, the template will often escape any dangerous HTML automatically.

Templating engines are now a mainstay feature in many web technology stacks. They make for more maintainable, more secure codebases, so this comes as no surprise.

It is possible, however, to handle HTML templating with plain PHP as well. You may want to do this for a number of reasons. Maybe you are working on a legacy project and don’t want to bring in any additional dependencies, or maybe you are working on a very small project and prefer to keep things as lightweight as possible. Or maybe the decision isn’t up to you at all.

Use cases for PHP templating

One place that I often implement plain PHP templating is WordPress, which doesn’t enforce a rigid MVC structure by default. I feel that bringing in a full templating engine is a bit heavy-handed, but I still want to separate my business logic from my templates and want my views to be reusable.

Whatever your reason, using plain PHP to define your HTML templates is sometimes the preferred choice. This post explores how this can be done in a reasonably professional way. The approach represents a practical middle ground between the spaghetti-coded style that PHP templating has become notorious for and the no-logic-allowed approach available with formal templating engines.

Let’s dive into an example of how a basic templating system can be put into practice. Again, we’re using WordPress as an example, but this could be swapped to a plain PHP environment or many other environments. And you don’t need to be familiar with WordPress to follow along.

The goal is to break our views into components and create a distinct separation between the business logic and HTML templates. Specifically, we are going to create a view that displays a grid of cards. Each card is going to display the title, excerpt, and author of a recent post.

Step 1: Fetching data to render

The first step to take is fetching the data that we want to display in our view. This could involve executing a SQL query or using the ORM or helper functions of your framework/CMS to access your database indirectly. It could also involve making an HTTP request to an external API or collecting user input from a form or query string.

In this example, we’re going to use the WordPress get_posts helper function to fetch some posts to display on our homepage.

<?php // index.php $  wp_posts = get_posts([   'numberposts' => 3 ]);

We now have access to the data we want to display in the cards grid, but we need to do some additional work before we can pass it to our view.

Step 2: Preparing data for templating

The get_posts function returns an array of WP_Post objects. Each object contains the post title, excerpt, and author information that we need, but we don’t want to couple our view to the WP_Post object type because we might want to show other kinds of data on our cards somewhere else in the project.

Instead, it makes sense to proactively convert each post object to a neutral data type, like an associative array:

<?php // index.php $  wp_posts = get_posts([   'numberposts' => 3 ]);  $  cards = array_map(function ($  wp_post) {   return [     'heading' => $  wp_post->post_title,     'body' => $  wp_post->post_excerpt,     'footing' => get_author_name($  wp_post->post_author)   ]; }, $  wp_posts);

In this case, each WP_Post object is converted into an associative array by using the array_map function. Notice that the keys for each value are not title, excerpt, and author but are given more general names instead: heading, body, and footing. We do this because the cards grid component is meant to support any kind of data, not just posts. It could just as easily be used to show a grid of testimonials that have a quote and a customer’s name, for example.

With the data properly prepared, it can now be passed into our render_view function:

<?php // index.php // Data fetching and formatting same as before  render_view('cards_grid', [   'cards' => $  cards ]);

Of course, the render_view function does not exist yet. Let’s define it.

Step 3: Creating a render function

// Defined in functions.php, or somewhere else that will make it globally available. // If you are worried about possible collisions within the global namespace, // you can define this function as a static method of a namespaced class function render_view($  view, $  data) {   extract($  data);   require('views/' . $  view . '.php'); }

This function accepts the name of the rendered view and an associative array representing any data to be displayed. The extract function takes each item in the associative array and creates a variable for it. In this example, we now have a variable named $ cards that contains the items we prepared in index.php.

Since the view is executed in its own function, it gets its own scope. This is nice because it allows us to use simple variable names without fear of collisions.

The second line of our function prints the view matching the name passed. In this case, it looks for the view in views/cards_grid.php. Let’s go ahead and create that file.

Step 4: Creating templates

<?php /* views/cards_grid.php */ ?> <section>   <ul>     <?php foreach ($  cards as $  card) : ?>     <li>       <?php render_view('card', $  card) ?>     </li>     <?php endforeach; ?>       </ul> </section>

This template uses the $ cards variable that was just extracted and renders it as an unordered list. For each card in the array, the template renders a subview: the singular card view.

Having a template for a single card is useful because it gives us the flexibility to render a single card directly or use it in another view somewhere else in the project.

Let’s define the basic card view:

<?php /* views/card.php */ ?> <div class="card">   <?php if (!empty($  heading)) : ?>     <h4><?= htmlspecialchars($  heading) ?></h4>         <?php endif;   if (!empty($  body)) : ?>     <p><?= htmlspecialchars($  body) ?></p>         <?php endif;   if (!empty($  footing)) : ?>           <span><?= htmlspecialchars($  footing) ?></span>   <?php endif; ?> </div>

Since the $ card that was passed into the render function contained keys for a heading, body, and footing, variables of those same names are now available in the template.

In this example, we can be reasonably sure that our data is free of XSS hazards, but it’s possible that this view could be used with user input at some later time, so passing each value through htmlspecialchars is prudent. If a script tag exists in our data it will be safely escaped.

It’s also often helpful to check that each variable contains a non-empty value before rendering it. This allows for variables to be omitted without leaving empty HTML tags in our markup.

PHP templating engines are great but it is sometimes appropriate to use PHP for what it was originally designed for: generating dynamic HTML.

Templating in PHP doesn’t have to result in unmaintainable spaghetti code. With a little bit of foresight we can achieve a basic MVC system that keeps views and controllers separate from each other, and this can be done with surprisingly little code.

The post PHP is A-OK for Templating appeared first on CSS-Tricks.



PHP Templating in Just PHP

With stuff like template literals in JavaScript and templating languages, like JSX, I’ve gotten used to wanting to write my HTML templates in one nice chunk and sprinkling in variables wherever I need them.

I had a situation where I needed to do that in “raw” PHP the other day, so I’m just documenting it here.

Say I have some data like…

$  title = "The Title"; $  desc  = "Some information about this thing blah blah."; $  img   = "/images/header.jpg";

But that data changes, or there might be multiple sets of it, and I want to be able to pass that data into a function and have it spit out some HTML. That way, it’s easy to change the template and have it affect everywhere that uses it.

I don’t want to sprinkle it into some HTML as a one-off. I’d rather have a function.

function echo_card($  title = "Default Title", $  desc = "Default Description", $  img = "/images/fallback.jpg") {    echo ""; }

Rather than string-interpolate a bunch of HTML together, PHP has the HEREDOC syntax that is a smidge like JavaScript’s template literals.

function echo_card($  title = "Default Title", $  desc = "Default Description", $  img = "/images/fallback.jpg") {    $  html = <<<"EOT"       <div class="card">          <img src="$  img" alt="">          <h2>$  title</h2>          <p>$  desc</p>       </div> EOT;     echo $  html; }

Now I can call this function to echo an HTML template with my data.

echo_card($  title, $  desc, $  img);

I found it a fairly comfortable way to work, without requiring any other libraries or anything.

The post PHP Templating in Just PHP appeared first on CSS-Tricks.