Jump to content

Markup regions help needed


SamC
 Share

Recommended Posts

I'm trying to get my head around the new markup regions. I've come across a problem. How do you wrap tags around two regions in a template file (a container) if '_main.php' is responsible for all output? This example renders the correct output:

_main.php

<region id="main">
  FULL WIDTH OR SIDEBAR IN HERE
</region>

basic-page.php

<region id="main">
  
<div class="container">
  
  <div class="content">
    Content in basic-page.php
  </div>

</div>

</region>

home.php

<region id="main">
  
<div class="container">
  
  <div class="content">
    Content in home.php
  </div>

  <div class="sidebar">
    Sidebar in home.php
  </div>

</div>

</region>


But how do I make the sidebar a region so I can populate it at will depending on which template is loaded but also add a container (which will be required)?

_main.php

<div id="main">
  FULL WIDTH OR SIDEBAR IN HERE
</div>

<div id="sidebar">
  THE SIDEBAR
</div>

I could just wrap a container around both in '_main.php':

<div class="container">

  <div id="main">
    FULL WIDTH OR SIDEBAR IN HERE
  </div>

  <div id="sidebar">
    THE SIDEBAR
  </div>

</div>

...but then EVERY page on the whole site would not be able to have full width elements. It's not possible to render tags via the page template files unless they are inside a tag/region with an id as they will be printed before the <html> tag.

I'm probably missing something here about markup regions. I know @bernhard mentioned using them recently so may be able to shed some light. Any hints would be great, thanks.

Link to comment
Share on other sites

1 hour ago, SamC said:

But how do I make the sidebar a region so I can populate it at will depending on which template is loaded but also add a container (which will be required)?

You could use pw-append on sidebar in template when it is needed instead of putting it inside _main.php.

In _main.php

<div id="main">
  FULL WIDTH OR SIDEBAR IN HERE
</div>

 

Inside some-template.php

<div id='sidebar' pw-append='main'></div>

 

  • Like 1
Link to comment
Share on other sites

@SamC, I don't entirely follow what you are saying, but here are a few things that might help.

1. You can remove elements in _main.php by using "pw-remove" in a template file.

_main.php

<div id="main">
  FULL WIDTH OR SIDEBAR IN HERE
</div>

<div id="sidebar">
  THE SIDEBAR
</div>

basic-page.php

<!-- Remove #sidebar -->
<div id="sidebar" pw-remove></div>

 

2. You can have as many nested ID'd or region elements in _main.php as you like, and then modify/replace any of them from your template.

_main.php

<region id="main">

    <div class="container">
    
        <div id="main">
            FULL WIDTH OR SIDEBAR IN HERE
        </div>
    
        <div id="sidebar">
            THE SIDEBAR
        </div>
    
    </div>

</region>

home.php

<div id="sidebar">
  <p>Just customise the sidebar.</p>
</div>

basic-page.php

<region id="main">
    <div class="container">  
        <p>Use a completely different #main on this template.</p>   
    </div>
</region>

 

3. The three blog posts about Markup Regions can be a bit confusing because the spec changed as the feature was developed and none of the posts cover the entire set of available keywords and syntax. Check out the comments in WireMarkupRegions.php for a more comprehensive spec.

