New Markup Regions features in ProcessWire 3.0.250

11 July 2025 by Ryan Cramer   1 Comment

This week we have some useful upgrades to ProcessWire’s Markup Regions system. These upgrades make Markup Regions even more flexible and intuitive by reducing the dependence on HTML id attributes.

With these latest updates, you can now target specific markup regions without id attributes in many cases. While id attributes are still an ideal way to define and populate markup regions, we thought more options would be worthwhile and expand the scope of what you can do with markup regions.

If you aren't yet familiar with Markup Regions, be sure to see the Markup Regions documentation, as this blog post just covers the most recent additions to Markup Regions, and not the system as a whole.

It’s now easier to populate tags that appear once per document

For any HTML tags that are intended to appear only once per HTML document, you no longer need to specify an id attribute. Now you can just specify the tag. Such tags include <html>, <head>, <title>, <body> and <main> (…and <base> but who uses that?). For example, you can output this anywhere, and it will populate your <title> tag:

<title>Hello world</title>

Let’s say you want to append a CSS <link> tag to your <head>:

<head pw-append>
  <link rel="stylesheet" type="text/css" href="/file.css">
</head>

Or perhaps a script before the closing </body> tag:

<body pw-append>
  <script>alert('hello world');</script>
</body>

Or maybe a temporary alert at the top of the document:

<body pw-prepend>
  <div class="uk-alert uk-alert-danger">
    School is closed today due to snow.
  </div>
</body>

Prior to this update, you needed to give your tags an HTML id attribute before you could populate them with Markup Regions, i.e. you had to do this to define the tag:

<title id="my-title-id">My original title</title>

And you had to do this to populate it:

<title id="my-title-id">My replaced title</title>

I wasn’t wild about this because tags like "title", "head" and "body" really don’t need HTML id attributes since they are already implied to be unique. So in ProcessWire 3.0.250, you no longer need to give such elements id attributes in order to populate them as markup regions, unless you want to.

Populating regions by class name

Another new feature added is the ability to populate Markup Regions using a class name rather than an id attribute. In the example below, I’m prepending a paragraph of text to the beginning of every element having "uk-container" in its class attribute:

<p class="uk-text-primary" pw-prepend=".uk-container">
  Hello world
</p>

As you can see above, if you want to target an element by class then you just prefix it with a period "." Just like you would in CSS. Because we’re using a class name rather than an id attribute, it’s worth noting that this would update ALL elements having that class name. In my case, I’ve got several <div class="uk-container"> elements, so now they all say "Hello world" at the top of them in Uikit’s primary text color. Just something to consider, as that may or may not be what you want.

Populating regions by tag name

You can now also populate markup regions by tag name. This provides yet another way to populate regions of markup without using an id attribute:

<div pw-append="<footer>">
  <p>Copyright 2025 by somebody</p>
</div>

As demonstrated above, we just specify the literal HTML tag <footer> as the value to our pw-* action attribute. Like with using class names, it will populate all <footer> elements. So if you want to narrow it down, you can also include a class name. In the example below, we’re appending a copyright statement to a <footer class="terms"> element:

<div pw-append="<footer.terms>">
  <p>Copyright 2025 by somebody</p>
</div>

New pw-update action

A new pw-update attribute action has been added that essentially works like pw-append except that it can update the targeted element’s attributes, rather than adding a new element within it.

To demonstrate, review the footer example above where it added a <div><p>Copyright… to <footer class="terms">. If we used pw-update rather than pw-append, it would instead just append the <p>Copyright… rather than the <div><p>Copyright…

Let’s look at a more useful example that adds attributes to the targeted element. In this example below, we are adding the class "uk-container-large" to all elements having the class "uk-container":

<div pw-update=".uk-container" class="uk-container-large"></div>

Note how we left the tag content blank. That’s because we were only using it to add a class name to the targeted element(s). But if we did specify some markup within it, then it would also be appended to the targeted element(s):

<div pw-update=".uk-container" class="uk-container-large">
  <p>Hello world</p>
</div>

Below is an example of the final output:

<div class="uk-container uk-container-large">
  <!-- existing markup here -->
  <p>Hello world</p>
</div>

Even with these latest additions, chances are you’ll still want to target most elements using HTML id attributes, as has always been the case with Markup Regions. But hopefully these latest additions help to accommodate more cases that may arise from time to time, and reduce the need for adding id attributes that are only used by Markup Regions.


Comments

  • Mikel

    Mikel

    • 2 months ago
    • 00

    Great news, Ryan! For us the Markup Regions output strategy always fehlt a bit „clumsy” because of having to use ids. With these additions I am really looking forward to using it more often in future projects. Thank you for all the effort and advancement!

 

NextProcessWire website redesign

3

This week I’m thrilled to report that we have a new website online. The site was designed by Jan Ploch and Diogo Oliveira of KONKAT Studio in Hamburg Germany. More