<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Zenphoto - simpler web gallery management</title>
	<atom:link href="http://www.zenphoto.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zenphoto.org</link>
	<description>Blog for news about Zenphoto and its development.</description>
	<lastBuildDate>Thu, 02 Sep 2010 10:29:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>no_show</title>
		<link>http://www.zenphoto.org/2010/09/no_show/</link>
		<comments>http://www.zenphoto.org/2010/09/no_show/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 10:09:36 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Theme plugins]]></category>
		<category><![CDATA[Unsupported]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[Theme]]></category>
		<category><![CDATA[user]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1831</guid>
		<description><![CDATA[Developed by Stephen Billard (sbillard)
Totally hides unpublished images from not signed in viewers.
Requires Zenphoto v1.3.1.1 or later
Download
]]></description>
			<content:encoded><![CDATA[<p>Developed by Stephen Billard (sbillard)</p>
<p>Totally hides unpublished images from not signed in viewers.</p>
<p>Requires Zenphoto v1.3.1.1 or later</p>
<p class="buttons"><a title="http://www.zenphoto.org/trac/attachment/wiki/ZenphotoPlugins/no_show.php.zip" href="http://www.zenphoto.org/trac/attachment/wiki/ZenphotoPlugins/no_show.php.zip">Download</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/09/no_show/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zenphoto 1.3.1.1</title>
		<link>http://www.zenphoto.org/2010/08/zenphoto-1-3-1-1/</link>
		<comments>http://www.zenphoto.org/2010/08/zenphoto-1-3-1-1/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 19:45:40 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Release]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1827</guid>
		<description><![CDATA[This is a bugfix release for Zenphoto 1.3.1. The full list of changes can be viewed in the Trac log.
As always you can download it on our download page.
]]></description>
			<content:encoded><![CDATA[<p>This is a bugfix release for <a title="http://www.zenphoto.org/2010/08/zenphoto-1-3-1" href="http://www.zenphoto.org/2010/08/zenphoto-1-3-1">Zenphoto 1.3.1.</a> The <a title="http://www.zenphoto.org/trac/browser/trunk" href="http://www.zenphoto.org/trac/browser/trunk">full list of changes</a> can be viewed in the Trac log.</p>
<p>As always you can download it on our <a title="http://www.zenphoto.org/" href="http://www.zenphoto.org/">download page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/zenphoto-1-3-1-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>class-pdf</title>
		<link>http://www.zenphoto.org/2010/08/class-pdf/</link>
		<comments>http://www.zenphoto.org/2010/08/class-pdf/#comments</comments>
		<pubDate>Sat, 28 Aug 2010 18:08:21 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Theme plugins]]></category>
		<category><![CDATA[Unsupported]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[pdf]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1824</guid>
		<description><![CDATA[Developed by Draekko based on the class video plugin
A plugin to list PDF files with an default image within the gallery. Display of the files is handled by the browser/system itself.
More info and download
]]></description>
			<content:encoded><![CDATA[<p>Developed by <a title="http://draekko.org" href="http://draekko.org">Draekko</a> based on the class video plugin<a title="http://draekko.org" href="http://draekko.org"></a></p>
<p>A plugin to list PDF files with an default image within the gallery. Display of the files is handled by the browser/system itself.</p>
<p class="buttons"><a title="http://draekko.org/?e=59" href="http://draekko.org/?e=59">More info and download</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/class-pdf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3rd party plugins: Zenphoto gallery (for Wordpress) / Google Analytics 2.0 / Dokuwiki-Zenphoto</title>
		<link>http://www.zenphoto.org/2010/08/3rd-party-plugins-zenphoto-gallery-google-analytics-2-0-dokuwiki-zenphoto/</link>
		<comments>http://www.zenphoto.org/2010/08/3rd-party-plugins-zenphoto-gallery-google-analytics-2-0-dokuwiki-zenphoto/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 08:56:55 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Third party]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1797</guid>
		<description><![CDATA[New plugins and tools from the net:

Zenphoto Gallery by akerbos: A Wordpress plugin that allows to use Zenphoto albums in WordPress posts. More info and download
Dokuwiki-Zenphoto by falstaff84: A Dokuwiki plug in which synchronizes the Dokuwiki user database with Zenphoto&#8217;s user database. More info and download
Google analytics plugin 2.0 update by j916: More information and [...]]]></description>
			<content:encoded><![CDATA[<p>New plugins and tools from the net:</p>
<ul>
<li><strong>Zenphoto Gallery</strong> by akerbos: A Wordpress plugin that allows to use <em>Zenphoto</em> albums in <em>WordPress</em> posts. <a title="wordpress.org/extend/plugins/zenphoto-gallery/" href="http://wordpress.org/extend/plugins/zenphoto-gallery/">More info and download</a></li>
<li><strong>Dokuwiki-Zenphoto</strong> by <a title="http://blog.falstaff.ch/" href="http://blog.falstaff.ch/">falstaff84: </a>A <a title="http://www.dokuwiki.org/" href="http://www.dokuwiki.org/">Dokuwiki</a> plug in which synchronizes the Dokuwiki user database with Zenphoto&#8217;s user database. <a title="http://github.com/falstaff84/dokuwiki-zenphoto" href="http://github.com/falstaff84/dokuwiki-zenphoto">More info and download</a></li>
<li><strong>Google analytics plugin</strong> 2.0 update by <a title="http://www.moto-treks.com/Software/google-analytics-for-zenphoto.html" href="http://www.moto-treks.com/Software/google-analytics-for-zenphoto.html">j916: More information and download</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/3rd-party-plugins-zenphoto-gallery-google-analytics-2-0-dokuwiki-zenphoto/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Dokuwiki-zenphoto</title>
		<link>http://www.zenphoto.org/2010/08/dokuwiki-zenphoto/</link>
		<comments>http://www.zenphoto.org/2010/08/dokuwiki-zenphoto/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 09:27:45 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Addons & Utilities]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[Unsupported]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[dokuwiki]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[synchronize]]></category>
		<category><![CDATA[user]]></category>
		<category><![CDATA[users]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1810</guid>
		<description><![CDATA[Developed by falstaff84
A Dokuwiki plug in which synchronizes the Dokuwiki user database with Zenphoto&#8217;s user database.
More info and download
]]></description>
			<content:encoded><![CDATA[<p>Developed by <a title="http://blog.falstaff.ch/" href="http://blog.falstaff.ch/">falstaff84</a></p>
<p>A <a title="http://www.dokuwiki.org/" href="http://www.dokuwiki.org/">Dokuwiki</a> plug in which synchronizes the Dokuwiki user database with Zenphoto&#8217;s user database.</p>
<p class="buttons"><a title="http://github.com/falstaff84/dokuwiki-zenphoto" href="http://github.com/falstaff84/dokuwiki-zenphoto">More info and download</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/dokuwiki-zenphoto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zenphoto Plugin Architecture</title>
		<link>http://www.zenphoto.org/2010/08/zenphoto-plugin-architecture/</link>
		<comments>http://www.zenphoto.org/2010/08/zenphoto-plugin-architecture/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 06:00:58 +0000</pubDate>
		<dc:creator>sbillard</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[User Guide]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/2008/04/zenphoto-plugin-architecture/</guid>
		<description><![CDATA[
Categories of plugins

Template plugins
Admin utilities
Core plugins


Filters
Plugin options
Separate plugin translations

As from the 1.2 release Zenphoto contains an implementation of &#8220;plugins&#8221; so that the functionality of the product can be extended without &#8220;bloating&#8221; the core code. Only users of the plugin will require the resources it uses. This article describes the architecture of Zenphoto plugins. Plugins may come [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li><a href="#categories-of-plugins">Categories of plugins</a>
<ul>
<li><a href="#template-plugins">Template plugins</a></li>
<li><a href="#admin-utilities">Admin utilities</a></li>
<li><a href="#core-plugins">Core plugins</a></li>
</ul>
</li>
<li><a href="#filters">Filters</a></li>
<li><a href="#plugin-options">Plugin options</a></li>
<li><a href="#plugin-translation">Separate plugin translations</a></li>
</ol>
<p>As from the 1.2 release Zenphoto contains an implementation of &#8220;plugins&#8221; so that the functionality of the product can be extended without &#8220;bloating&#8221; the core code. Only users of the plugin will require the resources it uses. This article describes the architecture of Zenphoto plugins. Plugins may come with the Zenphoto distribution or may be available for download from third party developers.</p>
<p>We have provided some <a title="Example plugins" href="http://http://www.zenphoto.org/category/extensions/example-plugins/">example plugins</a> to help with your understanding. Note that these plugins are not formally supported by the Zenphoto team.</p>
<h4><a name="categories-of-plugins"></a>Categories of plugins</h4>
<p>There are three categories of plugins implemented in Zenphoto. The categorys you most likely will experience is plugins that extend the functionality of Themes. These are <em>Template Plugins</em> and <em>Filters</em>.</p>
<ol>
<li><em>Template Plugins</em> add optional functions to the repertoire of capabilities available to Theme designers. Examples of this category of plugin are: <tt>Google Maps</tt> which adds the facility of printing maps based on GPS data from the image EXIF, <tt>Rating</tt> which provides an image rating system, and <tt>shutterfly</tt> which enables viewers to print a copy of an image using the Shutterfly WEB service. Zenphoto plugins reside in the <tt>zp-core/zp-extensions</tt> folder of the Zenphoto installation. Third party plugins should be placed in the root<tt> plugins</tt> folder.</li>
<li><em>Core plugins </em>are the  third category of plugin and are used to provide alternative implementations of Zenphoto core functions. Examples of these plugins are: The spamfilter set and the theme options implementation. These plugins let Zenphoto developers provide choices for how the particular feature is handled. The folder residence is the same as for <em>Template Plugins</em>.</li>
<li><em>Admin utilities</em> are backend plugins that appear as a button on the overview tab&#8217;s utilities section. There are several plugins included in the release that you might look at as examples. They resides in <tt>zp-core/utilities</tt>.<br />
These plugins do not add anything to the core itself, although template or core plugins can add utility buttons. An example is the <tt>sitemap-extended</tt> plugin (Zenphoto 1.3).</li>
</ol>
<p><em>Plugins</em> are PHP scripts that consist of two sections. There is a section that provides the &#8220;glue&#8221; between the plugin and the Zenphoto core. Then there is the section that implements the functionality provided by the plugin. The plugin consists of at least a PHP file residing in the <tt>zp-core/zp-extensions</tt> folder. It may optionally use a folder of its same name, also in the <tt>zp-core/extensions</tt> folder.</p>
<h5><a name="template-plugins"></a>Template plugins</h5>
<p>The &#8220;glue&#8221; section is the interface to Zenphoto. In it are several (possibly optional) statements to initialize variables or register scripts pertaining to the plugin.</p>
<ul>
<li><tt>$plugin_description</tt> should be set to the text you wish displayed on the admin plugins tab description of the plugin.</li>
<li><tt>$plugin_author</tt> is the author of the plugin. This is also displayed on the plugins tab.</li>
<li><tt>$plugin_version</tt> is the version of the plugin.</li>
<li><tt>$plugin_URL</tt> is an URL to the usage documentation for the plugin. For plugins distributed with Zenphoto this is an URL to the PHP documentation page of the plugin on zenphoto.org.</li>
<li><tt>$plugin_disable</tt> controls setting the checkbox to enable the plugin. If the plugin cannot run, set this to the &#8220;reason&#8221; and <em>admin</em> will display the &#8220;reason&#8221; and will not enable the plugin. The variable should not be present or be set to empty the plugin may be enabled.</li>
<li><tt>$plugin_is_filter</tt> [1.2.5] flags this plugin as a <em>filter</em> type plugin and sets it load priority. The filters will be loaded in decending priority order. Normal front-end plugins should set this variable to 1. They will be loaded by index.php after the<em> front-end</em> environment has been established. Values greater than 1 will cause the plugin to load with the class libraries. These will be available to the <em>admin</em> scipts as well as to the front-end, but will load before the front-end environment is established. Values less than zero will load normally on the <em>front-end</em> but will also be available to the admin scripts.[1.2.6] The absolute value of value will be used for the load prioirity.[1.2.7]</li>
<li><tt>$option_interface</tt> If your plugin supports options, this variable should set to an instance of the option handler class for the plugin. (See <a href="#pluginoptions">Plugin Options</a> below.)</li>
<li><tt>Theme interfaces: </tt>There are three &#8220;standard interface points&#8221; where your plugin can insert HTML into a plugin script. You use the zp_retister_filter() function to define what you wish to handle of these insertion points. (see below for how filters work.) The points of insertion are in the <em>head</em> of the script, just after the start of the <em>body</em> and just before then end of the <em>body</em> of the script. Register a filter for &#8216;theme_head&#8217; for the first and one for &#8216;theme_body_open&#8217; and &#8216;theme_body_close&#8221; for the latter two. For instance you can emit HTML to load CSS files in the head with &#8216;theme_head&#8217; or to insert javaScript using any of these filters.</li>
</ul>
<p>The implementation section contains any initialization code needed by the plugin and all the <em>function</em> statements that are to be provided to the Theme designer.</p>
<h5><a name="admin-utilties"></a>Admin utilities</h5>
<p>These plugins are a little different and require this basic setup in the beginning of the page:</p>
<ul>
<li>This sets up the right path for admin use:
<pre>define('OFFSET_PATH', 3);
chdir(dirname(dirname(__FILE__)));</pre>
</li>
<li>Include the necessary admin standard functions.
<pre>require_once(dirname(dirname(__FILE__)).'/admin-functions.php');
require_once(dirname(dirname(__FILE__)).'/admin-globals.php');</pre>
<p>You can of course also call other plugins if you need or create your own utility custom functions.</li>
<li>Setting up the button display:
<pre>$button_text = gettext('Title of the utility button');
$button_hint = gettext('A description of the utiltiy that appears on hovering the button.');
$button_icon = '&lt;option path to a button icon&gt;';
$button_rights = &lt;User rights to limit access to the utility&gt;;</pre>
<p>The other plugin types can also add a button by using a filter (see <a title="http://www.zenphoto.org/2010/04/zenphoto-plugin-architecture/#filters" href="http://www.zenphoto.org/2010/04/zenphoto-plugin-architecture/#filters">below</a>).</li>
<li>Setting up the gallery object and the webpath:
<pre>$gallery = new Gallery();
$webpath = WEBPATH.'/'.ZENFOLDER.'/';</pre>
</li>
</ul>
<p>Additionally admin utilities require a standard html setup to fit in the backend nicely:</p>
<pre>printAdminHeader();
?&gt;
&lt;!-- The opening of the &lt;html&gt; and &lt;head&gt; is printed by printAdminHeader() so you can add further stuff to the head here --&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php printLogoAndLinks(); ?&gt;
&lt;div id="main"&gt;
&lt;?php printTabs('home'); ?&gt;
&lt;div id="content"&gt;
&lt;h1&gt;&lt;?php echo (gettext('&lt;Name of your utility&gt;')); ?&gt;&lt;/h1&gt;
&lt;!--  Here you can do whatever your utility should do --&gt;
&lt;/div&gt;&lt;!-- content --&gt;
&lt;/div&gt;&lt;!-- main --&gt;
&lt;?php printAdminFooter(); ?&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<h5><a name="core-plugins"></a>Core plugins</h5>
<p>Zenphoto core plugins are extensions to the Zenphoto core. They may extend Zenphoto classes or provide new &#8220;back-end&#8221; capabilities. The current Zenphoto implementation makes use of three classes: <em>class objects</em>, <em>spamfilters</em> and <em>themeoptions</em>. These classes support an options interface (see <a href="#pluginoptions">below</a>.)</p>
<ol>
<li><em>Themeoption</em> plugins support only the options interface. This allows theme designers to have optional implementations and the gallery administrator to choose the appropriate values for these options. Themes are not required to support options and therefore the themeoptions plugin is optional.</li>
<li><em>Spam filter</em> plugins provide a <tt>filtermessage()</tt> function to examine a posting and determine if it is <em>Spam</em> or not.
<ul>
<li><strong><tt>filterMessage($author, $email, $website, $body, $imageLink)</tt></strong></li>
<li><tt>$author</tt> is the author field of the comment</li>
<li><tt>$email</tt> is the email field of the comment</li>
<li><tt>$website</tt> is the website field of the comment</li>
<li><tt>$body</tt> is the comment text</li>
<li><tt>$imageLink</tt> is the url to the full image</li>
</ul>
<p>This function is called to process comment postings. It may pass the comment (return value: 2), reject it (return value: 0), or mark it for moderation (return value: 1). The gallery administrator selects the filter appropriate for his needs from the ones found in the <tt>plugins/spamfilters</tt> folder.</li>
<li><em>Class objects</em> extend Zenphoto class capabilities. Currently the only class objects are for extending the &#8220;image&#8221; capabilities of Zenphoto. <tt>class_video.php</tt> provides support for video files and the example <tt>class_textobject.php</tt> is an example of how a new file type might be supported in Zenphoto by use of a class object plugin.</li>
</ol>
<h4><a name="filters"></a>Filters</h4>
<p><em>Filters</em> modify the behavior of existing Zenphoto functions and can be used by any of the plugin types. Examples of this kind of filter are found in the scripts <tt>filter_zenphoto_seo.php</tt> and <tt>filter_admin_toolbox.php</tt>.  Filters are applied to the output of other functions and may make modifications to that output. So, for instance, <tt>filter_zenphoto_seo</tt> has a filter for the <tt>seoFriendlyURL</tt> function that changes accented characters into non accented equivalents.</p>
<p>Filters are added to a function (which has filtering support) by using the function  <tt>zp_register_filter function($hook, $function_name, $priority, $accepted_args)</tt>).  <em>$hook</em> is the name of the filter item, <em>$function_name</em> is the function that will be invoked to filter the item, <em>$priority</em> is the rank of this filter among the list of filters for this item (defaults to 5), and <em>$accepted_args</em> is how many parmeters the filter requires (defaults to the number of parameters supplied). Filters are applied in ascending <em>$priority</em> order.</p>
<p>The registered function will be passed the parameters(with the exception of the<em> filter name string</em>) from the zp_apply_filter()  call. The function must always return the initial parameter of the list (if it exists) as this is then passed on to subsequent filters in the chain. This provides a means of filters operating on the changes made by other filters.</p>
<p>Zenphoto currently provides filter invocation for the following. Function parameters are indicated within the parens:</p>
<ul>
<li><tt>new_image</tt> ($image_object)<br />
Invoked just after Zenphoto saves a newly discovers image to the database.</li>
<li><tt>image_instantiate</tt> ($image_object) [1.2.9]<br />
Invoked when an image object is instantiated.</li>
<li>image_refresh</li>
<li><tt>new_album </tt>($album_object)<br />
Invoked whenever Zenphoto saves a newly discovered album to the database.</li>
<li><tt>album_instantiate </tt>($album_object) [1.2.9]<br />
Invoked when an album object is instantiated.</li>
<li>album_refresh</li>
<li><tt>new_page</tt> ($page_object) [1.2.5]<br />
Invoked when Zenpage saves a newly created page.</li>
<li><tt>new_article </tt>($news_object) [1.2.5]<br />
Invoked when Zenpage saves a newly created news article.</li>
<li><tt>seoFriendlyURL </tt>($string)<br />
Invoked wherever Zenphoto thinks that URL string text should be processed for non-seo friendly characters. The function return value is used as the new value of the string text.</li>
<li><tt>album_filter</tt> ($files[])<br />
Invoked when Zenphoto checks for albums (folders) for the gallery or a subalbum. The parameter is an array of filenames discovered. The return value of the function is the edited list of filenames.</li>
<li><tt>image_filter</tt> ($files[])<br />
Similar to <tt>album_filter</tt>, but for when Zenphoto checks an album for images. The return value is the updated image name list.</li>
<li><tt>admin_login_attempt</tt>($success, $user, $password)[1.2.6]<br />
Invoked whenever an attempt is made to log in as an administrator. Success is<em> </em>the <em>rights</em> of the user  if the login was successful. $user and $password are the credentials presented for the login.</li>
<li><tt>guest_login_attempt</tt>($success, $user, $password, $athority)[1.2.6]<br />
Invoked whenever an attempt is made to log in as a guest user. Success is <em>true </em>if the login was successful. $user and $password are the credentials presented for the login. $athority is the kind of login, e.g. <em>gallery</em>, <em>album</em>, etc.</li>
<li><tt>check_album_credentials</tt>($success)[1.2.9]<br />
Invoked when checking if a viewer is permitted to access an album. It should return <em>true</em> if access is allowed. If it returns true, no further checking is performed.</li>
<li><tt>check_news_credentials</tt>($success)[1.3.0]<br />
Invoked when checking if a viewer is permitted to access a Zenpage news article or category. It should return <em>true</em> if access is allowed. If it returns true, no further checking is performed.</li>
<li><tt>check_pages_credentials</tt>($success)[1.3.0]<br />
Invoked when checking if a viewer is permitted to access a Zenpage page. It should return <em>true</em> if access is allowed. If it returns true, no further checking is performed.</li>
<li><tt>admin_toolbox_<em>&lt;position&gt;</em></tt> [updated for 1.2.5]<br />
These filters allow additions to the <em>Admin Toolbox</em> links. <em>&lt;position&gt;</em> indicates where in the link list they will be placed. The positions are :</li>
<li>
<ul>
<li><tt>global</tt>:  on all instances of the links</li>
<li><tt>gallery</tt>:   on a gallery page</li>
<li><tt>album($albumname)</tt>:  on an album page</li>
<li><tt>image($albumname, $imagename)</tt>:  on an image page</li>
<li><tt>search</tt>:  on a search page</li>
<li><tt>news</tt>:  on a zenpage article page</li>
<li><tt>page</tt>:  on a zenpage page</li>
</ul>
<p>The filter should output the HTML for the link it desires to place in the <em>Admin Toolbox</em>.</li>
<li><tt>album<em>_&lt;album database field&gt;</em></tt> ($text, $object, $context, $field) [1.2.4]</li>
<li><tt>image<em>_&lt;image database field&gt;</em></tt> ($text, $object, $context, $field) [1.2.4]<br />
These filters are invoked by the various editable print functions. <tt>$text</tt> is the content that would be printed if there were no filter. The actual text printed will be the function return. <tt>$object</tt> is the Zenphoto album or image, <tt>$context</tt> will be  &#8217;album&#8217;, or &#8216;image&#8217;, <tt>$field</tt> is the <em>&lt;database field&gt;</em> name.</li>
<li><tt>comment_post</tt> ($commentobject, $ownerobject)<br />
This filter is called just before a newly posted comment is saved to the database. <tt>$commentobject</tt> is the comment and <tt>$ownerobject</tt> is the item (image, album, etc.) to which the object is posted.</li>
<li><tt>comment_approve(</tt>$commentobject)<br />
This filter is called when a SPAM comment is marked as approved (no longer SPAM) by the administrator.</li>
<li><tt>comment_disapprove(</tt>$commentobject) [1.2.7]<br />
This filter is called when a normal comment is marked as SPAM by the administrator.</li>
<li><tt>edit_album_utilities</tt> ($html, $album, $prefix) [1.2.5]<br />
Used to insert items in the &#8220;Utilities&#8221; acton box on the admin album edit tab.</li>
<li><tt>save_album_utilities_data</tt> ($html, $album, $prefix) [1.2.5]<br />
Used to process the POST of <span style="font-family: Courier New;">edit_album_utilities </span>actions.</li>
<li><span style="font-family: Georgia;">admin_tabs</span>($tabs, $current) [1.2.6]<br />
Used to insert (or delete)  tabs for Admin pages.</li>
<li><span style="font-family: Georgia;">admin_alterrights</span>($alterrights, $userobj) [1.2.6]<br />
Used to override disabling of admin rights and managed album user edit sections.</li>
<li><tt>edit_image_utilities</tt> ($html, $imag, $prefix, $subpage, $tagsort) [1.2.5]<br />
Used to insert items in the &#8220;Utilities&#8221; action box of the admin image edit tab.<em><tt></tt></em></li>
<li><em><tt>save_image_utilities_data</tt> ($html, $image, $prefix, $page, $sort)</em> [1.2.5]<br />
Used to process the POST of <span style="font-family: Courier New;">edit_image_utilities </span>actions.</li>
<li><em>custom data handling filters</em> (data, userobject, index)[1.2.5]<br />
These filters (listed below) are called to process editing and saving of the <tt>custom_data</tt> of images, albums, or comments. The <em>edit</em> variant allows you to format the data on the Admin edit pages. The <em>save</em> variant lets you process the information presented by the <em>edit</em> variant.The filters are:</p>
<ul>
<li><tt>save_image_custom_data</tt></li>
<li><tt>edit_image_custom_data</tt></li>
<li><tt>save_album_custom_data</tt></li>
<li><tt></tt><tt>edit_album_custom_data</tt></li>
<li><tt>save_comment_custom_data</tt></li>
<li><tt>edit_comment_custom_data</tt></li>
<li><tt>save_album_custom_data</tt> [1.2.6]</li>
<li><tt>edit_album_custom_data</tt> [1.2.6]</li>
<li><tt>save_admin_custom_data</tt> [1.2.6]</li>
<li><tt>edit_admin_custom_data</tt> [1.2.6]</li>
<li><tt>save_admin_custom_data</tt> [1.2.7]</li>
<li><tt>edit_admin_custom_data</tt> [1.2.7]</li>
</ul>
</li>
<li><em>register_user filters</em> [1.2.7]<br />
Used to allow extensions to the register_user plugin</p>
<ul>
<li><em>register_user_form ($html)</em><br />
add to the registeration form</li>
<li><em>register_user_register ($userobj)</em><br />
Called when a user registers</li>
<li><em>register_user_verify ($userobj)</em><br />
Called when a user has been verified</li>
</ul>
</li>
<li><em><tt>publish_article_utilities ($html)</tt></em> [1.2.6]<br />
Used to insert items into &#8220;Publish&#8221; action box on the Zenpage article edit tab.</li>
<li><em><tt>publish_page_utilities($html)</tt></em> [1.2.6]<br />
Used to insert items into &#8220;Publish&#8221; action box on the Zenpage pages edit tab.</li>
<li><em><tt>general_zenpage_utilities($html, $zenpage_object)</tt></em> [1.2.6]<br />
Used to insert items into &#8220;General&#8221; action box on the article and pages edit tabs.</li>
<li><em><tt>new_page($message, $pageobject)</tt></em> [1.2.6]<br />
Called just before saving a new Zenpage page.</li>
<li><em><tt>update_page($message, $pageobject, $oldtitlelink)</tt></em> [1.2.6]<br />
Called just before updating an existing Zenpage page.</li>
<li><em><tt>new_article($message, $pageobject)</tt></em> [1.2.6]<br />
Called just before saving a new Zenpage aticle.</li>
<li><em><tt>update_article($message, $pageobject, $oldtitlelink)</tt></em> [1.2.6]<br />
Called just before updating an existing Zenpage page.</li>
<li><em><tt>admin_utilities_buttons($buttons)</tt></em> [1.2.7]<br />
Called just before the Utilities functions buttons are displayed. Use this filter to add buttons to the admin overview page.</li>
<li><em><tt>admin_overview_left($discard)</tt></em> [1.2.9]<br />
Called at the bottom of the left column on the admin overview page.</li>
<li><em><tt>admin_overview_right($discard)</tt></em> [1.2.9]<br />
Called at the bottom of the right column on the admin overview page.</li>
<li><em>setupTheme ($theme)</em> [1.2.7]<br />
Called just after the current theme is determined. Use this filter to redirect to a different theme.</li>
<li><em>album_reefresh ($album_object)</em> [1.2.7]<br />
Invoked just after Zenphoto saves an album object during a metadate refresh.</li>
<li><em>image_refresh  ($image_object)</em> [1.2.5]<br />
Invoked just after Zenphoto saves an image object during a metadate refresh.</li>
<li><em>Image HTML handling filters</em> [1.2.7]<br />
These filters are called passing the <em>img src</em> HTML so that custom processing can be done. <em><tt>reflection_custom_images</tt></em> passes an additional parameter describing if the image is to be considered a <em>thumbnail</em></p>
<ul>
<li><em><tt>reflection_std_images</tt></em></li>
<li><em><tt>reflection_custom_images</tt></em></li>
<li><em><tt>reflection_std_image_thumbs</tt></em></li>
<li><em><tt><em><tt>reflection_std_album_thumbs</tt></em></tt></em></li>
<li><em><tt>reflection_custom_album_thumbs</tt></em></li>
</ul>
</li>
<li><em>check_upload_quota($current_error, $filepath)</em> [1.3.0]</li>
<li><em>get_upload_limit()</em> [1.3.0]</li>
<li><em>get_upload_header_text($default_text)</em> [1.3.0]</li>
<li><em>upload_helper_js($defaultJS)</em> [1.3.0]</li>
<li><em>upload_filetypes($types)</em> [1.3.0]<br />
These filters are used by the admin-upload scripts to implement a file size quota system.</li>
<li><em>load_theme_script($path)</em> [1.3.0]<br />
Called just before a theme page is loaded.</li>
<li><em>isMyItem($no)</em> [1.3.0]</li>
<li><em>checkForGuest($auth)</em> [1.3.0]<br />
These filters are used for password protection of zenphoto items.</li>
<li><em>load_request()</em> [1.3.0]<br />
This filter is called just befor processing a front-end page load</li>
<li><em>comment_form_data($data_and_disable)</em> [1.3.0]<br />
This filter is called prior to populating the comment form. <em>$data_and_disable </em>is a two dimensional array. Element <tt>data</tt> is an array containing the data which will be placed in the form. Element <tt>disabled</tt> is an array used for enabling and disabling of the form fields.</li>
<li><em>admin_managed_album_access($allow,$return)</em> [1.3.1]<br />
Called when access to an album is being denied.</li>
<li><em>admin_XSRF_access($discard,$access)</em> [1.3.1]</li>
<li>Called when a Cross Site Request Forgery has been intercepted.</li>
<li><em>admin_log_actions($file,$action)</em> [1.3.1]<br />
Called when a log has been deleted or reset.</li>
<li>texteditor_config($editorConfig, $mode) [1.3.1]<br />
Called to configure an external editor (e.g. TinyMCE) for use on the admin pages.</li>
<li>log_setup($success,$action,$details)[1.3.1]<br />
called to record setup actions that might be of interest.</li>
<li><em>theme_head</em> [1.3.2]<br />
Themes will invoke this filter just after they emit the &lt;head&gt; HTML tag.</li>
<li>theme_body_open [1.3.2]<br />
Themes will invoke this filter just after the &lt;body&gt; HTML tag.</li>
<li>theme_body_close [1.3.2]<br />
Themes will invoke this filter just before the &lt;/body&gt; HTML tag.</li>
</ul>
<p>You find some example or template filter plugins to build your own here:<br />
<a title="http://www.zenphoto.org/category/extensions/example-plugins/" href="http://www.zenphoto.org/category/extensions/example-plugins/">http://www.zenphoto.org/category/extensions/example-plugins/</a></p>
<h4><a name="plugin-options"></a>Plugin options</h4>
<p>Plugins may choose to have options that modify their behavior. These options are implemented through the options interface object. To support options, the plugin must declare a class which contains at least the following interface functions:</p>
<ul>
<li><tt>getOptionsSupported()</tt></li>
<li><tt>handleOptions()</tt></li>
</ul>
<p>Additionally, the class instantiation function should make calls on <tt>setOptionDefault()</tt> to initialize default values for all the options the plugin uses.</p>
<p><strong><tt>getOptionsSupported ()</tt></strong> is called from admin Options tab. It returns an array of the option names the theme supports.</p>
<p>The array is indexed by the option name. The value for each option is an array of elements for each option. Each element contains the option <tt>key</tt>, <tt>option type</tt>, <tt>multi-lingual</tt> and <tt>texteditor</tt> <em>flags</em>, and <tt>option description</tt>. (the <tt>multi-lingual</tt> flag is used only for options of type <em>text</em>, see bellow.) For the option names to be translatable, the key for the array element should be a &#8220;gettext()&#8221; call with a parameter of the display value of the option name. Also the description should be enclosed in a &#8220;gettext()&#8221; call. An example of an option array element is:<br />
<code><br />
gettext('My Option') =&gt; array('key' =&gt; 'my_option_key', 'type' =&gt; OPTION_TYPE_RADIO<br />
'buttons' =&gt; array(gettext(«button text») =&gt; «button value»,...),<br />
'selections' =&gt; array(gettext(«selector text») =&gt; «selector value»,...),<br />
'multilingual' =&gt; 1,<br />
'texteditor' =&gt; 1,<br />
'desc' =&gt; gettext('descripton telling what this options is about.'))<br />
</code><br />
The values for the type are:</p>
<ul>
<li><tt>'type' =&gt; OPTION_TYPE_TEXTBOX</tt> says for admin to use a standard textbox for the option</li>
<li><tt>'type' =&gt; OPTION_TYPE_CHECKBOX</tt> says for admin to use a standard checkbox for the option</li>
<li><tt>'type' =&gt; OPTION_TYPE_CUSTOM</tt> will cause admin to call handleOption() to generate the HTML for the option</li>
<li><tt>'type' =&gt; OPTION_TYPE_TEXTAREA</tt> will cause admin to use a standard textarea for the option (version 1.2.1)</li>
<li><tt>'type' =&gt; OPTION_TYPE_RADIO</tt> will cause admin to use radio buttons for the option (version 1.2.1)</li>
<li><tt>'type' =&gt; OPTION_TYPE_SELECTOR</tt> will cause admin to use a standard selector for the option (version 1.2.1)</li>
<li><tt>'type' =&gt; OPTION_TYPE_CHECKBOX_ARRAY</tt> will produce an array of checkboxeds (version 1.2.3)</li>
<li><tt>'type' =&gt; OPTION_TYPE_CHECKBOX_UL</tt> will produce an unorder  list of checkboxs (version 1.2.3)</li>
<li><tt>'type' =&gt; OPTION_TYPE_COLOR_PICKER</tt> will produce a Color picker (version 1.2.4)</li>
<li><tt>'type' =&gt; OPTION_TYPE_CLEARTEXT </tt>is like OPTION_TYPE_TEXTBOX but the POST processing does not &#8220;cleanse&#8221; the posted value. (version 1.2.7)</li>
</ul>
<p>For <span style="font-family: Courier New;">textarea</span> and for a <tt>textbox</tt> where the <tt>'multilingual'</tt> element in the array has a value of 1 these fields will be presented as <em>multi-lingual</em> input fields. That is, there will be a <tt>textbox/textarea</tt> for each of zenphoto&#8217;s supported languages. (This does assume that the global <tt>multi-lingual </tt>option has been selected.) When this option is displayed in a theme, <tt>get_language_string()</tt> must be used to isolate the appropriate language string for display. <tt>'texteditor'</tt> can be associated with type &#8216;3&#8242; options. If set it will attempt to attach a text editor to the textarea. (This is a version 1.2.2 feature and requires also that a texteditor be configured.) <tt>'buttons'</tt> is the set of radio buttons to display. <tt>'selector'</tt> is the list of options for the selection. <tt>'buttons'</tt> and <tt>'selector'</tt> are required only for type OPTION_TYPE_RADIO and type OPTION_TYPE_SELECTOR options respectively. For types OPTION_TYPE_CHECKBOX_ARRAY and OPTION_TYPE_CHECKBOX_UL <tt>'checkboxes'</tt> is the list of checkboxes.</p>
<p><strong><tt>handleOption($option, $currentValue)</tt></strong> is called when the &#8216;type&#8217; value of an option is &#8216;2&#8242; and must generate the HTML for the option user interface.</p>
<ul>
<li><tt>$option</tt> is the key name of the option being processed</li>
<li><tt>$currentValue</tt> is the &#8220;before&#8221; value of the option</li>
</ul>
<h4><a name="plugin-translation"></a>Separate plugin translations</h4>
<p>If you provide a theme as a third party, it&#8217;s translation is naturally not included with Zenphoto&#8217;s general translation file. But with Zenphoto 1.2 you can have an independent translation file for your plugin. Zenphoto uses gettext for translations. Please visit our<a title="translating tutorial" href="http://www.zenphoto.org/2008/05/translating-tutorial/"> translating tutorial</a> for more detailed information about that.</p>
<p>To set up your plugin for separate gettext translation, you just need to place the following function on top of the plugin file or on each file if you plugin consists of several files:</p>
<p><tt>&lt;?php setPluginDomain("&lt;plugin name&gt;"); ?&gt;</tt></p>
<p>This function tells Zenphoto that this plugin uses it&#8217;s own translation.</p>
<p>If your plugin consists of just one single file &lt;plugin name&gt;.php, you have to create an additional folder of the same name next to the plugin file. Use exact this folder setup:</p>
<p><code>/plugins/&lt;plugin name&gt;/locale/<br />
/plugins/&lt;plugin name&gt;/<tt>locale/</tt><tt>&lt;language locale&gt;/LC_MESSAGES/<br />
/plugins/&lt;plugin name&gt;/</tt><tt>locale/</tt><tt>&lt;language locale&gt;/LC_MESSAGES/</tt><tt>&lt;plugin name&gt;.po</tt><tt>/plugins/&lt;plugin name&gt;/</tt><tt>locale/</tt><tt>&lt;language locale&gt;/LC_MESSAGES/</tt><tt>&lt;plugin name&gt;.mo</tt></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/zenphoto-plugin-architecture/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Theming Tutorial</title>
		<link>http://www.zenphoto.org/2010/08/theming-tutorial/</link>
		<comments>http://www.zenphoto.org/2010/08/theming-tutorial/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 06:00:24 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Customizing]]></category>
		<category><![CDATA[Theming & Templating]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[User Guide]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=113</guid>
		<description><![CDATA[
Part 1: Theme Basics

What should I know before making a theme?
What is a theme
Where are the theme files located?
How can I install a theme designed by someone else?
How does a theme work?
Theme structure


Part 2: Making a theme

theme_description.php
theme.png
index.php
album.php
image.php
search.php
Adding the comments section


Part 3: Advanced Theme Functionality

Custom pages with the example of archive.php and slideshow.php
Separation of the gallery [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li><a href="#part-1"><strong>Part 1: Theme Basics</strong></a>
<ol>
<li><a href="#what-should-I-know-before-making-a-theme">What should I know before making a theme?</a></li>
<li><a href="#what-is-a-theme">What is a theme</a></li>
<li><a href="#where-are-the-theme-files-located">Where are the theme files located?</a></li>
<li><a href="#installing-a-theme">How can I install a theme designed by someone else?</a></li>
<li><a href="#how-does-a-theme-work">How does a theme work?</a></li>
<li><a href="#theme-structure">Theme structure</a></li>
</ol>
</li>
<li><a href="#part-2"><strong>Part 2: Making a theme</strong></a>
<ol>
<li><a href="#theme_description.php">theme_description.php</a></li>
<li><a href="#theme.png">theme.png</a></li>
<li><a href="#index.php">index.php</a></li>
<li><a href="#album.php">album.php</a></li>
<li><a href="#image.php">image.php</a></li>
<li><a href="#search.php">search.php</a></li>
<li><a href="#adding-comments">Adding the comments section</a></li>
</ol>
</li>
<li><a href="#"><strong>Part 3: Advanced Theme Functionality</strong></a>
<ol>
<li><a href="#custom-pages">Custom pages <em>with the example of archive.php and slideshow.php</em></a></li>
<li><a href="#custom-gallery">Separation of the gallery and the index page</a></li>
<li><a href="#custom-functions">Custom functions</a></li>
<li><a href="#theme-options">Theme options</a></li>
<li><a href="#override-options">Overriding options for special theme effects.</a></li>
<li><a href="#special-images">Special images</a></li>
<li><a title="#special-scripts" href="#special-scripts">Special scripts</a></li>
<li><a href="#theme-translations">Separate theme translations</a></li>
<li><a href="#sophisticated-theme-design">Sophisticated theme design</a></li>
</ol>
</li>
<li><a href="#part-4"><strong>Part 4: Theming Zenpage</strong></a>
<ol>
<li><a title="zenpage-theme-basics" href="#zenpage-theme-basics">Zenpage theme basics</a></li>
<li><a title="pages.php" href="#pages">pages.php</a></li>
<li><a title="news" href="#news">news.php</a></li>
<li><a title="news-on-index" href="#news-on-index">News on index.php</a></li>
<li><a title="search-results-for-zenpage-items" href="#search-results-for-zenpage-items">Adding search results for Zenpage items on search.php</a></li>
<li><a title="zenpage-content-on-other-theme-pages" href="#zenpage-content-on-other-theme-pages">Showing Zenpage content on other theme pages</a></li>
<li><a title="combinews" href="#combinews">The CombiNews feature</a></li>
</ol>
</li>
</ol>
<h4>Part 1: Theme Basics<a name="Part-1"></a></h4>
<h5>What should I know before making a custom theme?<a name="what-should-I-know-before-making-a-theme"></a></h5>
<p>During the process of this article, we will be looking at the basic files and function elements that are necessary to form a working Zenphoto theme, We&#8217;ll use the default theme as an example. We will not go into every single detail of the code because we assume that you have an good understanding of (X)HTML and CSS. You should also have a basic understanding what PHP is and how PHP code is put into a webpage and communicates with the server and returns information back to the client.</p>
<p>For more detailed information on the Zenphoto template functions please visit our <a title="http://www.zenphoto.org/documentation/index.html" href="http://www.zenphoto.org/documentation/index.html">functions documentation</a> and it&#8217;s accompaning <a title="http://www.zenphoto.org/2008/04/how-to-read-the-zenphoto-functions-guide/" href="http://www.zenphoto.org/2008/04/how-to-read-the-zenphoto-functions-guide/">How To Read The Zenphoto Functions Guide article</a>.</p>
<h5>What is a theme?<a name="what-is-a-theme"></a></h5>
<p>In technical terms, it&#8217;s a set of files that use a markup language ((X)HTML and CSS) and embedded PHP code to dynamically create the layout and style of your gallery. In other words, a theme is just a way to give your gallery a different look.</p>
<h5>Where are the theme files located?<a name="where-are-the-theme-files-located"></a></h5>
<p>By default, when you first install Zenphoto, you should have a file structure that looks similar to the image on the left. You have the &#8220;root&#8221; or main folder of Zenphoto, then in it you have four other folders named <tt>albums, cache, themes</tt>, and <tt>zp-core</tt>. The <tt>themes</tt> folder is where the default themes exist, where you should install new themes that you&#8217;ve downloaded, and where you will put all your new themes. Zenphoto comes with four themes: default, example, effervescence_plus and stopdesign.</p>
<h5>Where do I find themes and how can I install a theme designed by someone else?</h5>
<p>You can find all known custom themes at our <a title="zenphoto themes" href="/zp/theme">themes page</a>, or from the theme creator&#8217;s site.</p>
<p>Usually, the distribution of a theme comes with instructions on how to install the theme. For those instances where instructions don&#8217;t exist, here is a basic set of installation instructions for installing themes:</p>
<ol>
<li>Download the theme of your choice.</li>
<li>Expand the zip archive to a local folder.</li>
<li>Upload the extracted folder (keeping the underlying folder structure intact) to your <tt>/themes</tt> directory.</li>
<li>Go into your admin &gt; themes tab and choose your theme.</li>
<li>View your gallery with the new theme in place!</li>
</ol>
<p><strong>Note:</strong> Some themes have custom mods or things that need to be changed in addition to the normal theme installation. So take care to note in the theme distribution what these may be before you install.</p>
<h5>How does a theme work?<a name="how-does-a-theme-work"></a></h5>
<p>Themes are done in a pretty straightforward way. They&#8217;re just PHP files that use a set of theme functions (from <tt>zp-core/template-functions.php</tt>) to display the albums or images in any way. The current theme is selected in the admin themes panel. (Admin uses the file <tt>theme_description.php</tt> within the theme&#8217;s folder as the sorce of its information about the theme.) The root index.php file then looks at the URL arguments (album, image, etc. or lack thereof) and decides whether to load the theme&#8217;s index file, album page, or image page. Pretty simple.</p>
<p>The already mentioned template functions generate predefined HTML output for your convenience. These are the functions that generally beginn with <em>&#8220;print</em>&#8220;. You can style that via CSS to your needs. These function generate code that follows the XHTML 1.1 transitional standard.</p>
<p>Of course for advanced users it is also possible to get the pure data to setup your own html output using custom functions for more flexibility. You can read an introduction on this later in this tutorial.</p>
<h5>Theme Structure<a name="theme-structure"></a></h5>
<p>Here&#8217;s a brief description of the basic files that are needed for a standard theme:</p>
<p>These are the required basic files every theme must have:</p>
<ul>
<li><tt>theme_description.php</tt> &#8211; This is the description file which gives ZenPhoto information about your theme. This information is displayed in the themes page of the ZenPhoto admin backend. Older themes before ZenPhoto 1.2 may use a theme.txt file for the same purpose.</li>
<li><tt>theme.png</tt> &#8211; This is the theme thumbnail used in the Options page of ZenPhoto.</li>
<li><tt>index.php</tt> &#8211; This is the default php file. It&#8217;s read and displayed when someone visits your main gallery page.</li>
<li><tt>album.php</tt> &#8211; This page is displayed when someone clicks on an album link from your gallery page (index.php). It then displays all the pictures in the selected album as thumbnails.</li>
<li><tt>image.php</tt> &#8211; This page is displayed when someone clicks on a specific thumbnail picture on your album page (<tt>album.php</tt>). It then displays the selected picture (the sized image), all it&#8217;s comments, and the &#8220;add comment&#8221; form.</li>
</ul>
<p>The following files are optional as they are not required for a basic functioning theme:</p>
<ul>
<li><tt>search.php</tt> &#8211; The page that displays search results. Actually this page is optional if you don&#8217;t want to use the search on your site. It&#8217;s included in all standard themes.</li>
<li><tt>archive.php</tt> &#8211; A custom page that is used to display the monthly archive and a tag cloud. It&#8217;s included in all standard themes except stopdesign.</li>
<li><tt>themeoptions.php</tt> &#8211; This provides the option handling interface used by the admin backend on the theme options page.</li>
<li><tt>slideshow.php</tt> &#8211; A page that displays the slideshow. The design is generic so that it works with all themes without design adjusting, just a black background with the image on it, but it&#8217;s possible to make it look like your other theme pages. Related files that are required to run the slideshow are the <tt>slideshow.css</tt> and the <tt>slideshow-controls.png</tt> and the slideshow plugin must be installed and activated.</li>
</ul>
<p>A diagram that shows the relations of the theme files:</p>
<p><a href="http://www.zenphoto.org/wp-content/uploads/2008/05/zenphoto-theme-diagram-10.png"><img class="alignnone size-full wp-image-115" title="zenphoto-theme-diagram-10" src="http://www.zenphoto.org/wp-content/uploads/2008/05/zenphoto-theme-diagram-10.png" alt="" width="500" height="545" /></a></p>
<h4>Part 2: Making a Theme<a name="part-2"></a></h4>
<p>We will now look at the necessary theme pages and the basic structure of these file that Zenphoto needs to process a theme. You can then take this knowledge and use it to create your own theme. Again, we won&#8217;t discuss any functions (or any (X)HTML or CSS styling) in detail.</p>
<p>More info on specific functions can be found in our functions guide.</p>
<h5>theme_description.php<a name="theme_description.php"></a></h5>
<pre>&lt;?php // Zenphoto theme definition file
$theme_description['name'] = 'Default';
$theme_description['author'] = '&lt;a href="http://www.noscope.com"
target="_blank"&gt;Joen Asmussen&lt;/a&gt;
and &lt;a href="http://www.levibuzolic.com" target="_blank"&gt;Levi Buzolic&lt;/a&gt;';
$theme_description['version'] = '1.5';
$theme_description['date'] = '10/20/2007';
$theme_description['desc'] = "The default theme in 4 distinct flavors.
After choosing this theme you can pick the theme color by going to the
Admin Options tab
and changing the &lt;em&gt;Theme colors&lt;/em&gt; option."; ?&gt;</pre>
<p>First of all, the first line is REQUIRED. This line will tell ZenPhoto that this file is about to describe a theme. Zenphoto will then look at the rest of the information and process it. The information is set up as key-value relationships using the format key::value. This means that whatever the name of the key, the value is shown after the &#8220;=&#8221; . So now let&#8217;s take a look at the list of keys and what they&#8217;re for.</p>
<ul>
<li>name &#8211; This is the name of the theme.</li>
<li>author &#8211; This is the theme author&#8217;s name.</li>
<li>version &#8211; This should be the version number of the theme.</li>
<li>date &#8211; This should be the last known date of modification of the theme.</li>
<li>description &#8211; This should be a short description of the theme. It would be a good idea if you include within the description the Zenphoto version for which you actually made this theme.</li>
</ul>
<p>So just change the values of the keys to match your theme.</p>
<h5>theme.png/theme.gif/theme.jpg<a name="theme.png"></a></h5>
<p>This will most likely be the very last file that you create for your theme; it&#8217;s an image used to represent your theme. This image can either be a .png, .gif, or .jpg and the dimensions of the file should be 150 x 150px. Most themes use a screenshot of thefinished theme for this image.</p>
<h5>index.php<a name="index.php"></a></h5>
<p>Look at the code in <tt>index.php</tt>, it&#8217;s all just a standard xHTML-based webpage, but we&#8217;ll try and explain some of the PHP code that&#8217;s in there.</p>
<pre>&lt;?php if (!defined('WEBPATH')) die(); ?&gt;</pre>
<p>This bit of code makes sure that the configuration for Zenphoto is setup correctly, if not it will stop everything right here. (There&#8217;s no point in processing the rest of the webpage if the configuration is incorrect, right?)</p>
<pre>&lt;?php printGalleryTitle(); ?&gt;</pre>
<p>As you can read from the function name, this function will place the actual name of the Gallery Title on the displayed page. So for example, if the title of your gallery were John&#8217;s Flower Garden then the code would go from looking like this:</p>
<pre>&lt;title&gt;&lt;?php printGalleryTitle(); ?&gt;&lt;/title&gt;</pre>
<p>to like this:</p>
<pre>&lt;title&gt;John's Flower Garden&lt;/title&gt;</pre>
<p>The next bit of PHP code:</p>
<pre>&lt;?php echo $_zp_themeroot ?&gt;</pre>
<p>Tells ZenPhoto to show the current path to the current theme&#8217;s root directory. This is why it&#8217;s used in the following context:</p>
<pre>&lt;link rel="stylesheet" href="&lt;?php echo $_zp_themeroot ?&gt;/index.css" type="text/css" /&gt;</pre>
<p>This will give the correct path to the .css file.</p>
<pre>&lt;?php zp_apply_filter('theme_head); ?&gt;
&lt;?php zp_apply_filter('theme_body_open); ?&gt;
&lt;?php zp_apply_filter('theme_body_close); ?&gt;</pre>
<p>The Zenphoto template functions and many plugins require certain HTML entries in the HTML &#8221;head&#8221; section of your theme script files. Place &#8221;theme_head&#8221; line the above just after the &lt;head&gt; directive in your script. This replaces the call on zenJavascript() of Zenphoto releases prior to v1.3.2. That function is now deprecated.</p>
<p>Likewise, some plugins will need to place their code either at the beginning or at the end of the HTML &#8220;body&#8221;. Place the &#8220;theme_body_open&#8221; line just after the &lt;body&gt; directive and the &#8220;theme_body_close&#8221; line just before the &lt;/body&gt; directive.</p>
<pre>&lt;?php if (getOption('Allow_search')) { printSearchForm(''); } ?&gt;</pre>
<p>If you set it in the Allow_search options this will print the search form.</p>
<pre>&lt;?php printHomeLink('', ' | '); echo getGalleryTitle(); ?&gt;</pre>
<p>This is actually a short breadcrumb navigation that will print this if you use Zenphoto within a website and set the link to that site within the options:</p>
<p>Site name | Gallery title</p>
<p>The following code is the main chunk of code for this file. It&#8217;s the so called &#8220;album loop&#8221; that lists all the albums in the gallery:</p>
<pre>&lt;?php while (next_album()): ?&gt; &lt;div class="album"&gt;
&lt;div class="albumthumb"&gt;&lt;a href="&lt;?php echo getAlbumLinkURL();?&gt;"
title="&lt;?php echo getAlbumTitle();?&gt;"&gt;
&lt;?php printAlbumThumbImage(getAlbumTitle()); ?&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="albumtitle"&gt;
&lt;a href="&lt;?php echo getAlbumLinkURL();?&gt;"
title="&lt;?php echo getAlbumTitle();?&gt;"&gt;&lt;/a&gt;
&lt;?php printAlbumTitle(true); ?&gt;&lt;/div&gt; &lt;/div&gt; &lt;?php endwhile; ?&gt;</pre>
<p>Let&#8217;s take this line by line. First you&#8217;re starting a while loop in PHP and tell ZenPhoto that &#8216;as long as there&#8217;s a another album that&#8217;s next in the list of albums, do the following code&#8217;. The &#8216;code&#8217; that you want Zenphoto to process for every album is placed in between the the lines <tt>'&lt;?php while (next_album()): ?&gt;'</tt> and <tt>'&lt;?php endwhile; ?&gt;'</tt></p>
<p>That is why when you look at the xHTML source from your browser you see a div with an album class more than once, because it will put every album into a div tag with the album class.</p>
<p>Now inside that while loop you will see more PHP code. The functions <tt>getAlbumLinkURL(), getAlbumTitle(), printAlbumThumbImage()</tt>, and <tt>printAlbumTitle()</tt> are all theme functions of which we won&#8217;t explain because there are just too many to create a list here and you can also look them up in the theme function reference. However it&#8217;s pretty obvious what they do just by looking at the function names. Keep in mind that all these functions provide information about the album and this information will be repeated for each album in the list of albums while going through the while loop.</p>
<p><strong>Note:</strong> If you password protect an album via the admin backend and have the image display <em>use lock image</em> option set, Zenphoto uses a default image <tt>err-passwordprotected.gif</tt> as a replacement for the actual album thumb. This image is located within <tt>/zenphoto/zp-core/image/</tt> folder. But a theme can have its own image, all that needs to be done is to place a custom image of the same name like this: <tt>/zenphoto/&lt;themefolder&gt;/images/err-passwordprotected.gif</tt>.</p>
<pre>&lt;?php printPageListWithNav('&lt;', '&gt;'); ?&gt;</pre>
<p>This code will create an unordered list of links that link to the number of pages of albums in the gallery. So, for example, if you have three pages of albums, it will create the follwing code:</p>
<pre>&lt;ul class="pagelist"&gt; &lt;li class="prev"&gt;&lt;span class="disabledlink"&gt;&lt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="current"&gt;&lt;a href="http://www.zenphoto.org:8080/zp"
title="Page 1 (Current Page)"&gt;1 &lt;/a&gt;
&lt;/li&gt; &lt;li&gt;&lt;a href="http://www.zenphoto.org:8080/zp/page/2/" title="Page 2"&gt;2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.zenphoto.org:8080/zp/page/3/" title="Page 3"&gt;3&lt;/a&gt;&lt;/li&gt;
&lt;li class="next"&gt;&lt;a href="http://www.zenphoto.org:8080/zp/page/2/"
title="Next Page"&gt;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>Most themes then contain a footer that prints the gallery rss link and the link to the (optional) archive page:</p>
<pre>&lt;div id="credit"&gt;&lt;?php printRSSLink('Gallery','','RSS', ' | '); ?&gt;
&lt;a href="?p=archive"&gt;&lt;?php echo "Archive View"; ?&gt;&lt;/a&gt; | &lt;?php echo "Powered by"; ?&gt;
&lt;a href="http://www.zenphoto.org" title="&lt;?php echo 'A simpler web photo album'; ?&gt;"&gt;
zenphoto&lt;/a&gt;&lt;/div&gt;</pre>
<p>This is followed by the admin tool box that lets you directly jump to the admin backend if you are logged in, althought not necessary for a theme, this can be very useful:</p>
<pre>&lt;?php printAdminToolbox(); ?&gt;</pre>
<h5>album.php</h5>
<p>This page is almost exactly identical to index.php, so we won&#8217;t explain everything again.</p>
<p>We have the expanded breadcrumb navigation, that now prints additionally the album title, too.</p>
<pre>&lt;?php printHomeLink('', ' | '); ?&gt;
&lt;a href="&lt;?php echo getGalleryIndexURL();?&gt;" title="&lt;?php echo 'Albums Index'; ?&gt;"&gt;
&lt;?php echo getGalleryTitle();?&gt;&lt;/a&gt; | &lt;?php printParentBreadcrumb(); ?&gt;&lt;/span&gt;
&lt;?php printAlbumTitle(true);?&gt;&lt;/h2&gt;</pre>
<p>The <tt>&lt;?php printParentBreadcrumb(); ?&gt; </tt>part is for the breadcrumb display if you have one or more subalbum levels.</p>
<p>The next necessary element is then again the &#8220;album loop&#8221; you know already from <tt>index.php</tt>, that now displays the subalbums if available.</p>
<p>But now comes a really new part, the &#8220;image loop&#8221;:</p>
<pre>&lt;?php while (next_image(false, $firstPageImages)): ?&gt;&lt;div class="image"&gt;
&lt;div class="imagethumb"&gt;
&lt;a href="&lt;?php echo htmlspecialchars(getImageLinkURL());?&gt;"
title="&lt;?php echo getImageTitle();?&gt;"&gt;
&lt;?php printImageThumb(getImageTitle()); ?&gt;&lt;/a&gt; &lt;/div&gt;
&lt;/div&gt;&lt;?php endwhile; ?&gt;</pre>
<p>This works just like the &#8220;album loop&#8221; but displays the thumbnails of the images that are in the current selected album.</p>
<p>The remaining code is then again the page navigation and the footer that is the same as on index.php, except that you might want to use the album rss link instead of the gallery rss link.</p>
<h5>image.php<a name="image.php"></a></h5>
<p>Since you should be used to the theme functions by now, we won&#8217;t go into what everyone does, but we&#8217;ll try and explain the more difficult bits of code.</p>
<p>Right at the top of this file (right before you define where the AJAX code goes) you&#8217;ll notice a new bit of JavaScript.</p>
<pre>function toggleComments() { var commentDiv = document.getElementById("comments");
if (commentDiv.style.display == "block") { commentDiv.style.display = "none";
} else { commentDiv.style.display = "block"; } } &lt;/script&gt;</pre>
<p>This code will basically allow you to toggle whether or not you want the comments to show or not. Just use it in a link and use the OnClick method of a link to run the toggleComments() function.</p>
<pre>&lt;div class="navigation"&gt; &lt;?php if (hasPrevImage()) { ?&gt;
&lt;a href="&lt;?php echo getPrevImageURL();?&gt;" title="Previous Image"&gt;&lt;&lt;/a&gt;&lt;?php } ?&gt;
&lt;?php if (hasNextImage()) { ?&gt;&lt;a href="&lt;?php echo getNextImageURL();?&gt;" title="Next Image"&gt;&gt;
&lt;/a&gt;&lt;?php } ?&gt; &lt;/div&gt;</pre>
<p>If there is an image (in the list of images) previous than the one being viewed, tgis creates a link to that previous image with the text &#8220;&lt;&#8221;. Then, if there is an image (in the list of images) following the one being viewed, it creates a link to the following image with the text &#8220;&gt;&#8221;.</p>
<p>Again we will use the breadcrumb naviagtion that is now extended again with the image title:</p>
<pre>&lt;?php printHomeLink('', ' | '); ?&gt;
&lt;a href="&lt;?php echo getGalleryIndexURL();?&gt;" title="&lt;?php 'Albums Index'; ?&gt;"&gt;
&lt;?php echo getGalleryTitle();?&gt;&lt;/a&gt; |
&lt;?php printParentBreadcrumb("", " | ", " | ");
printAlbumBreadcrumb("", " | "); ?&gt; &lt;/span&gt;
&lt;?php printImageTitle(true); ?&gt;</pre>
<p>The next code display the actual image &#8211; we call it the &#8220;sized image&#8221; to separate it from the full size image, that is linked to the full image and if available the image description :</p>
<pre>&lt;div id="image"&gt;&lt;a href="&lt;?php echo getFullImageURL();?&gt;" title="&lt;?php echo getImageTitle();?&gt;"&gt;
&lt;strong&gt;&lt;?php printDefaultSizedImage(getImageTitle()); ?&gt;&lt;/strong&gt; &lt;/a&gt; &lt;/div&gt;
&lt;div id="narrow"&gt;&lt;?php printImageDesc(true); ?&gt;</pre>
<p>This is followed by the display of the EXIF information:</p>
<pre>&lt;?php if(getImageEXIFData()) {echo "&lt;div id=\"exif_link\"&gt;
&lt;a href=\"#TB_inline?height=345&amp;width=300&amp;inlineId=imagemetadata\"
title=\"Image Info\" class=\"thickbox\"&gt;Image Info
&lt;/a&gt;&lt;/div&gt;"; printImageMetadata('', false); } ?&gt;</pre>
<p>If you want to protect the display of your sized image and/or the comments by album or gallery password, you should place this &#8220;if clause&#8221; around the whole part of the above code from sized image to comments like this:</p>
<pre>&lt;?php if (!checkForPassword()) { ?&gt; stuff for sized image, comments, comments form &lt;?php }; ?&gt;</pre>
<p>The remaining is again the same as on album.php.</p>
<h5>search.php<a name="search.php"></a></h5>
<p>This is the last of the actual required theme page. It&#8217;s actually nearly the same as the <tt>album.php</tt> since it does displaying albums and image. But this time the search results and not fixed albums.</p>
<pre>&lt;div id="padbox"&gt; &lt;?php if (($total = getNumImages() + getNumAlbums()) &gt; 0) {
if ($_REQUEST['date']){ $searchwords = getSearchDate();
} else { $searchwords = getSearchWords(); }
echo "&lt;p&gt;Total matches for &lt;em&gt;".$searchwords."&lt;/em&gt;: $total&lt;/p&gt;"; } $c = 0; ?&gt;</pre>
<p>This is the actual new part that fetches the search queries someone entered and prints the how many matches there are. This is then followed by the already known &#8220;album loop&#8221; and &#8220;image loop&#8221; from <tt>album.php</tt>. After that the following code is added, that as you see is used if there are no matches.</p>
<pre>&lt;?php if ($c == 0) { echo "&lt;p&gt;Sorry, no image matches. Try refining your search.&lt;/p&gt;"; }</pre>
<p>The remaining is once again the same as on all other theme pages.</p>
<h5>Adding the comments section<a name="adding-comments"></a></h5>
<p>You can add comments to <a href="#album.php">album.php</a> and <a href="#image.php">image.php</a>. Additionally also to Zenpage&#8217;s <a title="#pages.php" href="#pages.php">pages.php</a> and <a href="#news.php">news.php</a>.</p>
<p>Since Zenphoto 1.2.6 the comment handling code has been transfered to the <em>comment_form</em> plugin. All you need to do is to put this code where you want the comment form and the comment display.</p>
<pre>&lt;?php
if (function_exists('printCommentForm')) { ?&gt;
&lt;div id="comments"&gt;
&lt;?php printCommentForm(); ?&gt;
&lt;/div&gt;
&lt;?php } ?&gt;</pre>
<p>You can of course modify the look of the comment section via CSS or you could even make your own comment form by changeing the file <tt>zp-core/plugins/comment_form/comment_form.php</tt>.</p>
<h4>Part 3: Advanced Theme Functionality<a name="part-3"></a></h4>
<p>This part of our tutorial is about the more advanced functionalitly you can add to your theme.</p>
<h5>Custom pages <em>with the example of <tt>archive.php</tt> and <tt>slideshow.php</tt></em><a name="custom-pages"></a></h5>
<p>&#8220;Custom pages&#8221; are additional pages that do not display actual gallery stuff like albums or images. You can have multiple custom pages that are called with the url</p>
<p><tt>zenphoto/index.php?p=pagetitle</tt> (non mod_rewrite)</p>
<p>or</p>
<p><tt>zenphoto/page/pagetitle</tt> (mod_rewrite)</p>
<p>In general a custom page is just like <tt>index.php</tt> but with the album loop removed. These pages can be used as an &#8220;about&#8221; or &#8220;references&#8221; page for example, but the content needs to be hardcoded and can not be adminstrated by zenphoto. (Of course, you can created theme options to allow customization of these pages from the admin theme options tab.)</p>
<p>You can use some of the more general theme functions as <tt>archive.php</tt> does.</p>
<p>Archive.php is used to display links that organize your images by month &amp; year, and a tag cloud of the most used tags:</p>
<pre>&lt;?php if (!checkForPassword()) {?&gt;
&lt;div id="archive"&gt;&lt;?php printAllDates(); ?&gt;&lt;/div&gt;
&lt;div id="tag_cloud"&gt; &lt;p&gt;Popular Tags&lt;/p&gt;
&lt;?php printAllTagsAs('cloud', 'tags'); ?&gt; &lt;/div&gt; &lt;?php } ?&gt;</pre>
<p>slideshow.php is actual a slim custom page that is outside the actual theme since it is meant to be used as a generic slideshow page. It consists of a basic html structure and the function</p>
<pre>&lt;?php printSlideShow(); ?&gt;</pre>
<h5>Separation of the gallery and the index page<a name="custom-gallery"></a></h5>
<p>You may wish to have an introductory page to your website but still keep the look and feel of the gallery for visitors viewing your images. This can easily be done by using the theme option <em>custom index page</em>. If you have an existing zenphoto gallery the easiest way to accomplish this task is to rename your current theme <tt>index.php</tt> script to something else, say <tt>gallery.php</tt>. Create your new index.php script to introduce your site. Include on it a link to <tt>http://yoursite.com/zenphoto/page/gallelry</tt> (assuming you named your old index file gallery.php and you installed zenphoto in the folder zenphoto). Set the custom <em>index page option</em> to <tt>gallery</tt> and your are all set.</p>
<h5>Custom functions<a name="custom-functions"></a></h5>
<p>Custom functions can be used to add additional functionality to your theme. Actually these are just an extra template functions that are placed as a extra PHP file within your theme&#8217;s folder. Name this theme file <tt>functions.php</tt> and it will be loaded automatically on every theme page to make the custom functions available.</p>
<h5>Theme options<a name="theme-options"></a></h5>
<p>Themes may create options that change the behavior or appearance of the theme. (All the distributed themes have options for these reasons.) Options are defined by PHP code in a file called <tt>themeoptions.php</tt> which is located in your theme folder. The file is optional, if you have no options you need not have <tt>themeoptions.php</tt>. Theme options are one class of Zenphoto plugins. Plugins are described <a title="Zenphoto Plugins" href="http://www.zenphoto.org/2008/04/zenphoto-plugin-architecture/">here</a>. You define the options in this code and make use of them in your theme by calling the function <tt>getOption()</tt> passing the option name. (It is a good idea to be sure any unique options you create have unique names so that they don&#8217;t conflict with options some other theme builder might have made.)</p>
<p>Some of the &#8217;standard&#8217; theme options (as defined by the distributed themes) are: &#8216;Allow_comments&#8217;, &#8216;Allow_search&#8217;, and &#8216;Theme_colors&#8217;. These are used in the distributed themes to enable comment forms, enable serach forms, and select a CSS for the theme. See the default theme for examples.</p>
<p>Themeoptions are a class of Zenphoto Plugin so reading about the <a title="Plugin Architecture" href="http://www.zenphoto.org/2008/04/zenphoto-plugin-architecture/">plugin architecture </a>might also be of some value.</p>
<h5>Overriding options for special theme effects<a name="override-options"></a></h5>
<p>If your theme has special needs for some options it is possible to override temporarily the options as set in the Administrative back end. Cases where this might be useful are, for instance, to insure that the theme looks well balanced when there are multiple album thumbs or image thumbs in a row. The theme may then wish to change the albums per page option (images per page option) so that it is a multiple of the number that will fit in a row. (The standard themes all do this.)</p>
<p>It would not be nice, however, for a theme to permanantly change the option as it would impact other themes that might get used. The <tt>setOption()</tt> function of zenphoto has provided a means to temporarily change an option without updating the options database. There is a third parameter the the <tt>setOption()</tt> function, <tt>$persistent</tt>, which is defaulted to true. Passing <tt>false</tt> to this parameter tells <tt>setOption()</tt> to change the value of the option in memory but not in the database.</p>
<p>The duration for an option set non-persistent is the scope of the script from where it is set until the script ends. This means that each script that relies on the transient value of the option must set it.</p>
<h5>Special images<a name="special-images"></a></h5>
<p>Zenphoto has several special images that a theme can replace it it wished. These are:</p>
<ul>
<li><code>imageDefault.png</code>which is used for album thumbnails when there are no images in the album.</li>
<li><code>multimediaDefault.png</code>which is the default image for video thumbnails.</li>
<p>and</p>
<li><code>err-passwordprotected.gif</code>which is used (optionally) as a standin for the thumbnail of an album which is password protected and the viewer has not supplied the password.</li>
</ul>
<p>A theme can override the images that come with Zenphoto by placing a same named image in a folder named <tt>images </tt>within the theme folder.</p>
<h5>Special scripts <a name="&gt;&lt;a href=" href="http://www.zenphoto.org/wp-admin/mce_href=">&#8220;&gt;</a></h5>
<p>There are currently two special PHP scripts that can be used to enhance your theme. They are optional, so if you have not created them, a standard behavior will replace them.</p>
<p><tt>404.php</tt>: If your theme contains this script it will be invoked whenever a page not found contition is raised by Zenphoto. Creating a script of this name allows you to control the presentaton of the page not found error. Each of the Zenphoto distributed themes contains such a script that you can take as an example.</p>
<p><tt>password.php</tt> (post 1.2.5): Default password protection handling will check passwords in the image and album loops. If an album is password protected, no subalbums or images will be returned from the loops. Instead, a password form will be presented. Additional protection can be achieved by placing <code>if (!checkforPassword(true) { }</code> block around content you wish hidden on password protected pages.</p>
<p>With the 1.2.6 release you can instead create a<tt> password.php</tt> script in your theme folder. If such a script exists, it will be loaded in place of the target Zenphoto page. This allows you to completely control the presentation of the password protected content. Each of the distributed themes contains such a script for your use as an example.</p>
<h5>Separate theme translations (post 1.2)<a name="theme-translations"></a></h5>
<p>If you provide a theme as a third party, it’s translation is naturally not included with Zenphoto’s general translation file. But with post Zenphoto 1.2 you can have an independent translation file for your theme. Zenphoto uses gettext for translations. Please visit our translating tutorial for more detailed information about that.</p>
<p>To set up your theme for separate gettext translation, you just need to place the following function on top of each theme file:</p>
<p><code>&lt;?php setThemeDomain(”&lt;theme name&gt;”); ?&gt;</code></p>
<p>This function tells Zenphoto that this theme uses it’s own translation.</p>
<p>You also need need to have a locale folder set up within your theme&#8217;s folder this way:</p>
<pre>/themes/&lt;theme name&gt;/locale/
/themes/&lt;theme name&gt;/locale/&lt;language locale&gt;/LC_MESSAGES/
/themes/&lt;theme name&gt;/locale/&lt;language locale&gt;/LC_MESSAGES/&lt;theme name&gt;.po
/themes/&lt;theme name&gt;/locale/&lt;language locale&gt;/LC_MESSAGES/&lt;theme name&gt;.mo</pre>
<p>It is important that you then only parse your theme&#8217;s folder with Poedit or another gettext editor.</p>
<h5><a name="sophisticated-theme-design"></a>Sophisticated theme design</h5>
<p>Zenphoto is actually not limited to the already described standard theme way. Besides the fact that all template functions have a &#8220;print&#8221; variant that prints a full convenient HTML setup there is also (nearly) always a &#8220;get&#8221; variant that just returns raw data (strings, objects, array etc.) to build customized functions for special needs.</p>
<p>Zenphoto also provides an object orientated framework for advanced users with coding knowledge to do different and more sophisicated things that are bascially only limited by your abilities.</p>
<p>See the <a title="http://www.zenphoto.org/2010/02/zenphotos-object-model-framework/" href="http://www.zenphoto.org/2010/02/zenphotos-object-model-framework/">object model framework tutorial</a> and the <a title="http://www.zenphoto.org/documentation" href="../documentation">functions documentation</a> for more details.</p>
<h4>Part 4: Theming Zenpage<a name="part-4"></a></h4>
<h5><a name="zenpage-theme-basics"></a>Zenpage theme basics</h5>
<p>This part will give you only a basic overview how to setup your theme for the <a title="http://www.zenphoto.org/2009/03/zenpage-a-cms-plugin-for-zenphoto/" href="http://www.zenphoto.org/2009/03/zenpage-a-cms-plugin-for-zenphoto/">CMS plugin Zenpage</a>. It will not explain every detail. For more about the functions in detail please visit the functions guide and take a look at the included zenpage-default theme.</p>
<p>Zenpage hooks on Zenphoto&#8217;s <a title="custom pages" href="#custom-pages">custom page feature</a> and therefore requires two new custom pages to be available with your theme folder: <tt>pages.php</tt> and <tt>news.php</tt>. The name can be changed if really required for a certain language but this is only recommended for more advanced users. You can read about it in the FAQs.</p>
<p>Generally you can use all general Zenpage functions on all Zenphoto theme pages as you can in turn use all general Zenphoto functions on these two new pages.  Although some functions are limited only to <tt>pages.php</tt> and <tt>news.php</tt> to work correctly.</p>
<h5><a name="pages"></a>pages.php</h5>
<p>This theme page is the simplest of the both since it will only show one page at the time, so we start with it.</p>
<p>For a general site you just need the headline and the content:</p>
<pre>&lt;h2&gt;&lt;?php printPageTitle(); ?&gt;&lt;/h2&gt;&lt;?php printPageContent(); ?&gt;</pre>
<p>You can of course customize this with <tt>printExtraContent()</tt> or the <tt>printCodeblock()</tt> functions.</p>
<p>If you like to have comments on your page you have to add the comments part, too. A pages comments part is quite similar to the normal Zenphoto comments part. The only difference is that it uses to specific Zenpage options <tt>getOption('zenpage_comments_allowed')</tt>and <tt>zenpageOpenedForComments()</tt> that allow to set these independently from the general Zenphoto comments setting. See <a title="#adding-comments" href="#adding-comments">adding the comments section</a> for details.</p>
<p>The last thing you have to add is the admin tool box:</p>
<pre>&lt;?php printAdminToolbox(); ?&gt;</pre>
<h5><strong><a name="news"></a>news.php</strong></h5>
<p>This page is a little more complicated because it showe either the single news article and the news loop. The general structure is <tt>single news articles</tt> or <tt>news loop</tt>. First we check if this is a single news article:</p>
<pre>&lt;?php if(is_NewsArticle()) { ?&gt;</pre>
<p>If it is we show it. This two functions print links to the next or previous articles:</p>
<pre> &lt;?php printPrevNewsLink(); ?&gt; &lt;?php printNextNewsLink(); ?&gt;</pre>
<p>Note that these do not work when in <em>CombiNews</em> mode to avoid confusing since images will not be included.</p>
<p>Next we need the article itself with title, content and a few other functions that should be quite self explaining:</p>
<pre>&lt;h3&gt;&lt;?php printNewsTitle(); ?&gt;&lt;/h3&gt; &lt;?php printNewsDate();?&gt;&lt;?php echo gettext("Comments:"); ?&gt;&lt;?php echo getCommentCount(); ?&gt; &lt;?php printNewsCategories(", ",gettext("Categories: "),"newscategories"); ?&gt;&lt;?php printNewsContent(); ?&gt;</pre>
<p>Now if you like to have comments you need again the comments part that we already know from the <a title="#pages.php" href="#pages.php">pages.php</a> section.</p>
<p>Now we have to close the <tt>&lt;?php if(is_NewsArticle()) { ?&gt; </tt>statement from the beginning and open the else part for the news loop:</p>
<pre>} else {</pre>
<p>The news loop itself is again quite similar to two structures you know from Zenphoto, the <tt>next_image()</tt> and the <tt>next_album()</tt> loops. The content itself is actually nearly the same as for a single news article:</p>
<pre> while (next_news()): ;?&gt; &lt;h3&gt;&lt;?php printNewsTitleLink(); ?&gt;&lt;/h3&gt;&lt;?php printNewsDate();?&gt;&lt;?php echo gettext("Comments:"); ?&gt;&lt;?php echo getCommentCount(); ?&gt;&lt;?php printNewsCategories(", ",gettext("Categories: "),"newscategories"); ?&gt;&lt;?php printNewsContent(); ?&gt;&lt;p&gt;&lt;?php printNewsReadMoreLink(); ?&gt;&lt;/p&gt;&lt;?php  endwhile; ?&gt;</pre>
<p>Closing is a a function that is similar to the pagination of Zenphoto&#8217;s album and index page:</p>
<pre>&lt;?php printNewsPageListWithNav(gettext('next &amp;raquo;'), gettext('&amp;laquo; prev')); ?&gt;</pre>
<p>Then you have to close the else statement that we openend above:</p>
<pre>&lt;?php } ?&gt;</pre>
<p>Last but not least you can again add the admin toolbox.</p>
<pre>&lt;?php printAdminToolbox(); ?&gt;</pre>
<h5><a name="search-results-for-zenpage-items"></a>Adding search results for Zenpage items on <tt>search.php</tt></h5>
<p>Search results for Zenpage news articles and pages are not paginated and only shown on the first search results page.</p>
<p>Since Zenpage is an optional plugin we need to make sure that we set Zenpage results to 0 if the plugin is not enabled to avoid errors:</p>
<pre>$zenpage = getOption('zp_plugin_zenpage');
  if ($zenpage &amp;&amp; !isArchive()) {
   $numpages = getNumPages();
   $numnews = getNumNews();
   $total = $total + $numnews + $numpages;
 } else {
   $numpages = $numnews = 0;
 }</pre>
<p>Now we add the code to show the Zenpage results on the first results page only:</p>
<pre>&lt;?php
if ($_zp_page == 1) {
  if ($numpages &gt; 0) {
  $number_to_show = 5;
  $c = 0;
  ?&gt;
  &lt;/h2&gt;
  &lt;h3&gt;&lt;?php printf(gettext('Pages (%s)'),$numpages); ?&gt;&lt;/h3&gt;
  &lt;ul&gt;
&lt;?php
   while (next_page()) {
     $c++;
  ?&gt;
     &lt;li&gt;
       &lt;h4&gt;&lt;?php printPageTitlelink(); ?&gt;&lt;/h4&gt;
       &lt;p&gt;&lt;?php echo shortenContent(strip_tags(getPageContent()),80,getOption("zenpage_textshorten_indicator")); ?&gt;&lt;/p&gt;
    &lt;/li&gt;
&lt;?php
   }
?&gt;
  &lt;/ul&gt;
&lt;?php
}
if ($numnews &gt; 0) {
  $number_to_show = 5;
  $c = 0;
?&gt;
  &lt;h3&gt;&lt;?php printf(gettext('Articles (%s)'),$numnews); ?&gt;&lt;/h3&gt;
  &lt;ul&gt;
&lt;?php
    while (next_news()) {
      $c++;
?&gt;
      &lt;li&gt;
        &lt;h4&gt;&lt;?php printNewsTitleLink(); ?&gt;&lt;/h4&gt;
        &lt;p&gt;&lt;?php echo shortenContent(strip_tags(getNewsContent()),80,getOption("zenpage_textshorten_indicator")); ?&gt;&lt;/p&gt;
     &lt;/li&gt;
&lt;?php
    }
?&gt;
  &lt;/ul&gt;
&lt;?php
  }
}</pre>
<h5><a name="news-on-index"></a>News on index.php</h5>
<p>This option allows to turn the theme <tt>index.php</tt> into the first page of the news section (all further ones will be displayed on <tt>news.php</tt>). All you have to do to use this is to copy the complete <tt>next_news()</tt> loop to your <tt>index.php.</tt></p>
<p>It is recommended to limit the display to the first index.php page because the news loop uses the same variable for paging as index.php does. So you will get some probably unexpected results if you don&#8217;t limit this.</p>
<p>Alternatively you could also skip albums on index.php and use the <tt>printAlbumMenu()</tt> plugin to access them instead.</p>
<h5><strong><a name="zenpage-content-on-other-theme-pages"></a>Showing Zenpage content on other theme pages</strong></h5>
<p>You can use the <tt>get/printPageContent()</tt>, <tt>get/printExtraContent()</tt> and <tt>get/printCodeblock()</tt> functions to show published or unpublished pages&#8217; content, extracontent or codeblocks elsewhere. More info about these functions&#8217; parameters on the <a title="http://www.zenphoto.org/documentation" href="../documentation">documentation</a>.</p>
<p>If you need more fields like author or date, you probably should do this with the class object directly:</p>
<pre>$page = new ZenpagePage("&lt;titlelink of the page to get&gt;");</pre>
<p>Then you can call each field with <tt>&lt;?php echo $page-&gt;getId(); ?&gt;</tt> for example. Note that the title, content and extracontent fields support the multi-lingual feature, so that they need to be called like this:</p>
<pre>&lt;?php echo get_language_string(<tt>$page-&gt;getTitle()</tt>); ?&gt;&lt;?php echo get_language_string($page-&gt;getContent()); ?&gt;&lt;?php echo get_language_string($page-&gt;getExtraContent()); ?&gt;</pre>
<p>Of course this works similar for news articles, too. For more info about the Zenpage object methods please see the the <a title="http://www.zenphoto.org/2010/02/zenphotos-object-model-framework/" href="../2010/02/zenphotos-object-model-framework/">object model framework tutorial</a> and the <a title="http://www.zenphoto.org/documentation" href="../documentation">functions documentation</a>.</p>
<h5><a name="combinews"></a>The CombiNews feature</h5>
<p>This actually does not really need any special theming. Zenpage will just internally use the normal functions to show the lastest image within the normal loop as if they were news articles. They are still independed.</p>
<p>But you have some additional functions to use with them. For example there is:</p>
<pre>&lt;?php getNewsType(); ?&gt;</pre>
<p>This will print if the entry is a news article or an image or a movie. More detailed info on the functions guide.</p>
<p>Since images, movies or audio files do not have categories, but albums you can show this, too:</p>
<pre>&lt;?phpif(is_GalleryNewsType()) {echo gettext("Album:")."&lt;a href='".getNewsAlbumURL()."' title='".getBareNewsAlbumTitle()."'&gt; ".getNewsAlbumTitle()."&lt;/a&gt;";} else {printNewsCategories(", ",gettext("Categories: "),"newscategories");}?&gt;</pre>
<p>If the entry is an image etc it prints a link to the album it belongs to. If not is prints the list of the news article categories.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/theming-tutorial/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Zenphoto Gallery</title>
		<link>http://www.zenphoto.org/2010/08/zenphoto-gallery/</link>
		<comments>http://www.zenphoto.org/2010/08/zenphoto-gallery/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 15:09:29 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Unsupported]]></category>
		<category><![CDATA[Wordpress tools]]></category>
		<category><![CDATA[albums]]></category>
		<category><![CDATA[external]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[Thumbs]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1795</guid>
		<description><![CDATA[Developed by akerbos
Zenphoto Gallery allows to use Zenphoto albums in WordPress posts. Other plugins need access to Zenphoto&#8217;s database, not so this one. Given a JSON frontend to Zenphoto&#8217;s RSS facilities (included), Zenphoto Gallery pulls the images from both the general images feed and album feeds. It also provides some means to customize gallery layout [...]]]></description>
			<content:encoded><![CDATA[<p>Developed by akerbos</p>
<p>Zenphoto Gallery allows to use <em>Zenphoto</em> albums in <em>WordPress</em> posts. Other plugins need access to Zenphoto&#8217;s database, not so this one. Given a JSON frontend to Zenphoto&#8217;s RSS facilities (included), Zenphoto Gallery pulls the images from both the general images feed and album feeds. It also provides some means to customize gallery layout and behaviour.</p>
<p class="buttons"><a title="wordpress.org/extend/plugins/zenphoto-gallery/" href="http://wordpress.org/extend/plugins/zenphoto-gallery/">More info and download</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/zenphoto-gallery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zenphoto 1.3.1</title>
		<link>http://www.zenphoto.org/2010/08/zenphoto-1-3-1/</link>
		<comments>http://www.zenphoto.org/2010/08/zenphoto-1-3-1/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 14:30:42 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Changelog]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Release]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1745</guid>
		<description><![CDATA[
Security enhancements [sbillard]
Note particularly that the &#8220;Ajax&#8221; editing on the front end is disabled by default. It may be enabled from the gallery options tab. In addition, the new album and delete links in the Admin Toolbox will be absent unless gallery sessions are enabled.
File manager moved from button on Zenpage admin pages to a [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li>Security enhancements<em> [sbillard]<br />
Note particularly that the &#8220;Ajax&#8221; editing on the front end is disabled by default. It may be enabled from the gallery options tab. In addition, the new album and delete links in the Admin Toolbox will be absent unless </em><em>gallery sessions are enabled.</em></li>
<li>File manager moved from button on Zenpage admin pages to a subtab of the upload tab for IE compatibility reasons<em> [sbillard]</em></li>
<li>Rights refinements for managed albums<em> [sbillard]<br />
</em></li>
<li>Several Imagick improvements<em> [sbillard, kagutsuchi]</em></li>
<li>Admin bulk checkbox actions for albums, images, comments<em> [acrylian, sbillard]</em></li>
<li>Several RSS improvements <em>[acrylian]</em></li>
<li>RSS-comments feed now also covers Zenpage item comments (<em>rss-news-comments.php</em> has been removed)<em> [acrylian]</em></li>
<li>Codeblocks for albums and images<em> [sbillard, acrylian]<br />
</em></li>
<li>Plugins
<ul>
<li>Security logger<em> [sbillard]</em></li>
<li>Automated dababase backups<em> [sbillard]</em></li>
<li>Menu manager: Admin bulk actions <em>[acrylian, sbillard]</em></li>
<li>Comment_form improvements <em>[sbillard]</em></li>
<li>user_mailing list utility improved and BCC lists added<em> [sbillard]</em></li>
<li>TinyMCE editor
<ul>
<li>Now a real plugin <em>[acrylian, sbillard]</em></li>
<li>tinyZenpage full image link option<em> [acrylian]</em></li>
<li>Support for individual configuration files<em> [acrylian, sbillard]</em></li>
</ul>
</li>
<li>Hitcounter updates <em>[sbillard, kagutsuchi]</em></li>
<li>Zenpage CMS plugin:
<ul>
<li>Admin bulk actions <em>[acrylian, sbillard]</em></li>
<li>Sticky news articles<em> [sbillard, acrylian]</em></li>
<li>CombiNews mode: Sorting for mtime sort order improved<em> [acrylian]<br />
</em></li>
</ul>
</li>
<li>Slideshow flash mode fixed<em> </em>plus transitions improved<em> [acrylian - Thanks to fretzl]</em></li>
<li>jCarousel_thumb_nav plugin: Vertical mode option/parameter added<em> [acrylian, fretzl]<br />
</em></li>
</ul>
</li>
<li>Various other improvements and fixes are listed on the trunk</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/zenphoto-1-3-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Third party: Keyboard navigation / precache script</title>
		<link>http://www.zenphoto.org/2010/08/third-party-keyboard-navigation-precache-script/</link>
		<comments>http://www.zenphoto.org/2010/08/third-party-keyboard-navigation-precache-script/#comments</comments>
		<pubDate>Sat, 07 Aug 2010 11:19:39 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Third party]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1790</guid>
		<description><![CDATA[New listed on the extensions section:

Keyboard navigation plugin by Laurent for the left/right arrows for the image page.
A precache script written in Python.

The precache script was not submitted to us but we found it accidentally via monitoring the web. Please always let us know via the forum whatever you created related to Zenphoto to us [...]]]></description>
			<content:encoded><![CDATA[<p>New listed on the extensions section:</p>
<ol>
<li><a title="http://www.latitudes-photos.com/keyboardnav" href="http://www.latitudes-photos.com/keyboardnav">Keyboard navigation plugin</a> by Laurent for the left/right arrows for the image page.</li>
<li>A<a title="http://raginggoblin.wordpress.com/2010/07/30/precache-script-for-zenphoto/" href="http://raginggoblin.wordpress.com/2010/07/30/precache-script-for-zenphoto/"> precache script written in Python</a>.</li>
</ol>
<p>The precache script was not submitted to us but we found it accidentally via monitoring the web. Please always let us know via the forum whatever you created related to Zenphoto to us so we can list it as a central resource.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/08/third-party-keyboard-navigation-precache-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