/**
 * Identify and populate markup regions in given HTML
 *
 * To use this, you must set `$config->useMarkupRegions = true;` in your /site/config.php file.
 * In the future it may be enabled by default for any templates with text/html content-type.
 *
 * This takes anything output before the opening `<!DOCTYPE` and connects it to the right places
 * within the `<html>` that comes after it. For instance, if there's a `<div id='content'>` in the
 * document, then a #content element output prior to the doctype will replace it during page render.
 * This enables one to use delayed output as if it’s direct output. It also makes every HTML element
 * in the output with an “id” attribute a region that can be populated from any template file. It’s
 * a good pairing with a `$config->appendTemplateFile` that contains the main markup and region
 * definitions, though can be used with or without it.
 *
 * Beyond replacement of elements, append, prepend, insert before, insert after, and remove are also
 * supported via “pw-” prefix attributes that you can add. The attributes do not appear in the final output
 * markup. When performing replacements or modifications to elements, PW will merge the attributes
 * so that attributes present in the final output are present, plus any that were added by the markup
 * regions. See the examples for more details.
 *
 * Examples
 * ========
 * Below are some examples. Note that “main” is used as an example “id” attribute of an element that
 * appears in the main document markup, and the examples below focus on manipulating it. The examples
 * assume there is a `<div id=main>` in the _main.php file (appendTemplateFile), and the lines in the
 * examples would be output from a template file, which manipulates what would ultimately be output
 * when the page is rendered.
 * 
 * In the examples, a “pw-id” or “data-pw-id” attribute may be used instead of an “id” attribute, when
 * or if preferred. In addition, any “pw-” attribute may be specified as a “data-pw-” attribute if you
 * prefer it. 
 * ~~~~~~
 * Replacing and removing elements
 * 
 *   <div id='main'>This replaces the #main div and merges any attributes</div>
 *   <div pw-replace='main'>This does the same as above</div>
 *   <div id='main' pw-replace>This does the same as above</div>
 *   <div pw-remove='main'>This removes the #main div</div>
 *   <div id='main' pw-remove>This removes the #main div (same as above)</div>
 *
 * Prepending and appending elements
 * 
 *   <div id='main' class='pw-prepend'><p>This prepends #main with this p tag</p></div>
 *   <p pw-prepend='main'>This does the same as above</p>
 *   <div id='main' pw-append><p>This appends #main with this p tag</p></div>
 *   <p pw-append='main'>Removes the #main div</p>
 * 
 * Modifying attributes on an existing element
 * 
 *   <div id='main' class='bar' pw-prepend><p>This prepends #main and adds "bar" class to main</p></div>
 *   <div id='main' class='foo' pw-append><p>This appends #main and adds a "foo" class to #main</p></div>
 *   <div id='main' title='hello' pw-append>Appends #main with this text + adds title attribute to #main</div>
 *   <div id='main' class='-baz' pw-append>Appends #main with this text + removes class “baz” from #main</div>
 *
 * Inserting new elements
 * 
 *   <h2 pw-before='main'>This adds an h2 headline with this text before #main</h2>
 *   <footer pw-after='main'><p>This adds a footer element with this text after #main</p></footer>
 *   <div pw-append='main' class='foo'>This appends a div.foo to #main with this text</div>
 *   <div pw-prepend='main' class='bar'>This prepends a div.bar to #main with this text</div>
 * 
 * ~~~~~~

 

  • Like 2
Link to comment
Share on other sites

9 hours ago, Robin S said:

Markup Regions can be a bit confusing because the spec changed as the feature was developed

The comments in the source code are still confusing, for example last line of "Prepending and appending elements":

9 hours ago, Robin S said:

<p pw-append='main'>Removes the #main div</p>

Why does it remove the main div?

Anyway, I think @SamC might be looking for and "inject" sort of feature with which it is possible to add markup when it is not possible to prepend/append or replace, that is:

<div id="main">
   How can I INJECT markup here?
</div>

Either way, I find Markup Regions rather limited because these are just static commands  and it is not possible to conditionally change anything. For example, I have a sidebar with widgets and all publicly visible pages have a YAML field to configure the widgets it should display. When a page's widget configuration field is empty, the closest parent with valid widget configuration is used for that page. Such things are not possible with Markup Regions.

However, I do use Markup Regions but only in the <head> to define extra resources when a given template needs it, eg: <pw-region id='site-head' pw-append>. And I also use it for defining the main "view" of a given page in order to define the actual content rendered in _main-php, eg: <section pw-replace id="site-view" >.  But that's all there is to it in my case.

Link to comment
Share on other sites

2 hours ago, szabesz said:

Anyway, I think @SamC might be looking for and "inject" sort of feature with which it is possible to add markup when it is not possible to prepend/append or replace

I think this may be getting closer. Let's start with the final output:

<!-- /home/ -->
<div class="container-1400px">
  <div>SOME STUFF IN A CONTAINER</div>
</div>

<!-- /basic page/ -->
<div class="full-width-coloured-bg">
  <div class="container-1400px">
    <div>SOME STUFF IN A CONTAINER</div>
  </div>
</div>

<div class="container-1400px">
  <div class="row">
    <div class="col-10">
      LEFT SIDE
    </div>
    <div class="col-2">
      SIDEBAR
    </div>
  </div>
</div>

<!-- /services page/ -->
<div class="full-width-coloured-bg">
  <div class="container-1400px">
    FULL WIDTH STUFF
  </div>
</div>

<div class="container-1400px">
  <div>SOME STUFF IN A CONTAINER</div>
</div>

<div class="container-1400px">
  <div class="row">
    <div class="col-10">
      LEFT SIDE
    </div>
    <div class="col-2">
      SIDEBAR
    </div>
  </div>
</div>

I just can't see in any way how I can get this working with markup regions. With direct output and includes, it's a breeze, but the disadvantage to using direct output is that I'm having to set all my templates with an 'alternate template filename' of '_main.php' and then 'include($page->template->name)' in the main content area. Markup regions should allow me to pre-populate which would be nice.

Of course, I could go the WP route and just for each template include header, then the content, then include footer, so wouldn't have to set the alternate template filename at all, but never been a great fan of that approach either. I like using a master template where everything is rendered from within that.

Just can't see how this could be done. I was looking to use something like this:

<region id="outer" class="might-need-a-full-width-class-here">

  <region id="main"></region>
  <region id="sidebar"></region>

</region>

So in a template, sidebar will only appear if I add that tag:

// basic-page.php
<region id="sidebar">
  <?php include("./includes/sidebar"); ?>
</region>

But of course, as soon as you use a tag with an id of "outer" to get the wrapper div in, the entire contents of that region are replaced and the main and sidebar are zapped out of existence.

If you use div instead of region, the div is printed along with the class, which means you end up having full width wrappers around everything.

See what I'm saying? Finding this hard to explain.

Link to comment
Share on other sites

3 hours ago, szabesz said:

Why does it remove the main div?

Pretty sure that's just a typo, and should read "This does the same as above".

3 hours ago, szabesz said:

Such things are not possible with Markup Regions.

You can do anything with Markup Regions that you can do with the typical delayed output approach. Each markup region serves the same purpose as some variable that you would put markup in and output in _main.php, like $sidebar or whatever.

 

1 hour ago, SamC said:

Just can't see how this could be done.

There are a few ways. Here is one...

_main.php (just showing the main content part - of course there will be <head>, footer, etc in this file too)

<region id="main-content">
    <region id="top">
        <div class="full-width-coloured-bg">
            <div class="container-1400px">
                <div>SOME STUFF IN A CONTAINER</div>
            </div>
        </div>
    </region>

    <div class="container-1400px">
        <div class="row">
            <div class="col-10">
                LEFT SIDE
            </div>
            <div class="col-2">
                SIDEBAR
            </div>
        </div>
    </div>
</region>

basic-page.php

This file can be empty because _main.php is based on the markup needs of basic-page. But until this bug is fixed you might want to include some dummy region in basic-page.php or else the Markup Regions parser won't be triggered and <region> tags in _main.php will not be removed.

home.php

<region id="main-content">
    <div class="container-1400px">
        <div>SOME STUFF IN A CONTAINER</div>
    </div>
</region>

services-page.php

<region id="top">
    <div class="full-width-coloured-bg">
        <div class="container-1400px">
            FULL WIDTH STUFF
        </div>
    </div>

    <div class="container-1400px">
        <div>SOME STUFF IN A CONTAINER</div>
    </div>
</region>

 

  • Like 3
Link to comment
Share on other sites

3 hours ago, Robin S said:
7 hours ago, szabesz said:

Such things are not possible with Markup Regions.

You can do anything with Markup Regions that you can do with the typical delayed output approach. Each markup region serves the same purpose as some variable that you would put markup in and output in _main.php, like $sidebar or whatever.

I'm wondering how I could do this; for example we have in _main.php:

// _main.php
<head id="site-head">
  globally used stuff in head
</head>

Let's add some JS like this:

// template-which-needs-js.php
<pw-region id='site-head' pw-append>
    <script src="<?= urls()->templates ?>assets/js/my-script_1.js"></script>
</pw-region>

Let's say on some pages of template-which-needs-js.php  (say the ones with their $page->name beginning with "special" ) I have to link to my-script_2.js and not my-script_1.js How can I do that? How can "wrap it" in conditional statements? I've just made up this example, I do not actually need it but I've been wondering for a while how to do something like this, that is how to use Markup Region markups conditionally .

Link to comment
Share on other sites

5 hours ago, szabesz said:

Let's say on some pages of template-which-needs-js.php  (say the ones with their $page->name beginning with "special" ) I have to link to my-script_2.js and not my-script_1.js How can I do that?

Let's do a comparison of how you would do this with the typical delayed output approach vs Markup Regions. When it comes to the Markup Regions example I'll do it a little differently than you've proposed it, with a dedicated <region> for scripts instead of appending to <head>.

 

Delayed output

_init.php

$scripts = '';

_main.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <?= scripts ?>
</head>
//...

template-which-needs-js.php

if(strpos($page->name, 'special') === 0) {
    $scripts .= "<script src='{$config->urls->templates}assets/js/my-script_2.js'</script>";
} else {
    $scripts .= "<script src='{$config->urls->templates}assets/js/my-script_1.js'</script>";
}

 

Markup Regions

_init.php

Nothing needed here because one of the nice things about Markup Regions is that you don't need to initialise a markup variable.

_main.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <region id="scripts"></region>
</head>
//...

template-which-needs-js.php

<region id="scripts" pw-append>
    <?php if(strpos($page->name, 'special') === 0): ?>
        <script src="<?= $config->urls->templates ?>assets/js/my-script_2.js"></script>
    <?php else: ?>
        <script src="<?= $config->urls->templates ?>assets/js/my-script_1.js"></script>
    <?php endif; ?>
</region>

 

So comparing a markup region to a variable:

  • Use pw-append where you would have used $some_var .= 'something'
  • Use pw-prepend where you would have used $some_var = 'something' . $some_var
  • Use neither pw-append nor pw-prepend where you would have used $some_var = 'something'

But Markup Regions are even more powerful because you can have multiple nested markup regions in _main.php, which is something you cannot do with variables.

  • Like 4
Link to comment
Share on other sites

Thanks Robin for the example! To tell the truth I never tried <region> because I use NetBeans and even though it should be able to handle custom tags, actually it cannot do it on my Mac and complains about errors when HTML error checking is on :( That is why I decided not to use <region> tags in the first place so that the IDE does not report errors in the document.

Now that I see that more can be done using  <region> than simply using pw- attributes with standard html tags, I just do not know where to go from here. Turning off error checking for html is an option but that is not a workaround I like.

I've just downloaded Eclipse for php (PDT) to see if it can deal with it.

Link to comment
Share on other sites

Use the EAP version (early access program):

https://confluence.jetbrains.com/plugins/servlet/mobile#content/view/51185764

But you will see soon how helpful it is compared to other IDEs so chances are you will buy it. I also prefer freewares where possible but in this case it's worth the money. I tried Netbeans several times, lately about half a year ago but switched back to PhpStorm.

  • Like 1
Link to comment
Share on other sites

1 hour ago, szabesz said:

€ 199.00 /1st year
€ 159.00 /2nd year
€ 119.00 /3rd yr onwards

That's extremely expensive :(

That's the organisation pricing. You're an individual customer so it's $89. And you don't need to pay anything beyond that. See the license details.

The ongoing "subscription" is if you want to receive updates (sort of like the system with Ryan's Pro modules), but the reality is that an IDE is a glorified text editor - it's not like they're bringing out must-have new ways to edit text every other month. So you'll be fine with the current version for some years to come.

  • Like 1
Link to comment
Share on other sites

10 minutes ago, Robin S said:

So you'll be fine with the current version for some years to come.

You are right, it describes me quite well :)

Thanks for pointing out the important details, I really misunderstood their licensing policy and I did not even notice this "perpetual fallback license" thingy. Let's say – for example – I want to use PHPStorm for 3 years and I only pay €89. That's something to seriously consider! It should be realistic as it seems they even support OS X 10.5?
https://www.jetbrains.com/help/phpstorm/system-requirements.html#d341056e226

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...