Diazo Theming Guidelines¶
This guidelines tries to make it easier to start a new Diazo based theme for Plone. They contain Plone HTML and Diazo snippets to copy into your theme. Some tips for plone.app.theming are also included.
Contents¶
HTML Snippets¶
HTML Snippets of default Plone elements to copy into your static theme template.
Basic HTML template¶
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Plone OpenSource CMS auf Basis von Python und Zope</title>
<meta name="viewport" content="width=device-width" />
</head>
<body>
<div id="visual-portal-wrapper">
<!-- Plone header -->
<!-- Plone body -->
<!-- Plone footer -->
</div>
</body>
</html>
Plone Layout¶
Header¶
<div id="portal-header">
### HEADER ###
</div>
Body¶
<div id="portal-columns">
<div id="portal-column-one">
### COL1 ###
</div>
<article id="portal-column-content">
<div id="content-wrapper">
<div class="documentEditable">
<div id="edit-bar">
</div>
<dl class="portalMessage info">
<dt>Info</dt>
<dd>Information Message.</dd>
</dl>
<dl class="portalMessage error">
<dt>Error</dt>
<dd>Error Message.</dd>
</dl>
<div id="content">
### CONTENT ###
</div>
</div>
</div>
</article>
<div id="portal-column-two">
### COL2 ###
</div>
</div>
Plone Elements¶
Plone elements to copy into theme templates.
General Elements¶
General Plone elements to copy into theme templates.
Personaltools¶
<div id="portal-personaltools-wrapper">
<dl class="actionMenu activated" id="portal-personaltools">
<dt class="actionMenuHeader">
<a id="user-name" href="">admin</a>
</dt>
<dd class="actionMenuContent">
<ul>
<li id="personaltools-dashboard">
<a href="">Persönliche Seite</a>
</li>
<li id="personaltools-preferences">
<a href="">Meine Einstellungen</a>
</li>
<li id="personaltools-plone_setup">
<a href="">Konfiguration</a>
</li>
<li id="personaltools-logout">
<a href="">Abmelden</a>
</li>
</ul>
</dd>
</dl>
</div>
Siteactions¶
<div id="siteactions-wrapper">
<ul id="portal-siteactions">
<li><a href="">Startseite</a></li>
<li><a href="">Sitemap</a></li>
<li><a href="">Kontakt</a></li>
<li><a href="">Impressum</a></li>
</ul>
</div>
Languageselector¶
<ul id="portal-languageselector">
<li class="language-de"><a href="" title="Deutsch"> </a></li>
<li class="language-en"><a href="" title="English"> </a></li>
<li class="language-pl"><a href="" title="Polski"> </a></li>
</ul>
Logo¶
<a id="portal-logo"
href=""
title="Plone OpenSource CMS auf Basis von Python und Zope"
accesskey="1">
<img src="images/logo.png" />
</a>
Searchbox¶
<div id="portal-searchbox">
<form name="searchform"
id="livesearch0"
action="@@search">
<div class="LSBox">
<label class="hiddenStructure"
for="searchGadget">Website durchsuchen</label>
<input name="SearchableText"
type="text"
size="18"
title="Website durchsuchen"
accesskey="4"
class="searchField"
id="searchGadget"
placeholder="Website durchsuchen"
autocomplete="off">
<input class="searchButton" type="submit" value="Suche">
<div class="searchSection">
<input id="searchbox_currentfolder_only"
class="noborder"
type="checkbox"
name="path"
value="/">
<label
for="searchbox_currentfolder_only">nur im aktuellen Bereich</label>
</div>
</div>
</form>
<div id="portal-advanced-search" class="hiddenStructure">
<a href="@@search" accesskey="5">Erweiterte Suche…</a>
</div>
</div>
Breadcrumbs¶
<div id="portal-breadcrumbs">
<span id="breadcrumbs-you-are-here">Sie sind hier:</span>
<span id="breadcrumbs-home">
<a href="">Startseite</a>
<span class="breadcrumbSeparator">
›
</span>
</span>
<span id="breadcrumbs-1" dir="ltr">
<span id="breadcrumbs-current">Nachrichten</span>
</span>
</div>
Portlets¶
General Plone elements to copy into theme templates.
Event Portlet¶
<dl class="portlet portletEvents">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a href="events" class="tile">Termine</a>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem odd">
<a href="events/quis-aute-iure-reprehenderit"
class="tile"
title="Duis autem vel eum iriure dolor in.">
Quis aute iure reprehenderit
</a>
<span class="portletItemDetails">
<span>20.03.2012 - 21.03.2012</span>
</span>
</dd>
<dd class="portletItem even">
<a href="events/world-plone-day-2012"
class="tile"
title="Der World Plone Day 2012 findet am 25. April weltweit statt.">
World Plone Day 2012
</a>
<span class="portletItemDetails">
<span>25.04.2012 10:00 - 17:00</span>
<span> — Inqbus GmbH & Co. KG, Karl-Heine-Str. 99, Leipzig</span>
</span>
</dd>
<dd class="portletFooter">
<a href="events" class="tile">Kommende Termine…</a>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
News Portlet¶
<dl class="portlet portletNews">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a href="news" class="tile">Nachrichten</a>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem odd">
<a href="news/lorem-ipsum-sed-do"
class="tile"
title="Lorem ipsum dolor sit amet, consectetur adipisicing elit.">
Lorem ipsum sed do
</a>
<span class="portletItemDetails">19.03.2012</span>
</dd>
<dd class="portletItem even">
<a href="news/lorem-ipsum-dolor-sit-amet"
class="tile"
title="Lorem ipsum dolor sit amet.">
Lorem ipsum dolor sit amet
</a>
<span class="portletItemDetails">19.03.2012</span>
</dd>
<dd class="portletFooter">
<span class="portletBottomLeft"></span>
<a href="news">Weitere Nachrichten…</a>
<span class="portletBottomRight"></span>
</dd>
</dl>
Recent Portlet¶
<dl class="portlet portletRecent">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a href="recently_modified">Aktuelle Änderungen</a>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem odd">
<a href="events/world-plone-day-2012/view"
class="state-published tile"
title="Der World Plone Day 2012 findet am 25. April weltweit statt.">
World Plone Day 2012
<span class="portletItemDetails">19.03.2012</span>
</a>
</dd>
<dd class="portletItem even">
<a href="events/quis-aute-iure-reprehenderit/view"
class="state-published tile"
title="Duis autem vel eum iriure dolor in hendrerit.">
Quis aute iure reprehenderit
<span class="portletItemDetails">19.03.2012</span>
</a>
</dd>
<dd class="portletFooter">
<a href="recently_modified" class="tile">Alle Änderungen…</a>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
RSS Portlet¶
<dl class="portlet portletRss">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a href="http://inqbus-hosting.de" class="tile">Dokumentation - Übersicht</a>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem odd">
<a href="" class="tile">
Plone: Portlets in Diazo Regel filtern
<span class="portletItemDetails">
27.02.2012
</span>
</a>
</dd>
<dd class="portletItem even">
<a href="" class="tile">
Solved: IPMI interface unsuable due to vanished gateway MAC
<span class="portletItemDetails">
23.02.2012
</span>
</a>
</dd>
<dd class="portletFooter">
<a href="http://inqbus-hosting.de">Mehr…</a>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
Collection Portlet¶
<dl class="portlet portletCollection portlet-collection-kollektionsportlet">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a href="news/aggregator">
<span>Kollektionsportlet</span>
</a>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem odd">
<a href="news/lorem-ipsum-sed-do"
class="tile"
title="Lorem ipsum dolor sit amet, consectetur adipisicing elit.">
Lorem ipsum sed do
<span class="portletItemDetails">19.03.2012</span>
</a>
</dd>
<dd class="portletItem even">
<a href="news/lorem-ipsum-dolor-sit-amet"
class="tile"
title="Lorem ipsum dolor sit amet, consectetur adipisicing elit.">
Lorem ipsum dolor sit amet
<span class="portletItemDetails">19.03.2012</span>
</a>
</dd>
<dd class="portletFooter">
<span class="portletBottomLeft"></span>
<span>
<a href="news/aggregator">Weiter…</a>
</span>
<span class="portletBottomRight"></span>
</dd>
</dl>
Calendar Portlet¶
<dl class="portlet portletCalendar">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a href="?month:int=2&year:int=2012&orig_query="
rel="nofollow"
title="Vorheriger Monat"
id="calendar-previous"
class="calendarPrevious">«</a>
März 2012
<a href="?month:int=4&year:int=2012&orig_query="
rel="nofollow"
title="Nächster Monat"
id="calendar-next"
class="calendarNext">»</a>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem">
<table class="ploneCalendar" summary="Kalender">
<caption class="hiddenStructure">März</caption>
<thead>
<tr class="weekdays">
<th scope="col">Mo</th>
<th scope="col">Di</th>
<th scope="col">Mi</th>
<th scope="col">Do</th>
<th scope="col">Fr</th>
<th scope="col">Sa</th>
<th scope="col">So</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
<td>9</td>
<td>10</td>
<td>11</td>
</tr>
<tr>
<td>12</td>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
<td>17</td>
<td>18</td>
</tr>
<tr>
<td class="todaynoevent"><strong>19</strong></td>
<td>20</td>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
<td>25</td>
</tr>
<tr>
<td>26</td>
<td>27</td>
<td>28</td>
<td>29</td>
<td>30</td>
<td>31</td>
<td></td>
</tr>
</tbody>
</table>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
Login Portlet¶
<div class="portletWrapper">
<dl class="portlet portletLogin">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a class="tile" href="">Log in</a>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem odd">
<form method="post" id="loginform" action="">
<div>
<input type="hidden" value="1" name="form.submitted">
<input type="hidden" value="" name="came_from">
<input type="hidden" value="0" id="js_enabled" name="js_enabled">
<input type="hidden" value="" id="cookies_enabled" name="cookies_enabled">
<input type="hidden" value="" id="login_name" name="login_name">
<input type="hidden" value="0" id="pwd_empty" name="pwd_empty">
</div>
<div class="field">
<label for="__ac_name">Login Name</label><br>
<input type="text"
id="__ac_name"
value=""
name="__ac_name"
alt="Login Name"
size="10">
</div>
<div class="field">
<label for="__ac_password">Password</label><br>
<input type="password"
id="__ac_password"
name="__ac_password"
alt="Password"
size="10">
</div>
<div style="display:none" class="cookiesMessage portalMessage">
Cookies are not enabled. You must enable cookies before you can log in.
</div>
<div class="formControls">
<input type="submit" alt="Log in" value="Log in" name="submit" class="context">
</div>
</form>
</dd>
<dd class="portletItem even">
<a class="tile" href=""><img width="16" height="16" title="" alt="" src="images/info_icon.gif">Forgot your password?</a>
</dd>
</dl>
</div>
Static Text Portlet¶
<dl class="portlet portletStaticText portlet-static-lorem-ipsum-dolor-sit-amet">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<span>
Lorem ipsum dolor sit amet
</span>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem odd">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat.
</p>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
Search Portlet¶
<dl class="portlet portletSearch">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<a class="tile" href="@@search">Suche</a>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem">
<form id="livesearch1"
action="@@search">
<div class="LSBox">
<input class="searchField portlet-search-gadget"
name="SearchableText"
type="text"
size="15"
title="Website durchsuchen"
placeholder="Website durchsuchen"
autocomplete="off">
<input class="searchButton" type="submit" value="Suche">
<div class="LSResult" style="">
<div class="LSShadow"></div>
</div>
</div>
</form>
<div class="visualClear"><!-- --></div>
</dd>
<dd class="portletFooter">
<a href="@@search" class="tile">Erweiterte Suche…</a>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
Newsletter Portlet¶
Portlet from Products.EasyNewsletter extension.
<dl class="portlet portletNewsletterSubscriber">
<dt class="portletHeader">
<span class="portletTopLeft"></span>
<span>Newsletter</span>
<span class="portletTopRight"></span>
</dt>
<dd class="portletItem lastItem">
<form action="@@register-subscriber">
<input type="hidden"
name="newsletter"
value="/newsletter">
<select class="easynewsletter_text"
id="salutation"
name="salutation">
<option value="">Anrede wählen...</option>
<option value="ms">Frau</option>
<option value="mr">Herr</option>
</select>
<input class="easynewsletter_text"
onclick="this.value=''"
name="fullname"
value="Vorname Nachname">
<input class="easynewsletter_text"
onclick="this.value=''"
name="subscriber"
value="Ihre E-Mail">
<input class="standalone easynewsletter_button"
type="submit"
value="Abonnieren">
</form>
<span class="portletBottomLeft"></span>
<span class="portletBottomRight"></span>
</dd>
</dl>
Content¶
Plone content elements to copy into theme templates.
Folder¶
Document¶
<div id="content">
<div id="viewlet-above-content-title"></div>
<h1 id="parent-fieldname-title"
class="documentFirstHeading">
Lorem ipsum dolor sit amet
</h1>
<div id="viewlet-below-content-title">
<div class="documentByLine" id="plone-document-byline">
<span class="documentAuthor">
erstellt von <a
href="http://127.0.0.1:8001/example.com/author/admin">admin</a>
—
</span>
<span class="documentModified">
<span>zuletzt verändert:</span>
21.03.2012 15:44
</span>
<span class="contentHistory" id="content-history">
—
<a href="http://127.0.0.1:8001/example.com/front-page/@@historyview"
rel="#pb_3"
class="link-overlay"
style="cursor: pointer; ">Historie</a>
</span>
</div>
</div>
<div id="parent-fieldname-description"
class="documentDescription">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis,
</div>
<div id="viewlet-above-content-body"></div>
<div id="content-core">
<div>
<p>Stet clita kasd gubergren, no sea takimata sanctus est. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
<div id="viewlet-below-content-body">
<div class="visualClear"><!-- --></div>
<div class="documentActions">
</div>
</div>
</div>
Image¶
News Item¶
Event¶
Collection¶
Diazo Rules Snippets¶
Diazo rules snippets to merge Plone content with Theme content.
Rules for Plone¶
Diazo rules for Plone.
Base Rules¶
<?xml version="1.0" encoding="UTF-8"?>
<rules
xmlns="http://namespaces.plone.org/diazo"
xmlns:css="http://namespaces.plone.org/diazo/css"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- theme wrapper, to prevent theming ZMI -->
<rules css:if-content="#visual-portal-wrapper">
<!-- define Theme template for front-page -->
<theme href="index.html" css:if-content="body.section-front-page" />
<!-- define Theme template for other pages -->
<theme href="article.html" />
<!-- prevent theming if $ajax_load is true -->
<notheme if="$ajax_load" />
<!-- prevent theming manage-portlets view -->
<notheme css:if-content="body.template-manage-portlets" />
<!-- prevent theming usergroup-userprefs view -->
<notheme css:if-content="body.template-usergroup-userprefs" />
<!-- drop stuff from Template, which we readd below from Plone
<drop theme="/html/head/meta" />
<drop theme="/html/head/title" />
<drop theme="/html/head/base" />
<drop theme="/html/head/comment()" />
<after
content="/html/head/meta"
theme-children="/html/head" />
<!-- include plone javascript files -->
<before
content="/html/head/script"
theme-children="/html/head" />
<after
content="/html/head/base | /html/head/comment()"
theme-children="/html/head"
/>
<!-- include plone kss files, but not css -->
<after
content="/html/head/link[@type='text/kss']"
theme-children="/html/head"
/>
<!-- copy id and dir attribute from Plone into Theme -->
<copy
attributes="id dir"
css:content="body"
css:theme="body"
/>
<!-- merge css classes from Plone into Theme -->
<merge
attributes="class"
css:content="body"
css:theme="body"
/>
<!-- copy Plone logo href into Theme -->
<copy
attributes="href"
css:content='#portal-logo'
css:theme="#portal-logo"
/>
<!-- Personal tools -->
<replace
css:content="#portal-personaltools"
css:theme="#portal-personaltools"
/>
<!-- copy Plone site actions into Theme-->
<replace
css:content="#portal-siteactions li"
css:theme-children="#portal-siteactions"
/>
</rules>
</rules>
Diazo Recipes¶
Diazo and XSL recipes for special usecases.
Add attributes on the fly¶
The example add target=”_blank” to all links in a portlet with the class portlet-collection-links.
<?xml version="1.0" encoding="UTF-8"?>
<rules
xmlns="http://namespaces.plone.org/diazo"
xmlns:css="http://namespaces.plone.org/diazo/css"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- add target="_blank" to all links in portlet-collection-links -->
<xsl:template match="//dl[contains(@class,'portlet-collection-links')]//a">
<a target="_blank"><xsl:apply-templates select="./@*[contains(' href title class rel ', concat(' ', name(), ' '))]"/><xsl:value-of select="." /></a>
</xsl:template>
<!-- theme wrapper, to prevent theming ZMI -->
<rules css:if-content="#visual-portal-wrapper">
[...]
</rules>
</rules>
This should also work, but does not if the selected node has already child notes.
<xsl:template match="//dl[contains(@class,'portlet-collection-links')]//a">
<xsl:attribute name="target">_blank</xsl:attribute><xsl:copy-of select="." />
</xsl:template>
Then you become the follwing error:
XSLTApplyError: xsl:attribute: Cannot add attributes to an element if children have been already added to the element.
At diazo.org is another way described in the recipes: http://docs.diazo.org/en/latest/recipes/adding-an-attribute/index.html
<?xml version="1.0" encoding="UTF-8"?>
<rules xmlns="http://namespaces.plone.org/diazo"
xmlns:css="http://namespaces.plone.org/diazo/css"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<replace css:theme="#target" css:content="#content" />
<xsl:template match="a">
<xsl:copy>
<xsl:attribute name="target">_blank</xsl:attribute>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</rules>
Add CSS class depending on existing portal-columns¶
This adds a css class for every existing portal-column to the body tag. If portal-column-one exist we add col-one, if portal-column-content exsists we add col-content and if portal-column-two exists we add col-two.
<before theme-children="/html/body" method="raw">
<xsl:attribute name="class"><xsl:value-of select="/html/body/@class" /><xsl:if css:test="#portal-column-one"> col-one</xsl:if><xsl:if css:test="#portal-column-content"> col-content</xsl:if><xsl:if css:test="#portal-column-two"> col-two</xsl:if></xsl:attribute>
</before>
This can be used to change the grid layout like this¶
The following example shows the scss for compass, which define different grid columns depending on the body classes.
body.col-one.col-content.col-two #content-wrapper {
@include container;
#portal-column-content {
@include column(12);
@include prepend(4.5);
}
#portal-column-one {
@include column(4.5);
@include pull(16.5);
}
#portal-column-two {
@include column(4.5, true);
}
}
body.col-one.col-content #content-wrapper {
@include container;
#portal-column-content {
@include column(16.5, true);
@include prepend(4.5);
}
#portal-column-one {
@include column(4.5);
@include pull(21, true);
}
}
Move plone elements around¶
Sometimes one need to move Plone elements from one place to another or merge some elements together. In the following example we merge the language flags together with the document actions.
<replace css:content-children=".documentActions > ul">
<xsl:for-each select="//*[@class='documentActions']/ul/li">
<xsl:copy-of select="." />
</xsl:for-each>
<xsl:for-each select="//*[@id='portal-languageselector']/*">
<xsl:copy-of select="." />
</xsl:for-each>
</replace>
Remove the value of the searchButton¶
Sometimes it is usefull to remove the value (text) of the search button, for example if you whant an image only search button. The following XSL code replace the value of searchButton with an empty string.
<xsl:template match="//div[@id='portal-searchbox']//input[@class='searchButton']/@value">
<xsl:attribute name="value"></xsl:attribute>
</xsl:template>
This special case can also be solved with pure CSS like so:
.searchButton{
text-indent: -10000px;
}
Plone integration with plone.app.theming¶
Configurating and using Plone’s Diazo integration with plone.app.theming.
Using manifest.cfg for metadata¶
You can use the manifest.cfg to define the name and description of the theme and much more useful, you can define parameters to use in Diazo rules.
[theme]
title="Plone Theme: MyTheme"
description = "Diazo based Plone Theme"
doctype = <!Doctype html>
[theme:parameters]
language = portal_state/language
ajax_load = python: 'ajax_load' in request.form
anonymous = portal_state/anonymous
Then you can use this parameters in Diazo rules like this:
<notheme if="$ajax_load" />
Disabling the theme for a particular view, script or template¶
Some times you don’t want Diazo in the middle of your request/response. For example if you call some view over ajax and it must return just a string, Diazo break’s your string, because it converts a string to some thing like this:
<!Doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"><body><p>True</p></body></html>
And this may break your application.
To get sure that Diazo let your response alone, you have to set the X-Theme-Disabled header:
response.setHeader('X-Theme-Disabled', 'True')
or directly from a template:
tal:define="dummy python:request.response.setHeader('X-Theme-Disabled', 'True')"
Read it on Read the Docs¶
This docs are available on https://plone-theming-with-diazo.readthedocs.org/en/latest/
Source on Bitbucket¶
The source is on bitbucket: https://bitbucket.org/inqbus/plone-theming-with-diazo/ contributions are welcome ;).