Tales of a Metal Cloud – Part 2

Metal Cloud
Photo by dedalusj

This article is looong overdue. I started it in July 2012 and never got any further, but now ownCloud 5 is released, and I have just released version 0.2 of TAL Page Templates for ownCloud so here it goes 😉 (Some of the examples for "current" ownCloud templates are a bit outdated, but I hope you get the gist of it)

In last episode of...

In the previous post about TAL Page Templates for ownCloud I gave my reasons for wanting to implement PHPTAL in ownCloud, and gave a short example of the benefits it will give for the developer. I wrote I "...will dig deeper into how to use it to render a full page, how to access variables, how to make use of the powerfull METAL.." which I have later decided not to do, as many have described that better than I could do, so if you're not familiar with TAL and METAL, there's plenty to read in the resources section in that post. I also wrote that I would show "...how I’ve plugged it all in to use ownClouds built-in authentication, template discovery and internationalization system", but thinking about it, there is no reason for showing how it's implemented, but rather I should show more of how to use the ownCloud specific parts. So this will mostly be a manual-like listing of how to use TAL page templates compared to the current use of inline PHP code.

What's next

With ownCloud 5 comes the new App Framework with another template engine - Twig. Personally I'm not very fond of the Twig markup, so hopefully from ownCloud 6 it will be possible to choose which engine to use. The App Framework is still very new, and I haven't explored it properly, but I'm sure it will be a great adition to ownCloud - especially if you can use TAL to write your templates 😉

Links and images

A lot of the scripting used in ownClouds page templates is for linking to apps, pages, services and images. There are several convenience methods for this. PHPTAL implements the standard set of TALES expressions, but also allows you to create custom expression modifiers. I have utilized this to substitute the direct PHP calls.

Linking to an image

Before:
<img class="svg" src="<?php echo image_path('', 'logo-wide.svg'); ?>" alt="ownCloud" />
<img class="svg" src="<?php echo image_path('app', 'someimage.png'); ?>" alt="ownCloud" />
After:
<img class="svg" tal:attributes="src image:string:logo-wide.svg" alt="ownCloud" />
<img class="svg" tal:attributes="src image:string:app/someimage.png" alt="ownCloud" />

Constructing a link

Before:
<a href="<?php echo link_to('', 'index.php'); ?>">Home</a>
<a href="<?php echo link_to('app', 'index.php'); ?>">Some app</a>
After:
<a tal:attributes="href linkto:string:index.php">Home</a>
<a tal:attributes="href linkto:string:app/index.php">Some app</a>

Link to remote service

Before:
<link rel="stylesheet" href="<?php echo OC_Helper::linkToRemote('core.css') ?>" type="text/css" media="screen" />
<a href="<?php echo OC_Helper::linkToRemote('webdav') ?>">WebDAV</a>
After:
<link rel="stylesheet" type="text/css" media="screen" tal:attributes="href remote:string:core.css" />
<a tal:attributes="href remote:string:webdav">WebDAV</a>

Accessing configuration

Before:
ownCloud version: <?php echo OCP\Config::getSystemValue('version'); ?>
Default quota: <?php echo OCP\Config::getAppValue('files', 'default_quota'); ?>
Calendar time zone: <?php echo OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone'); ?>
After:
ownCloud version: ${config:string:sys/version}
Default quota: ${config:string:app/files/default_quota}
Calendar time zone: ${config:string:user/calendar/timezone}

Translating content

Before:
<p><?php echo $l->t('This will be translated.'); ?><p>
After:
<p i18n:translate="">This will be translated.<p>
Read more...

Translating content with variables

Before:

There is no standardized way to do this currently. I have seen both translation keys using printf formatting and custom interpolation using e.g. curly brackets.

After:
<tal:block i18n:name="username" tal:content="user" />
<p i18n:translate="">Your user name is ${username}.</p>

Your user name is ${username}.

Or you can wrap it in some markup:

<p i18n:translate="">
Welcome back <span i18n:name="username" tal:replace="user"/>.
</p>

Welcome back .

Read more...

Translating attributes.

