johnstephens

What common, non-obvious site components can be custom-built from the API?

Recommended Posts

johnstephens    18

This is a story of desire, stilted romance, triumph, and discovery of a simpler way.

TL;DR: ProcessWire has hidden goodies in it, but it makes me wonder what else I'm missing.

The other day I was thinking, "Hey, I make a lot of navigation. Lists of links, glossary-style HTML sitemaps with links and descriptions, nested menus, etc. I wonder if I could automate some of the markup and stuff by making a custom function?"

So normally, I might build a navigation menu in ProcessWire like this:

$menu = $pages->get('/')->children;

$out = "<ul class='my-menu-class'>";

foreach($menu as $item) {

  $out .= "<li class='my-item-class'><a class='my-link-class' href='{$item->url}'>{$item->title}</a></li>";

}

$out .= "</ul>";

Within this, there are only a handful of things I might want to handle differently for different menus: The classes, the HTML elements, the pages included,  the sort, and the limit, for a few.

After some amateur writing and testing, I came up with a new object class that would take some config and return a menu in HTML:

$out = '';

require_once('./ClassMenu.php');

$menu_settings = array(
  'pages' => $pages->get('/')->children,
  'label_class' => 'my-label-class',
  'label_tag' => 'dt',
  'desc_class' => 'my-description-class',
  'desc_tag' => 'dd',
  'desc_field' => 'description',
  'wrap_class' => 'my-list-class',
  'wrap_tag' => 'dl'
);

$menuzilla = new Menu($menu_settings);

$out .= $menuzilla->render();

 

The above menu would return something like this:

<dl class='my-list-class'>
  <dt class='my-label-class'><a href='/about/'>About</a></dt>
  <dd class='my-description-class'>About page description…</dd>
  <dt class='my-label-class'><a href='/products/'>Products</a></dt>
  <dd class='my-description-class'>Product page description…</dd>
  <dt class='my-label-class'><a href='/misc/'>Miscellanium</a></dt>
  <dd class='my-description-class'>Miscellanium page description…</dd>
  <!-- etc. -->
</dl>

It worked great, and it was pretty flexible. As I considered adding more complex functionality, I remembered Soma's tutorial about building forms with ProcessWire, and I wondered if I could learn something about building markup from ProcessWire's render method.

That's when I found MarkupPageArray.

MarkupPageArray, for those who don't know, adds a render method to page arrays, giving them the ability to generate HTML without further ado, like so:

$out = '';

$menu = $pages->get('/')->children;

$out .= $menu->render();

But what if you don't like ProcessWire's default markup or classes? You can override that simply:
 

$out = '';

$menu = $pages->get('/')->children;

$out .= $menu->render(array(
  'listMarkup' => "<dl class='my-list-class'>{out}</dl>",
  'itemMarkup' => "<dt class='my-label-class'><a href='{url}'>{title}</a></dt><dd class='my-description-class'>{description}</dd>"
));

This renders the same HTML I posted above, using only ProcessWire's own API and no custom functions.

It brings a tear to the eye.

So my question is this: What other common site components are hidden in the API waiting to be uncovered by the hapless and meek in their thrashing about for wisdom?

  • Like 7

Share this post


Link to post
Share on other sites

Hey there!

I find myself discovering more and more beauty when working with ProcessWire. this render method is also new for me. Thank you a lot for sharing this.

  • Like 2

Share this post


Link to post
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


  • Recently Browsing   0 members

    No registered users viewing this page.