Templating makes the web go round. The synthesis of data and structure into content. It’s our coolest superpower as developers — grab some data, then make it work for us, in whatever presentation we need. An array of objects can become a table, a list of cards, a chart, or whatever we think is most useful to the user. Whether the data is our own blog posts in Markdown files, or on-the-minute global exchange rates, the markup and resulting UX are up to us as front-end developers. Show
PHP is an amazing language for templating, providing many ways to merge data with markup. Let’s get into an example of using data to build out an HTML form in this post. Want to get your hands dirty right away? In PHP, we can inline variables into string literals that use double quotes, so if we have a variable 0, we can write 1, and it prints the expected 2. For more complex templating, we can always concatenate strings, like: 3.For the old-schoolers, there’s 4. For multiline strings, you can use Heredoc (the one that starts like 5). And, last but certainly not least, we can sprinkle PHP variables inside HTML, like 6.All of these options are great, but things can get messy when a lot of inline logic is required. If we need to build compound HTML strings, say a form or navigation, the complexity is potentially infinite, since HTML elements can nest inside each other. What we’re trying to avoidBefore we go ahead and do the thing we want to do, it’s worth taking a minute to consider what we don’t want to do. Consider the following abridged passage from the scripture of WordPress Core, 7, verses 170-270:
In order to build out a navigation 8 in this function, we use a variable, 9, which is a very long string to which we keep adding stuff. This type of code has a very specific and limited order of operations. If we wanted to add an attribute to the 0, we must have access to 1 before this runs. And if we wanted to optionally nest a 2 or an 3 inside the 0, we’d need to author a whole new block of code that would replace the middle of line 7 with about 4-10 new lines, depending on what exactly we want to add. Now imagine you need to optionally add the 2 , and then optionally add the 3, either inside the 2 or after it. That alone is three 8 statements, making the code even less legible.It’s very easy to end up with string spaghetti when concatenating like this, which is as fun to say as it is painful to maintain. The essence of the problem is that when we try to reason about HTML elements, we’re not thinking about strings. It just so happens that strings are what the browser consumes and PHP outputs. But our mental model is more like the DOM — elements are arranged into a tree, and each node has many potential attributes, properties, and children. Wouldn’t it be great if there were a structured, expressive way to build our tree? Enter… The $p->setAttribute('class', 'headline');9 classPHP 5 added the 0 module to it’s roster of Not So Strictly Typed™ types. Its main entry point is the 9 class, which is intentionally similar to the Web API’s JavaScript 0. If you’ve ever used 3 or, for those of us of a certain age, jQuery’s 4 syntax, this will probably feel quite familiar.We start out by initializing a new 9:
Now we can add a 6 to it:
The string 7 represents the type of element we want, so other valid strings would be 8, 9 , etc.Once we have an element, we can set its attributes:
We can add children to it:
And finally, get the complete HTML string in one go:
Notice how this style of coding keeps our code organized according to our mental model — a document has elements; elements can have any number of attributes; and elements nest inside one another without needing to know anything about each other. The whole “HTML is just a string” part comes in at the end, once our structure is in place. The “document” here is a bit different from the actual DOM, in that it doesn’t need to represent an entire document, just a block of HTML. In fact, if you need to create two similar elements, you could save a HTML string using 0, modify the DOM “document” some more, and then save a new HTML string by calling 0 again.Getting data and setting the structureSay we need to build a form on the server using data from a CRM provider and our own markup. The API response from the CRM looks like this:
This example doesn’t use the exact data structure of any specific CRM, but it’s rather representative. And let’s suppose we want our markup to look like this:
What’s that 2? It’s a small trick that allows us to track in CSS whether the field is empty, without needing JavaScript. As long as the input is empty, it matches 3, but the user doesn’t see any visible placeholder text. Just the kind of thing you can do when we control the markup!Now that we know what our desired result is, here’s the game plan:
So let’s stub out our process and get some technicalities out of the way:
So far, we’ve gotten the data and parsed it, initialized our 9 and echoed its output. What do we want to do for each field? First off, let’s build the container element which, in our example, should be a 6, and the labelling 2 which is common to all field types:
Since we’re in a loop, and PHP doesn’t scope variables in loops, we reset the 8 element on each iteration. Then, if the field has a label, we build the element. At the end, we append it to the container element.Notice that we set classes using the 9 method. Unlike the Web API, there unfortunately is no special handing of class lists. They’re just another attribute. If we had some really complex class logic, since It’s Just PHP™, we could create an array and then implode it: 0.Single inputsSince we know that the API will only return specific field types, we can switch over the type and write specific code for each one: 0Now let’s handle text areas, single checkboxes and hidden fields: 1Notice something new we’re doing for the checkbox and hidden cases? We’re not just creating the 1 element; we’re making changes to the container 6 element! For a single checkbox field we want to modify the class of the container, so we can align the checkbox and label horizontally; a hidden 1‘s container should also be completely hidden.Now if we were merely concatenating strings, it would be impossible to change at this point. We would have to add a bunch of 8 statements regarding the type of element and its metadata in the top of the block. Or, maybe worse, we start the 5 way earlier, then copy-paste a lot of common code between each branch.And here is the real beauty of using a builder like 9 — until we hit that 0, everything is still editable, and everything is still structured.Nested looping elementsLet’s add the logic for 8 elements: 2OK, so there’s a lot going on here, but the underlying logic is the same. After setting up the outer 8, we make an array of 0s to append inside it.We’re also doing some 8-specific trickery here: If there is no pre-selected option, we add an empty placeholder option that is already selected, but can’t be selected by the user. The goal is to place our 2 as a “placeholder” using CSS, but this technique can be useful for all kinds of designs. By appending it to the 3 before appending the other options, we make sure it is the first option in the markup.Now let’s handle 4s of radio buttons and checkboxes: 3So, first we determine if the field set should be for checkboxes or radio button. Then we set the container class accordingly, and build the 4. After that, we iterate over the available choices and build a 6 for each one with an 1 and a 6.Notice we use regular PHP string interpolation to set the container class on line 21 and to create a unique ID for each choice on line 30. FragmentsOne last type we have to add is slightly more complex than it looks. Many forms include instruction fields, which aren’t inputs but just some HTML we need to print between other fields. We’ll need to reach for another 9 method, 0. This allows us to add arbitrary HTML without using the DOM structuring: 4At this point you might be wondering how we found ourselves with an object called 3, which actually represents a static 2 element. The goal is to use a common variable name for each iteration of the fields loop, so at the end we can always add it using 3 regardless of the actual field type. So, yeah, naming things is hard.ValidationThe API we are consuming kindly provides an individual validation message for each required field. If there’s a submission error, we can show the errors inline together with the fields, rather than a generic “oops, your bad” message at the bottom. Let’s add the validation text to each element: 5That’s all it takes! No need to fiddle with the field type logic — just conditionally build an element for each field. Bringing it all togetherSo what happens after we build all the field elements? We need to add the 3, 8, and 6 objects to the DOM tree we’re building. We can also use the opportunity to add common attributes, like 7. Then we’ll add the submit button, which is separate from the fields in this API. 6Why are we checking if 3 is truthy? Since we reset it to 9 at the top of the loop, and only build it if the type conforms to our expected switch cases, this ensures we don’t accidentally include unexpected elements our code can’t handle properly.Hey presto, a custom HTML form! Bonus points: rows and columnsAs you may know, many form builders allow authors to set rows and columns for fields. For example, a row might contain both the first name and last name fields, each in a single 50% width column. So how would we go about implementing this, you ask? By exemplifying (once again) how loop-friendly 9 is, of course!Our API response includes the grid data like this: 7We’re assuming that adding a 1 attribute is enough for styling the width, but that each row needs to be it’s own element (i.e. no CSS grid).Before we dive in, let’s think through what we need in order to add rows. The basic logic goes something like this:
Now, how would we do this if we were concatenating strings? Probably by adding a string like 2 whenever we reach a new row. This kind of “reversed HTML string” is always very confusing to me, so I can only imagine how my IDE feels. And the cherry on top is that thanks to the browser auto-closing open tags, a single typo will result in a gazillion nested 6s. Just like fun, but the opposite.So what’s the structured way to handle this? Thanks for asking. First let’s add row tracking before our loop and build an additional row container element. Then we’ll make sure to append each container 4 to its 5 rather than directly to 6. 8So far we’ve just added another 6 around the fields. Let’s build a new row element for each row inside the loop: 9All we need to do is overwrite the 5 object as a new DOM element, and PHP treats it as a new unique object. So, at the end of every loop, we just append whatever the current 5 is — if it’s still the same one as in the previous iteration, then the form is updated; if it’s a new element, it is appended at the end.Where do we go from here?Forms are a great use case for object-oriented templating. And thinking about that snippet from WordPress Core, an argument might be made that nested menus are a good use case as well. Any task where the markup follows complex logic makes for a good candidate for this approach. 9 can output any XML, so you could also use it to build an RSS feed from posts data.Here’s the entire code snippet for our form. Feel free it adapt it to any form API you find yourself dealing with. Here’s the official documentation, which is good for getting a sense of the available API. We didn’t even mention 9 can parse existing HTML and XML. You can then look up elements using the XPath API, which is kinda similar to 02, or 03 on Node.js. There’s a bit of a learning curve, but it’s a super powerful API for handling external content.Fun(?) fact: Microsoft Office files that end with 04 (e.g. 05) are XML files. Don’t tell the marketing department, but it’s possible to parse Word docs and output HTML on the server.The most important thing is to remember that templating is a superpower. Being able to build the right markup for the right situation can be the key to a great UX. How to get DOM element in PHP?The DOMDocument::getElementById() function is an inbuilt function in PHP which is used to search for an element with a certain id. Parameters:This function accepts a single parameter $elementId which holds the id to search for. Return Value: This function returns the DOMElement or NULL if the element is not found.
How to access HTML elements in PHP?Using the PHP DOMDocument Class, call the DOMDocument object. Call the predefined loadHTML() function with variable parameters. Using the getElementById() DOM function we get the HTML element value.
How to get all element with class name in JavaScript?The syntax is as follows:
var elements = document. getElementsByClassName(name); Here “name” is the class name you are looking to find and “elements” is a variable that would contain the array of elements.
How to select all elements with same class in JavaScript?To select elements by a given class name, you use the getElementsByClassName() method:. let elements = document.getElementsByClassName('className'); ... . <html> <head> <title>JavaScript getElementsByClassName() example</title> </head> <body> <div id="container"> <p class="note">The first note.</. |