Before:
<img alt="<?php echo $l->t('Log out');?>" title="<?php echo $l->t('Log out');?>" src="<?php echo image_path('', 'actions/logout.svg'); ?>" />
After:
<img tal:attributes="src image:string:/actions/logout.svg" i18n:attributes="alt;title" alt="Log out" title="Log out" />
See more...

Iterating

$arr = array('color' => 'red',
            'taste' => 'sweet',
            'shape' => 'round',
            'name'  => 'apple');
Before:
<select size="4">
<?php foreach($$arr as $key=>$value) { ?>
<option value="<php echo $key; >" ><php echo $value; ></option>
</select>
<?php } ?>
After:
<select size="4">
<option tal:repeat="item arr" tal:attributes="value repeat/item/key" tal:content="item"></option>
</select>
Read more...

If you want to try it out, you will need ownCloud 5.x where you can enable the "TAL Page Templates for ownCloud" app from Settings/Apps. If you prefer to install from git, it's available at Github.

Flattr this!

Posted in ownCloud, PHP. Tags: , , . No Comments »

Tales of a Metal Cloud – Part 1

About reaching the goal and beautifying the path or Usability is also about the code (usability in the code?).
Metal Cloud

Many moons ago, when I unintentionally had ended up as a web developer, I had the pleasure of working for two small companies that both used Plone and hence ZPT - Zope Page Templates. After messing around with all kinds of ugly, inconsistent web coding, it was a relief to be able to use the clean markup that TAL provides, and seamlessly assemble pages using METAL.

Using Zope also had the benefit of having Python as it's backend scripting language. I don't want to dive into how much I prefer Python over PHP - enough has been said about that already - and I fully acknowledge that the ubiquity of PHP makes it the perfect choice for a project like ownCloud. Nor do I want to question the strength of the template class used in ownCloud; you can do practically everything. But the strength of OC_Template is IMHO also it's weakness.

During the few months I've been coding for ownCloud, ideas for it's usage have spawned, new apps pop up, code is being tweaked to do amazing stuff and soon the app repository will be "there's an app for that" also for ownCloud.

Being at the point where everyone can create and publish an app for ownCloud sets up some requirements:

  • Maintainability: If the app is ever abandoned, it has to be easy for a new maintainer to take over. This leads to:
  • Readability: No-one wants to maintain an app with poorly structured code and markup, or with none or insufficient documentation.
  • Validity: This is very broad and covers e.g. packaging, cross browser usability and that the markup adheres to common standards.
Maintain the beauty of the markup.

With the Template Attribute Language (TAL) we can achieve having beautifully structured markup, and the interpreter will let us know of any missing end tags or wrongly nested markup, as a matter of fact the page won't render if we mess it up.

The good thing is that some good people have made a PHP library that implements TAL, TALES and METAL, so I've made a proof of concept ownCloud integration using it, which actually works pretty well, if I may say so 😉

Time to show what this will mean for the template author. As example I use the form for editing the structured name data in the ownCloud Contacts app.
Below is how the currently used markup looks.

< ?php
$name = isset($_['name'])?$_['name']:'';
?>
<div id="edit_name_dialog" title="Edit name">
	<form>
	<fieldset>
	<dl class="form">
		<dt><label for="pre">< ?php echo $l->t('Hon. prefixes'); ?></label></dt>
		<dd>
			<input name="pre" id="pre" value="<?php echo isset($name[3]) ? $name[3] : ''; ?/>" type="text" list="prefixes" />
			<datalist id="prefixes">
				<option value="<?php echo $l->t('Mrs.'); ?>">
				</option><option value="<?php echo $l->t('Mr.'); ?>">
				</option><option value="<?php echo $l->t('Sir'); ?>">
				</option><option value="<?php echo $l->t('Dr.'); ?>">
			</option></datalist>
		</dd>
		<dt><label for="giv">< ?php echo $l->t('Given name'); ?></label></dt>
		<dd><input name="giv" id="giv" value="<?php echo isset($name[1]) ? $name[1] : ''; ?/>" type="text" /></dd>
		<dt><label for="add">< ?php echo $l->t('Additional names'); ?></label></dt>
		<dd><input name="add" id="add" value="<?php echo isset($name[2]) ? $name[2] : ''; ?/>" type="text" /></dd>
		<dt><label for="fam">< ?php echo $l->t('Family name'); ?></label></dt>
		<dd><input name="fam" id="fam" value="<?php echo isset($name[0]) ? $name[0] : ''; ?/>" type="text" /></dd>
		<dt><label for="suf">< ?php echo $l->t('Hon. suffixes'); ?></label></dt>
		<dd>
			<input name="suf" id="suf" value="<?php echo isset($name[4]) ? $name[4] : ''; ?/>" type="text" list="suffixes" />
			<datalist id="suffixes">
				<option value="<?php echo $l->t('M.D.'); ?>">
				</option><option value="<?php echo $l->t('Ph.D.'); ?>">
				</option><option value="<?php echo $l->t('Jr.'); ?>">
				</option><option value="<?php echo $l->t('Sn.'); ?>">
			</option></datalist>
		</dd>
	</dl>
	</fieldset>
	</form>
