concrete5 with XHP (facebook's XML syntax in PHP) - new repo up!

Permalink
Hi concrete5 people - just a quick announcement that I've setup a new repository athttps://github.com/jkoudys/concrete5-xhp... . This is part of my ongoing work to run concrete5 under facebook's excellent HHVM. As hacklang doesn't support mixed PHP + HTML, XHP is the standard way of writing view logic on hack. Fortunately, xhp is actually excellent, and even better, it works very well with how concrete5 is organized.

As a quick example, using this lib, you could convert:
<div id="header-area">
  <?php
    $a = new Area('Header Nav');
    $a->display($c);
  ?>
</div>


into:
<div id="header-area">
  <c5:area name="Header Nav" page={$c} />
</div>


While it's not something specific to c5 under xhp, I do find xhp (and hack) syntax to work very nicely for outputting lists of data. Rather than doing a big foreach (and waiting for the next developer to put something on the wrong side of its squiggly bracket at some point in the next year), you can do a nice little map like:
<ul>
  { $myPageList->map( $page ==> <li>{ $page->getCollectionName() }</li> ) }
</ul>


HTML helpers are completely obsolete as a concept with XHP, since rather than use a class to echo out strings of html, you can now define your own elements which render out to the html you need.

Rather than writing:
<?php
$form = Loader::helper('form');
?>
<form>
<h3>Some Header</h3>
<?= $form->text('uName', $uName, ['class' => 'loginname primary']>
<?= $form->select('favoriteFruit', array('p' => 'Pears', 'a' => 'Apples', 'o' => 'Oranges'), 'a') ?>
</form>


You write:
<c5:form>
  <h3>Some Header</h3>
  <c5:form-text name="uName" value={$uName} class="loginname primary" />
  <c5:form-select name="favoriteFruit" options={ array( 'p' => 'Pears', 'a' => 'Apples', 'o' => 'Oranges' ) } selected="a" />
</c5:form>


While the above examples are simple, you can see already how this really starts to work the bigger your page goes. The validation throws you errors earlier and better than any 3rd-party HTML validator could, the rendered page is free of whitespace, and most importantly: you're not mixing control flow logic with view logic. Experienced programmers will appreciate how organized it keeps your code, and someone who only knows HTML could easily write concrete5 views, as they'd simply need to learn a few new tags that start with <c5: .

edit:
I've now included Cache support, so you can set element trees entirely to the cache! You can do it from your view by just including the cache settings for that element directly into the attributes, e.g.:
<c5:area name="Search Results" cached={true} cache-timeout="3600" />


In a bigger site, these attributes could be added right before rendering the page using a config file. This is xml, meaning we can select through it similarly to the JavaScript DOM. This syntax is invalid right now (the selector is a bit clunky for these purposes), but hopefully in the future this sort of thing will be possible:
/* Cache all product preview thumbnails for 6 minutes */
foreach($htmlRootElement->getChildren('c5:pagelist.thumbnails') as $thumbnails) {
  $thumbnails->setAttributes(['cached' => true, 'cachetimeout' => 360]);
}


Which could then be quickly built out to a big config file where you just set selectors, and it sets the attributes for you:
['c5:pagelist.thumbnails', 360],
['c5:search#products, 30],
['ul#typeaheads li c5:form-select', 1200]

 
ijessup replied on at Permalink Reply
ijessup
Just stumbled on this.

Hell of an undertaking! Nice to see it happening.

Good luck, and keep us posted. :)