Publications

Tutorials

Slots & Plugs

This FigDice mechanism is useful when you can factor out a common shape for your all your pages, with various sections whose contents you want to delegate to the actual view your controller is requested for.

Suppose that all your pages contain an HTML header with title, and a menu, and a footer.
All these components are almost the same everywhere, with possibly some slight differences from page to page: for example, the <title> tag would reflect the actual current page's topic.

<html>
<head>
<title> [I want my article's title here] </head>
</head>

<body>
<div class="Menu"> [I want my menu here] </div>

<div class="PageContent"> [I want my article here] </div>

<div class="Footer"> [I want my footer here] </div>
</body>
</html>

Your controller is requested to pull a particular article page, and you want to focus on the contents of this page. You do not want all your pages to reimplement the same structure above.

Yet, each article will provide its particular title.

You can do this with Slots and Plugs. Your procedure becomes:

  • one generic page layout HTML file,
  • one specific FigDice template per article,
  • your controller loads solely the article-specific template,
  • which includes the generic layout,
  • and supplies specific contents to the identified placeholders.

Although the identically-repeated parts (here: menu and footer) can be achieved with plain includes, the Slots and Plugs are a special feature for contextual content blocks.

file: page-layout.html

<html>
<head>
<title fig:slot="docTitle" />
</head>
<body>
<div class="Menu"> <fig:include file="menu.html" /> </div>

<div class="PageContent">
<div fig:slot="pageContent" />
</div>

<div class="Footer"> <fig:include file="footer.html" /> </div>
</body>
</html>

file: myarticle.html

<xml fig:mute="true"> <!-- Mute because this tag
should not end up in the HTML document.
But the FigDice template must have an XML root node. -->


<!-- Load the generic Page Layout...
This is the only thing you have to repeat in every article file! -->

<fig:include file="page-layout.html" />

<!-- My Article initialization... -->
<fig:feed ... />

<!-- Supply the <title> tag now!... -->
<title fig:plug="docTitle"> Actual Title Here </title>

<!-- Supply the contextual page content now!... -->
<div fig:plug="pageContent"> Lorem ipsum... </div>
</xml>

controller:

$view = new \figdice\View();
...
$view->loadFile( 'myarticle.html' );

echo( $view->render() );


With this mechanism, for example, you can also provide meta keywords specific to each page, without the need to duplicate the HTML skeleton in every single page.

In fact, you simply invert the natural inclusion principle: instead of pulling common areas, you push contextual content into externally defined placeholders.

Internationalization

Your application contains multiple views (high-level views rendering complete HTML DOM ; and partial views which you load dynamically with Ajax into your pages). Now you need to translate the views into various natural languages.

You create Dictionaries which provide translations against keys, and you use the keys in your views instead of direct human text.

file: contact.xtml (French Dictionary)


<fig:dictionary xmlns:fig="http://www.figdice.org/" language="fr"> <!-- Indicate the target language of this translation file -->

<!-- List all the keys that your dictionary handles... -->
<entry key="Title">Titre<entry>
<entry key="Lastname">Nom<entry>
<entry key="Firstname">Prénom<entry>
<entry key="DateOfBirth">Date de naissance<entry>

<!-- Entries can contain HTML tags: -->
<entry key="NumberOfFriends">Nombre<br/>d'amis<entry>

<!-- Entries can contain parameters:
use the parameters by their name, as passed to the fig:trans tag,
and enclose them in curly braces: -->

<entry key="ContactHasNFriends">Ce contact a {numberOfFriends} amis.<entry>

</fig:dictionary>

You are advised to partition your dictionaries according to consistent feature groups.
That is: put your keys regarding Contact-related screens in a contact.xml dictionary, and your keys regarding Product-related screens (within the same app) in a product.xml dictionary.
This enables you to:

  • potentially reuse your dictionaries across applications,
  • reduce the length of your keys, whose names are locally scoped to a given dictionary,
  • maintain smaller dictionaries, easier to handle,
  • load specialized dictionaries in different views, so as to avoid loading your entire translation book in small views where it is not needed.

You will organize your dictionary files in the following tree:

myproject/lang
  + fr
    - contact.html
    - product.html
  + de
    - contact.html
    - product.html
  + es
    - contact.html
    - product.html

In your Template file, you load and use the dictionaries as follows:
file: view-contact.xml

<html>
<!-- Load the dictionary files of interest in your current template
and specify a local alias for each of them: -->

<fig:dictionary file="product.xml" name="Product" />
<fig:dictionary file="contact.xml" name="Contact" />


<!-- Now, when you need to output captions, use Keys from Dictionaries
instead of hard-coded text: -->

<table>
<tr>
<td> <fig:trans dict="Contact" key="Title" /> </td>
<td> <span fig:text="/customer/title" /> </td>
</tr>
<tr>
<td> <fig:trans dict="Contact" key="Lastname" /> </td>
<td> <span fig:text="/customer/lastname" /> </td>
</tr>
</table>
<fig:trans dict="Contact" key="ContactHasNFriends" numberOfFriends="count(/customer/friends)" />
</html>

Now, before you render the \figdice\View template, you must tell it what is the target language to display:

file: controller.php

$figView = new \figdice\View();
//Tell the View where to find the Dictionary tree:
$figView->setTranslationPath( 'myproject/lang' );
...
$figView->setLanguage( 'fr' );
//The target language will be most probably defined in your session data
...
$html = $figView->render();