</div>

This isn't exactly pretty, and if you want to use a visual HTML editor, it won't look good there either. And believe me, this isn't the worst looking example 😉
Let's see the same snippet edited for using TAL and TALES

<div id="edit_name_dialog" i18n:domain="contacts" i18n:attributes="title" title="Edit name">
	<form>
	<fieldset tal:condition="name">
	<dl class="form">
		<dt><label for="pre">Hon. prefixes</label></dt>
		<dd>
			<input name="pre" id="pre" tal:attributes="value name/3|nothing" value="" type="text" list="prefixes" />
			<datalist id="prefixes">
				<option i18n:attributes="value" value="Mrs." />
				<option i18n:attributes="value" value="Mr." />
				<option i18n:attributes="value" value="Sir" />
				<option i18n:attributes="value" value="Dr" />
			</datalist>
		</dd>
		<dt><label for="giv" i18n:translate="">Given name</label></dt>
		<dd><input name="giv" id="giv" tal:attributes="value name/1|nothing" value="" type="text" /></dd>
		<dt><label for="add" i18n:translate="">Additional names</label></dt>
		<dd><input name="add" id="add" tal:attributes="value name/2|nothing" value="" type="text" /></dd>
		<dt><label for="fam" i18n:translate="">Family name</label></dt>
		<dd><input name="fam" id="fam" tal:attributes="value name/0|nothing" value="" type="text" /></dd>
		<dt><label for="suf" i18n:translate="">Hon. suffixes</label></dt>
		<dd>
			<input name="suf" id="suf" tal:attributes="value name/4|nothing" value="" type="text" list="suffixes" />
			<datalist id="suffixes">
				<option i18n:attributes="value" value="M.D." />
				<option i18n:attributes="value" value="Ph.D." />
				<option i18n:attributes="value" value="Jr." />
				<option i18n:attributes="value" value="Sn." />
			</datalist>
		</dd>
	</dl>
	</fieldset>
	</form>
</div>

In part 1 I've shown the basics of using TAL, but this is only a foretaste of how PHPTAL can be used in ownCloud. In the next part - hopefully comming shortly - I will dig deeper into how to use it to render a full page, how to access variables, how to make use of the powerfull METAL macros and how I've plugged it all in to use ownClouds built-in authentication, template discovery and internationalization system.

In the meanwhile have a look at the resources below for information about TAL, TALES and METAL


Update: I wrote this article quite a while ago, but never got around to publishing it. In the mean time I've made my implementation available at https://github.com/tanghus/tal/ and made a Journal/Notes app utilizing it which is available at https://github.com/tanghus/journal/. I will publish both soon at the ownCloud app repository.
Update 2: The TAL Page Templates only works on current git master which will be released as ownCloud 5 in some time within the next couple of months 😉 Update 3: I have released TAL Page Templates for ownCloud 4.5 and it is available from the app repository, or from Settings/Apps when you have installed/upgraded to 4.5. At the same time I have released a small Journal/Notes app which uses the TAL templates.

Flattr this!

Posted in ownCloud, Programming. Tags: , , . 7 Comments »