Jump to content

Markup Regions pw vs data-pw different behavior


Recommended Posts

I am trying Markup Regions for the first time on a site these days. And I have read Markup Regions Front-End Docs at ProcessWire.com. There is says that "pw-" and "data-pw-" is doing the same thing. Although I get different output when I try both in the same situation.

E.g. when I am trying to append a <script>-tag, I need to add data-pw-append=footer. With just pw-append, it will output the script above <doctype> and <html>. Also, I need to use data-pw-append inside a php function, with pw-append the same as above happens.

Other places, I cannot recall exactly where, the opposite happens. Where I have to use pw-append instead of data-pw-append. (Or pw-id instead of data-pw-id).

Is this normal behavior? Is there any more documentation on usage I have missed perhaps?

Link to comment
Share on other sites

@huseyin I think it is worth the change for me. I used a method where i included head.php, header.php and foot.php on each template. Now I have it all in _main.php. That alone was a step for me in the right direction.

Also, I have moved a lot of code around. My site has grown over time, so it was a lot of if statements in head.php e.g.:

if ($page->template == "basic-page") { …

Now I solve it with regions in _main.php and each template file.

Still getting to know Markup Regions though.

Link to comment
Share on other sites

Hi @snobjorn, I do not use markup regions myself, but maybe doing a g**gle search like this:

?q=site:processwire.com/ Markup Regions

will reveal something relevant you don't know?






Link to comment
Share on other sites

Could post a brief code snippet of what you are trying to do?

I am assuming you should have something like this:

On _main.php:

<footer id="footer-region">



On other_template.php

<div id="footer-region" pw-append>




@huseyin Just to give my personal opinion, I just really like that with markup regions you can code the markup pretty much like if you were doing normal template output, no string concatenation to fill up a variable to output content, instead of doing that you wrap your markup with the Markup Regions conventions. That would probably be the downside, that you have to understand that maybe not all markup visible in your code, will actually end up in the output markup (depending on how you use it!), and this has sometimes caused me confusion while coding, but nowadays I practically code all my templates with markup regions strategy. 

So in conclusion, I see it more as a "style" rather than something better or worse. 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

I always use the Markup Regions, until now I haven't needed more complicated system in my projects. Roughly this is my standard configuration:


<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="..3rd_party_styles_1.css">
    <link rel="stylesheet" href="..3rd_party_styles_2.css">
    <pw-region id="styles_area"></pw-region><!--#styles_area-->
    <link rel="stylesheet" href="..my_main_style.css">
    <pw-region id="head_area"></pw-region><!--#head_area-->
        Header Content Here (regularly a file included)
    <div class="container">
        <pw-region id="content_area"></pw-region><!--#content_area-->
        Footer Content Here (regularly a file included)
    <pw-region id="append_area"></pw-region><!--#append_area-->
    <script src="..3rd_party_scripts_1.js"></script>
    <script src="..3rd_party_scripts_2.js"></script>
    <pw-region id="scripts_area"></pw-region><!--#scripts_area-->
    <script src="..my_main_scripts.js"></script>


<?php namespace ProcessWire; 
    $vars_or_arrays = "fill_some_vars_or_arrays_here";

<pw-region id="styles_area">
    <link rel="stylesheet" href="..3rd_party_styles_3.css">
      	body { background: #F2F2F2 !important; }
        h2 { text-transform: uppercase !important; }
        .classA { background: red; }
        .classB { font-size: 2rem; }

<pw-region id="head_area">
    <link rel="dns-prefetch" href="//example.com">
    <link rel="preconnect" href="//example.com">
    <link rel="prefetch" href="image.png">

<pw-region id="content_area">
        Here render your page content from $page or using $pages, $vars_or_arrays, etc.

<pw-region id="append_area">
    <div class="modal">
        <a href="#">close</a>
        <div class="modal_body">
            Content of modal window

<pw-region id="scripts_area">
    <script src="..3rd_party_scripts_3.js"></script>
        window.onload = function(event) {
            alert('Hello World!');

Use the regions from the main layout as needed on each page, to add a modal window, run a javascript, add styles, etc. I always use <pw-region> because this element is removed from the final markup if it's not used in the template file.

  • Like 3
Link to comment
Share on other sites

"Markup Regions pw vs data-pw different behavior"
I have not yet experienced such a behavior. Maybe you are mixing up "Boolean action attributes (inner HTML)" with "Action attributes with value (outer HTML)"? Regarding the differences between these two, see my explanation below.

18 hours ago, elabx said:

Could post a brief code snippet of what you are trying to do?


Here is my simplified docs for markup regions, we can also call it "cheat sheet". I wrote it some time ago:

Defining markup regions

Basic region

Wrapping tags do appear in the final markup. Children tags are preserved if not explicitly replaced.
<div id="hello"> OR <div data-pw-id="hello">
data-pw-... They are removed from the final output and thus not visible to front-end markup, while id="..." is not removed!

Placeholder region

Only the inner HTML will be used and the wrapping tags won't appear in the final markup. 
<pw-region id="hello">...</pw-region>

Good for groupping tags in the <head> eg.: <pw-region id="site_scripts"> 

Optional region

It will be automatically removed from the document markup if nothing populates it, so it is a region which should be empty by default.
<div id='hello' data-pw-optional></div>


  • an <ul>, which [according to HTML5 specs] is required to have one or more <li> elements within it, otherwise it's invalid HTML.
  • a sidebar which is only needed on pages populated with widgets

/* -------------------------------------------------------------------------------------------------- */

Populating markup regions

Available action attributes:

  • data-pw-replace: replaces a region’s markup
  • data-pw-append: appends markup to a region
  • data-pw-prepend: prepends markup to a region
  • data-pw-before: inserts markup before a region
  • data-pw-after: inserts markup after a region

Boolean action attributes (inner HTML)

Only applies the inner HTML to the region.

TARGET CODE: <div id='hello'> <h2> Hello World </h2> </div>

  • <p data-pw-id="hello" data-pw-append> This text will APPEND to div#hello </p>
  • <p data-pw-id="hello" data-pw-prepend> This text will PREPEND to div#hello </p>
  • <p data-pw-id="hello" data-pw-before> This will insert this text BEFORE div#hello </p>
  • <p data-pw-id="hello" data-pw-after> This will insert this text AFTER div#hello. </p>


This will insert this text BEFORE div#hello
<div id='hello'>
	This text will PREPEND to div#hello
	<h2> Hello World </h2>
	This text will APPEND to div#hello
This will insert this text AFTER div#hello

Action attributes with value (outer HTML)

All of the markup that you specify (the outer HTML) becomes part of the final document markup (except for the pw-* attributes):

TARGET CODE: <div id='hello'> <h2> Hello World </h2> </div>

  • <p data-pw-append="hello"> This paragraph will APPEND to div#hello </p>
  • <p data-pw-prepend="hello"> This paragraph will PREPEND to div#hello </p>
  • <p data-pw-before="hello"> This will insert this paragraph BEFORE div#hello </p>
  • <p data-pw-after="hello" class="world"> This will insert this paragraph with class "world" AFTER div#hello. </p>


<p> This will insert this paragraph BEFORE div#hello </p>
<div id='hello'>
	<p> This paragraph will PREPEND to div#hello </p>
	<h2> Hello World </h2>
	<p> This paragraph will APPEND to div#hello </p>
<p class="world"> This will insert this paragraph with class "world" AFTER div#hello. </p>

/* ------------------------------------------------  ------------------------------------------------ */

Adding HTML attributes

Any HTML attribute you add to the action tag that does not begin with pw- or data-pw- will be added to the originally defined region tag.

TARGET CODE: <ul id="foo" class="bar"> <li> First item </li> </ul>
ACTION CODE: <ul data-pw-append="foo" title="Hello"> <li> Second item </li> </ul>


<ul id="foo" class="bar" title="Hello">
	<li> First item </li>
	<li> Second item </li>

Adding and removing classes

  • Classes from the action tag and the region tag are merged by default.
  • To remove a class by the region action: prepend a minus sign to the class to be removed, eg: class="-foo bar" will result in class="bar"



  • Like 11
Link to comment
Share on other sites

 Thanks for the cheat sheet, @szabesz. And you're code is great inspiration @Pixrael.

Here's my code, @elabx, or parts of it. This is the code that gives me correct output.


<?php namespace ProcessWire; ?>
<!doctype html>

… template stuff

<footer pw-id=footer>
    … more template stuff


some-page-template.php, the relevant code at the bottom:

<?php namespace ProcessWire; ?>

… template stuff

    echo "<script data-pw-append=footer src=\"" . $config->urls->templates . "theme/js/showmore.min.js\"></script>";
    echo "<script data-pw-append=footer type=\"application/ld+json\">" . json_encode($schema_review) . "</script>";

But if I edit the last part, to <script pw-append=footer… instead of data-pw-append, it will output the scripts before <!doctype html>. That is what I don't get. Reading about the two variations being similar in usage.

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...