User guide

Theming Tutorial

    Part 1: Theme Basics

    What should I know before making a custom theme?

    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'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. If you don't have this understanding we recommend to learn that first. A good resource is for example: www.w3schools.com.

    For more detailed information on the Zenphoto template functions please visit our functions documentation and it's accompaning How To Read The Zenphoto Functions Guide article.

    What is a theme?

    In technical terms, it'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.

    Where are the theme files located?

    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 "root" or main folder of Zenphoto, then in it you have four other folders named albums, cache, themes, and zp-core. The themes folder is where the default themes exist, where you should install new themes that you've downloaded, and where you will put all your new themes. Zenphoto comes with four themes: default, example, effervescence_plus and stopdesign.

    Where do I find themes and how can I install a theme designed by someone else?

    You can find all known custom themes at our themes page, or from the theme creator's site.

    Usually, the distribution of a theme comes with instructions on how to install the theme. For those instances where instructions don't exist, here is a basic set of installation instructions for installing themes:

    1. Download the theme of your choice.
    2. Expand the zip archive to a local folder.
    3. Upload the extracted folder (keeping the underlying folder structure intact) to your /themes directory.
    4. Go into your admin > themes tab and choose your theme.
    5. View your gallery with the new theme in place!


    Note: 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.

    How does a theme work?

    Themes are done in a pretty straightforward way. They're just PHP files that use a set of theme functions (from zp-core/template-functions.php) to display the albums or images in any way. The current theme is selected in the admin themes panel. (Admin uses the file theme_description.php within the theme'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's index file, album page, or image page. Pretty simple.

    The already mentioned template functions generate predefined HTML output for your convenience. These are the functions that generally beginn with "print". You can style that via CSS to your needs. These function generate code that follows the XHTML 1.1 transitional standard.

    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.

    Theme Structure

    Zenphoto themes don't require any special standard HTML or CSS setup. You can freely design and structure your theme as needed. It is recommended to look also at the included standard  themes, most nottably the Defaultand Zenpage theme as they are the two most plain structured ones.

    However, there are some required basic files every theme must have (advanced, experienced theme coders may also leave this standard structure of course):

    • theme_description.php - 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.
    • theme.png - This is the theme thumbnail used in the Options page of ZenPhoto.
    • index.php - This is the default php file. It's read and displayed when someone visits your main gallery page.
    • album.php - 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.
    • image.php - This page is displayed when someone clicks on a specific thumbnail picture on your album page (album.php). It then displays the selected picture (the sized image), all it's comments, and the "add comment" form.

    zenphoto-theme-diagram-2


    The following files are optional as they are not required for a basic functioning theme. You see them in some themes:

    • search.php - The page that displays search results. Actually this page is optional if you don't want to use the search on your site. It's included in all standard themes.
    • archive.php - A custom page that is used to display the monthly archive and a tag cloud. It's included in all standard themes except stopdesign.
    • themeoptions.php - This provides the option handling interface used by the admin backend on the theme options page.
    • slideshow.php - 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's possible to make it look like your other theme pages. Related files that are required to run the slideshow are the slideshow.css and the slideshow-controls.png and the slideshow plugin must be installed and activated.
    • news.php - The page that displays both the Zenpage news loop or single news articles. This is an optional page of the Zenpage CMS plugin. More info on the theme page here.
    • pages.php - The page that displays single Zenpage . This is an optional page of the Zenpage CMS plugin. More info on the theme page here.

    Part 2: Making a Theme

    We will now look at the necessary theme pages and the basic structure of these file that Zenphoto needs to process a theme. Again, we won't discuss any functions (or any (X)HTML or CSS styling) in detail and only provide basic examples of standard function whose names are pretty self explanatory. Optional plugin functions are not included.

    As already said it is up to you what HTML structure (besides the core one naturally) you use in your theme. So we just included the bare bones HTML page construct in the following examples. Look at the included standard theme for suggestions.

    You can then take this knowledge and use it to create your own theme. More info on specific functions can be found in our functions guide.

    theme_description.php
    <?php // Zenphoto theme definition file
    $theme_description['name'] = 'Default';
    $theme_description['author'] = '<a href="http://www.noscope.com"
    target="_blank">Joen Asmussen</a>
    and <a href="http://www.levibuzolic.com" target="_blank">Levi Buzolic</a>';
    $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 <em>Theme colors</em> option."; ?>

    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 "=" . So now let's take a look at the list of keys and what they're for.

    • name - This is the name of the theme.
    • author - This is the theme author's name.
    • version - This should be the version number of the theme.
    • date - This should be the last known date of modification of the theme.
    • description - 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.

    So just change the values of the keys to match your theme.

    theme.png/theme.gif/theme.jpg

    This will most likely be the very last file that you create for your theme; it'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.

    index.php
    <?php
    	// force UTF-8
    	if (!defined('WEBPATH')) die();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<?php zp_apply_filter('theme_head'); ?>
    		<title><?php echo getBareGalleryTitle(); ?></title>
    		<meta http-equiv="content-type" content="text/html; charset=<?php echo LOCAL_CHARSET; ?>" />
    		<link rel="stylesheet" href="<?php echo $_zp_themeroot; ?>/style.css" type="text/css" />
    		<?php printRSSHeaderLink('Gallery',gettext('Gallery RSS')); ?>
    	</head>
    	<body>
    		<?php zp_apply_filter('theme_body_open'); ?>
    		<?php printGalleryTitle(); ?>
    		<?php 
    			if (getOption('Allow_search')) { 
    				printSearchForm("","search","",gettext("Search gallery")); 
    			} 
    		?>
    		<?php printGalleryDesc(); ?>
    		<?php while (next_album()): ?>
    			<a href="<?php echo html_encode(getAlbumLinkURL());?>" title="<?php echo gettext('View album:'); ?> <?php echo getAnnotatedAlbumTitle();?>"><?php printAlbumThumbImage(getAnnotatedAlbumTitle()); ?></a>
    			<a href="<?php echo html_encode(getAlbumLinkURL());?>" title="<?php echo gettext('View album:'); ?> <?php echo getAnnotatedAlbumTitle();?>"><?php printAlbumTitle(); ?></a>
    			<?php printAlbumDate(""); ?>
    			<?php printAlbumDesc(); ?>
    		<?php endwhile; ?>
    		<?php printPageListWithNav("« ".gettext("prev"), gettext("next")." »"); ?>
    		<?php printRSSLink('Gallery','','RSS', ' | '); ?>
    		<?php printZenphotoLink(); ?>
    		<?php 
    			printAdminToolbox();
    			zp_apply_filter('theme_body_close');
    		?>
    	</body>
    </html>
    

    The Zenphoto template functions and many plugins require certain HTML entries in the HTML "head" section of your theme script files. So every theme page must include the three "zp_apply_filter" calls.

    album.php

    This page is almost exactly identical to index.php, so we won't explain everything again.

    We have the expanded breadcrumb navigation, that now prints additionally the album title, too.

    <?php
    	// force UTF-8
    	if (!defined('WEBPATH')) die();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<?php zp_apply_filter('theme_head'); ?>
    		<title><?php echo getBareGalleryTitle(); ?> | <?php echo getBareAlbumTitle();?></title>
    		<meta http-equiv="content-type" content="text/html; charset=<?php echo LOCAL_CHARSET; ?>" />
    		<link rel="stylesheet" href="<?php echo $_zp_themeroot; ?>/style.css" type="text/css" />
    		<?php printRSSHeaderLink('Album',getAlbumTitle()); ?>
    </head>
    	<body>
    		<?php zp_apply_filter('theme_body_open'); ?>
    		<?php printHomeLink('', ' | '); ?><a href="<?php echo html_encode(getGalleryIndexURL());?>" title="<?php echo gettext('Albums Index'); ?>"><?php echo getGalleryTitle();?></a> | <?php printParentBreadcrumb(); ?><?php printAlbumTitle();?>
    		<?php 
    			if (getOption('Allow_search')) {  
    				printSearchForm("","search","",gettext("Search gallery")); 
    			} 
    		?>
    		<?php printAlbumDesc(true); ?>
    		<?php while (next_album()): ?>
    			<a href="<?php echo html_encode(getAlbumLinkURL());?>" title="<?php echo gettext('View album:'); ?> <?php echo getAnnotatedAlbumTitle();?>"><?php printAlbumThumbImage(getAnnotatedAlbumTitle()); ?></a>
    			<a href="<?php echo html_encode(getAlbumLinkURL());?>" title="<?php echo gettext('View album:'); ?> <?php echo getAnnotatedAlbumTitle();?>"><?php printAlbumTitle(); ?></a>
    			<?php printAlbumDate(""); ?>
    			<?php printAlbumDesc(); ?>
    		<?php endwhile; ?>
    		<?php while (next_image()): ?>
    			<a href="<?php echo html_encode(getImageLinkURL());?>" title="<?php echo getBareImageTitle();?>"><?php printImageThumb(getAnnotatedImageTitle()); ?></a>
    			</div>
    		<?php endwhile; ?>
    		<?php printPageListWithNav("« ".gettext("prev"), gettext("next")." »"); ?>
    		<?php printTags('links', gettext('<strong>Tags:</strong>').' ', 'taglist', ''); ?>
    		<?php printRSSLink('Gallery','','RSS', ' | '); ?>
    		<?php printZenphotoLink(); ?>
    		<?php 
    			printAdminToolbox();
    			zp_apply_filter('theme_body_close');
    		?>
    	</body>
    </html>
    
    image.php
    <?php
    	// force UTF-8 
    	if (!defined('WEBPATH')) die();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<?php zp_apply_filter('theme_head'); ?>
    		<title><?php echo getBareGalleryTitle(); ?> | <?php echo getBareAlbumTitle();?> | <?php echo getBareImageTitle();?></title>
    		<meta http-equiv="content-type" content="text/html; charset=<?php echo LOCAL_CHARSET; ?>" />
    		<link rel="stylesheet" href="<?php echo $_zp_themeroot; ?>/style.css" type="text/css" />
    		<?php printRSSHeaderLink('Gallery',gettext('Gallery RSS')); ?>
      </head>
    	<body>
    		<?php zp_apply_filter('theme_body_open'); ?>
    		<?php printHomeLink('', ' | '); ?><a href="<?php echo html_encode(getGalleryIndexURL());?>" title="<?php echo gettext('Albums Index'); ?>"><?php echo getGalleryTitle();?></a> | <?php printParentBreadcrumb(); ?><?php printAlbumTitle(true);?>
    		<?php 
    			if (getOption('Allow_search')) {  
    				printSearchForm("","search","",gettext("Search gallery")); 
    			} 
    		?>
    		<?php if (hasPrevImage()) { ?>
    			<a href="<?php echo html_encode(getPrevImageURL());?>" title="<?php echo gettext("Previous Image"); ?>"><?php echo gettext("prev"); ?></a>
    		<?php } if (hasNextImage()) { ?>
    			<a href="<?php echo html_encode(getNextImageURL());?>" title="<?php echo gettext("Next Image"); ?>"><?php echo gettext("next"); ?></a>
    		<?php } ?>
    		<?php printHomeLink('', ' | '); ?><a href="<?php echo html_encode(getGalleryIndexURL());?>" title="<?php gettext('Albums Index'); ?>"><?php echo getGalleryTitle();?></a> | <?php printParentBreadcrumb("", " | ", " | "); printAlbumBreadcrumb("", " | "); ?><?php printImageTitle(true); ?>
    		<a href="<?php echo html_encode($fullimage);?>" title="<?php echo getBareImageTitle();?>">		
    			<?php printDefaultSizedImage(getImageTitle()); ?>
    		</a>
    		<?php printImageDesc(); ?>
    		<?php
    			if (getImageMetaData()) { 
    				printImageMetadata('', false); ;
    			}
    		?>
    		<?php printTags('links', gettext('<strong>Tags:</strong>').' ', 'taglist', ''); ?>
    		<?php printRSSLink('Gallery','','RSS', ' | '); ?>
    		<?php printZenphotoLink(); ?>
    		<?php 
    			printAdminToolbox();
    			zp_apply_filter('theme_body_close');
    		?>
    	</body>
    </html>
    
    search.php

    This is the last of the actual required theme page. It's actually nearly the same as the album.php since it does displaying albums and image. But this time the search results and not fixed albums.

    <?php
    	// force UTF-8
    	if (!defined('WEBPATH')) die();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<?php zp_apply_filter('theme_head'); ?>
    		<title><?php echo getBareGalleryTitle(); ?> | <?php echo gettext("Search"); ?></title>
    		<meta http-equiv="content-type" content="text/html; charset=<?php echo LOCAL_CHARSET; ?>" />
    		<link rel="stylesheet" href="<?php echo $_zp_themeroot; ?>/style.css" type="text/css" />
    		<?php printRSSHeaderLink('Gallery',gettext('Gallery RSS')); ?>
    	</head>
    	<body>
    		<?php 
    			zp_apply_filter('theme_body_open'); 
    			$total = getNumImages() + getNumAlbums();
    			if (!$total) {
    				$_zp_current_search->clearSearchWords();
    			}
    		?>
    		<?php printHomeLink('', ' | '); ?><a href="<?php echo html_encode(getGalleryIndexURL());?>" title="<?php echo ('Gallery Index'); ?>"><?php echo getGalleryTitle();?></a> | <?php echo gettext("Search");?>		
    		<?php printSearchForm("","search","",gettext("Search gallery")); ?>
    		<?php
    			if (($total = getNumImages() + getNumAlbums()) > 0) {
    				if (isset($_REQUEST['date'])){
    					$searchwords = getSearchDate();
     				} else { $searchwords = getSearchWords(); }
    					echo sprintf(gettext('Total matches for <em></em>: %2$u'), html_encode($searchwords), $total);
    			}
    			$c = 0;
    		?>
    		<?php while (next_album()): $c++;?>
    			<a href="<?php echo html_encode(getAlbumLinkURL());?>" title="<?php echo gettext('View album:'); ?> <?php echo getAnnotatedAlbumTitle();?>"><?php printAlbumThumbImage(getAnnotatedAlbumTitle()); ?></a>
    			<a href="<?php echo html_encode(getAlbumLinkURL());?>" title="<?php echo gettext('View album:'); ?> <?php echo getAnnotatedAlbumTitle();?>"><?php printAlbumTitle(); ?></a>
    			<?php printAlbumDate(""); ?>
    			<?php printAlbumDesc(); ?>
    		<?php endwhile; ?>
    		<?php while (next_image()): $c++;?>
    			<a href="<?php echo html_encode(getImageLinkURL());?>" title="<?php echo getBareImageTitle();?>"><?php printImageThumb(getAnnotatedImageTitle()); ?></a>
    			</div>
    		<?php endwhile; ?>
    		<?php 
    			if ($c == 0) {
    				echo gettext("Sorry, no image matches found. Try refining your search.");
    			}
    		?>
    		<?php printPageListWithNav("« ".gettext("prev"), gettext("next")." »"); ?>
    		<?php printTags('links', gettext('<strong>Tags:</strong>').' ', 'taglist', ''); ?>
    		<?php printRSSLink('Gallery','','RSS', ' | '); ?>
    		<?php printZenphotoLink(); ?>
    		<?php 
    			printAdminToolbox();
    			zp_apply_filter('theme_body_close');
    		?>
    	</body>
    </html>
    
    Adding the comments section

    You can add comments to album.php and image.php. Additionally also to Zenpage's pages.php and news.php.

    Since Zenphoto 1.2.6 the comment handling code has been transfered to the comment_form plugin. All you need to do is to enable that plugin and put this code where you want the comment form and the comment display.

    <?php
    	if (function_exists('printCommentForm')) { ?>
    		printCommentForm();  
    	} 
    ?>
    

    You can of course modify the look of the comment section via CSS or you could even make your own comment form by changing the file zp-core/plugins/comment_form/comment_form.php.

    Part 3: Advanced Theme Functionality

    This part of our tutorial is about the more advanced functionalitly you can add to your theme.

    Custom pages with the example of archive.php and slideshow.php

    "Custom pages" 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

    zenphoto/index.php?p=pagetitle (non mod_rewrite)

    or

    zenphoto/page/pagetitle (mod_rewrite)

    In general a custom page is just like index.php but with the album loop removed. These pages can be used as an "about" or "references" 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.)

    You can use some of the more general theme functions as archive.php does.

    Archive.php is used to display links that organize your images by month & year, and a tag cloud of the most used tags:

    <?php if (!checkForPassword()) {?>
    <div id="archive"><?php printAllDates(); ?></div>
    <div id="tag_cloud"> <p>Popular Tags</p>
    <?php printAllTagsAs('cloud', 'tags'); ?> </div> <?php } ?>


    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

    <?php printSlideShow(); ?>
    Separation of the gallery and the index page

    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 custom index page. If you have an existing zenphoto gallery the easiest way to accomplish this task is to rename your current theme index.php script to something else, say gallery.php. Create your new index.php script to introduce your site. Include on it a link to http://yoursite.com/zenphoto/page/gallery (assuming you named your old index file gallery.php and you installed zenphoto in the folder zenphoto). Set the custom index page option to gallery and your are all set.

    Custom functions

    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's folder. Name this theme file functions.php and it will be loaded automatically on every theme page to make the custom functions available.

    Theme options


    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 themeoptions.php which is located in your theme folder. The file is optional, if you have no options you need not have themeoptions.php. Theme options are one class of Zenphoto plugins. Plugins are described here. You define the options in this code and make use of them in your theme by calling the function getOption() passing the option name. (It is a good idea to be sure any unique options you create have unique names so that they don't conflict with options some other theme builder might have made.)

    Some of the 'standard' theme options (as defined by the distributed themes) are: 'Allow_comments', 'Allow_search', and 'Theme_colors'. 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.

    Themeoptions are a class of Zenphoto Plugin so reading about the plugin architecture might also be of some value.

    Overriding options for special theme effects

    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.)

    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 setOption() function of zenphoto has provided a means to temporarily change an option without updating the options database. There is a third parameter the the setOption() function, $persistent, which is defaulted to true. Passing false to this parameter tells setOption() to change the value of the option in memory but not in the database.

    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.

    Special images

    Zenphoto has several special images that a theme can replace it it wished. These are:

    • imageDefault.png which is used for album thumbnails when there are no images in the album.
    • multimediaDefault.png which is the default image for video thumbnails.
    • err-passwordprotected.gif 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.

    A theme can override the images that come with Zenphoto by placing a same named image in a folder named images within the theme folder.

    Special scripts

    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.

    404.php: 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.

    password.php (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 if (!checkforPassword(true) { } block around content you wish hidden on password protected pages.

    With the 1.2.6 release you can instead create a password.php 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.

    Separate theme translations (post 1.2)

    If you provide a theme as a third party, its translation is naturally not included with Zenphoto’s general translation file. Zenphoto uses gettext for translations of literal strings on your theme.

    Please visit the translating tutorial for more detailed information on how to setup your theme for theme translations and how gettext translation works in general.

    Sophisticated theme design

    Zenphoto is actually not limited to the already described standard theme way. Besides the fact that all template functions have a "print" variant that prints a full convenient HTML setup there is also (nearly) always a "get" variant that just returns raw data (strings, objects, array etc.) to build customized functions for special needs.

    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.

    See the object model framework tutorial and the functions documentation for more details.

    Part 4: Theming Zenpage

    Zenpage theme basics

    This part will give you only a basic overview how to setup your theme for the CMS plugin Zenpage. 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.

    Zenpage hooks on Zenphoto's custom page feature and therefore requires two new custom pages to be available with your theme folder: pages.php and news.php. 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.

    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 pages.php and news.php to work correctly.

    pages.php

    This theme page is the simplest of the both since it will only show one page at the time, so we start with it:

    <?php
    	// force UTF-8
    	if (!defined('WEBPATH')) die();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<?php zp_apply_filter('theme_head'); ?>
    		<title><?php if(!isset($ishomepage)) { echo getBarePageTitle(); } ?> | <?php echo getBareGalleryTitle(); ?></title>
    		<meta http-equiv="content-type" content="text/html; charset=<?php echo LOCAL_CHARSET; ?>" />
    		<link rel="stylesheet" href="<?php echo $_zp_themeroot; ?>/style.css" type="text/css" />
    		<?php printZenpageRSSHeaderLink("Pages","", "Zenpage news", ""); ?>
    	</head>
    	<body>
    		<?php zp_apply_filter('theme_body_open'); ?>
    		<?php printHomeLink('', ' | '); ?><a href="<?php echo html_encode(getGalleryIndexURL());?>" title="<?php echo ('Gallery Index'); ?>"><?php echo getGalleryTitle();?></a> | <?php printZenpageItemsBreadcrumb(" » ",""); ?>
    		<?php 	
    			if (getOption('Allow_search')) { 
    				printSearchForm("","search","",gettext("Search gallery")); 
    			} 
    		?>
    		<?php printPageTitle(); ?>		
    		<?php printPageContent(); ?>
    		<?php	printTags('links', gettext('<strong>Tags:</strong>').' ', 'taglist', ', ');	?>
    		<?php printRSSLink('Gallery','','RSS', ' | '); ?>
    		<?php printZenpageRSSLink("News","","",gettext("News"),''); ?>
    		<?php 
    			printAdminToolbox();
    			zp_apply_filter('theme_body_close');
    		?>
    	</body>
    </html>
    
    news.php

    This page is a little more complicated because it shows either the single news article and the news loop. The general structure is single news articles or news loop.

    <?php
    	// force UTF-8 
    	if (!defined('WEBPATH')) die();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<title><?php echo gettext("News"); ?> <?php echo getBareNewsTitle(""); ?><?php printCurrentNewsCategory(" | "); printCurrentNewsArchive(); ?> | <?php echo getBareGalleryTitle(); ?></title>
    		<meta http-equiv="content-type" content="text/html; charset=<?php echo LOCAL_CHARSET; ?>" />
    		<link rel="stylesheet" href="<?php echo $_zp_themeroot; ?>/style.css" type="text/css" />
    		<?php printZenpageRSSHeaderLink("News","", "Zenpage news", ""); ?>
    		<?php zp_apply_filter('theme_head'); ?>
    	</head>
    	<body>
    		<?php zp_apply_filter('theme_body_open'); ?>
    		<?php printHomeLink('', ' | '); ?><a href="<?php echo getGalleryIndexURL(false); ?>"><?php echo gettext("Index"); ?></a> <?php printNewsIndexURL(gettext('News'),' » '); ?><strong><?php printZenpageItemsBreadcrumb(' » ',''); printCurrentNewsCategory(" » "); ?><?php printNewsTitle(" » "); printCurrentNewsArchive(" » "); ?>
    		<?php 	
    			if (getOption('Allow_search')) { 
    				printSearchForm("","search","",gettext("Search gallery")); 
    			} 
    		?>
    		<?php 
    		if(is_NewsArticle()) { // single news article
      		if(getPrevNewsURL()) { 
      			printPrevNewsLink(); 
      		} 
      		if(getNextNewsURL()) { 
      			printNextNewsLink(); 
      		} 
      		printNewsTitle(); 
      		printNewsDate();
      		printNewsCategories(", ",gettext("Categories: "),"newscategories"); ?>
    			printNewsContent(); 
    			printTags('links', gettext('<strong>Tags:</strong>').' ', 'taglist', ', '); 		
    		} else { // news article loop
    			while (next_news()): ;?>
     				printNewsTitleLink(); 
     				printNewsDate();
    				if(is_GalleryNewsType()) { //required for Zenpage's CombiNews mode
    					if(!is_NewsType("album")) {
    						echo " | ".gettext("Album:")."<a href='".getNewsAlbumURL()."' title='".getBareNewsAlbumTitle()."'> ".getNewsAlbumTitle()."</a>";
    					} 
    				} else {
    					echo ' | '; printNewsCategories(", ",gettext("Categories: "),"newscategories");
    				}
    				printNewsContent();
       			printTags('links', gettext('<strong>Tags:</strong>').' ', 'taglist', ', '); 
     			endwhile;
     			printNewsPageListWithNav(gettext('next »'), gettext('« prev'),true,'pagelist',true);
    		} 
    		?>
    		<?php printRSSLink('Gallery','','RSS', ' | '); ?>
    		<?php printZenpageRSSLink("News","","",gettext("News"),''); ?>
    		<?php 
    			printAdminToolbox();
    			zp_apply_filter('theme_body_close');
    		?>
    	</body>
    </html>
    
    Adding search results for Zenpage items on search.php

    Adding search results to a search page is actually a little more complicated and may look a little confusing first. Search results for Zenpage news articles and pages are not paginated and only shown on the first search results page.

    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:

    <?php
    // force UTF-8 Ø
    if (!defined('WEBPATH')) die();
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    	<head>
    		<?php zp_apply_filter('theme_head'); ?>
    		<title><?php echo getBareGalleryTitle(); ?> | <?php echo gettext("Search"); ?></title>
    		<meta http-equiv="content-type" content="text/html; charset=<?php echo LOCAL_CHARSET; ?>" />
    		<link rel="stylesheet" href="<?php echo $_zp_themeroot; ?>/style.css" type="text/css" />
    		<?php printRSSHeaderLink('Gallery',gettext('Gallery RSS')); ?>
    	</head>
    	<body>
    		<?php zp_apply_filter('theme_body_open'); ?>
    		<?php printGalleryTitle(); ?>
    		<?php
    		$zenpage = getOption('zp_plugin_zenpage');
    		$numimages = getNumImages();
    		$numalbums = getNumAlbums();
    		$total = $numimages + $numalbums;
    		if ($zenpage && !isArchive()) {
    			$numpages = getNumPages();
    			$numnews = getNumNews();
    			$total = $total + $numnews + $numpages;
    		} else {
    			$numpages = $numnews = 0;
    		}
    		if ($total == 0) {
    			$_zp_current_search->clearSearchWords();
    		}
    		if (getOption('Allow_search')) {
    			// this is special code to allow category specific searches+results. It is actually optional.
    			$categorylist = $_zp_current_search->getCategoryList();
    			if (is_array($categorylist)) {
    				$catlist = array('news'=>$categorylist,'albums'=>'0','images'=>'0','pages'=>'0');
    				printSearchForm(NULL, 'search', NULL, gettext('Search category'), NULL, NULL, $catlist);
    			} else {
    				// this is special code to allow album specific searches+results. It is actually optional.
    				$albumlist = $_zp_current_search->getAlbumList(); // this is special code to allow category specific searches+results
    				if (is_array($albumlist)) {
    					$album_list = array('albums'=>$albumlist,'pages'=>'0', 'news'=>'0');
    					printSearchForm(NULL, 'search', NULL, gettext('Search album'), NULL, NULL, $album_list);
    				} else {
    					// this part is the only required part
    					printSearchForm("","search","",gettext("Search gallery"));
    				}
    			}
    		}
    		?>
    		<a href="<?php echo getGalleryIndexURL(false);?>" title="<?php gettext('Index'); ?>"><?php echo gettext("Index"); ?></a> » <?php echo "<strong>".gettext("Search")."</strong>";	?>
    		<?php
    		$searchwords = getSearchWords();
    		$searchdate = getSearchDate();
    		if (!empty($searchdate)) {
    			if (!empty($searchwords)) {
    				$searchwords .= ": ";
    			}
    			$searchwords .= $searchdate;
    		}
    		if ($total > 0 ) {
    			printf(ngettext('%1$u Hit for <em></em>','%1$u Hits for <em></em>',$total), $total, html_encode($searchwords));
    		}
    		if ($_zp_page == 1) { //test of zenpage searches
    			if ($numpages > 0) {
    				$number_to_show = 5;
    				$c = 0;
    				printf(gettext('Pages (%s)'),$numpages); printZDSearchShowMoreLink("pages",$number_to_show);
    				while (next_page()) {
    					$c++;
    					printZDToggleClass('pages',$c,$number_to_show); 
    					printPageTitlelink();
    					shortenContent(strip_tags(getPageContent()),80,getOption("zenpage_textshorten_indicator"));
    				}
    			}
    			if ($numnews > 0) {
    				$number_to_show = 5;
    				$c = 0;
    				printf(gettext('Articles (%s)'),$numnews); printZDSearchShowMoreLink("news",$number_to_show); 
    				while (next_news()) {
    					printNewsTitleLink();
    					echo shortenContent(strip_tags(getNewsContent()),80,getOption("zenpage_textshorten_indicator"));
    				}
    			}
    		}
    		if (getOption('search_no_albums')) {
    			if (!getOption('search_no_images') && ($numpages + $numnews) > 0) {
    				printf(gettext('Images (%s)'),$numimages);
    			}
    		} else {
    			if (getOption('search_no_images')) {
    				if (($numpages + $numnews) > 0) {
    					printf(gettext('Albums (%s)'),$numalbums);
    				}
    			} else {
    				printf(gettext('Albums () & Images ()'),$numalbums,$numimages);
    			}
    		}
    		if (getNumAlbums() != 0) { 
    			while (next_album()): ?>
    				<a href="<?php echo html_encode(getAlbumLinkURL());?>" title="<?php echo gettext('View album:'); ?> <?php echo getBareAlbumTitle();?>"><?php printCustomAlbumThumbImage(getBareAlbumTitle(), NULL, 95, 95, 95, 95); ?></a>
     				<a href="<?php echo html_encode(getAlbumLinkURL());?>" title="<?php echo gettext('View album:'); ?> <?php echo getBareAlbumTitle();?>"><?php printAlbumTitle(); ?></a>
     				<?php 
     				printAlbumDate(""); 
     				echo truncate_string(getAlbumDesc(), 45); 
     			endwhile; 
     		} 
     		if (getNumImages() > 0) {
     			while (next_image()) { ?>
    				<a href="<?php echo html_encode(getImageLinkURL());?>" title="<?php echo getBareImageTitle();?>"><?php printImageThumb(getBareImageTitle()); ?></a>
    				<?php 
    			} 
    		} 
    		if ($total == 0) {
    			echo "<p>".gettext("Sorry, no matches found. Try refining your search.")."</p>";
    		}
    		printPageListWithNav("« ".gettext("prev"),gettext("next")." »");
    		printAdminToolbox();
    		zp_apply_filter('theme_body_close');
    		?>
    	</body>
    </html>
    
    News on index.php

    This option allows to turn the theme index.php into the first page of the news section (all further ones will be displayed on news.php). All you have to do to use this is to copy the complete next_news() loop to your index.php.

    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't limit this.

    Alternatively you could also skip albums on index.php and use the printAlbumMenu() plugin to access them instead.

    Showing Zenpage content on other theme pages

    You can use the get/printPageContent(), get/printExtraContent() and get/printCodeblock() functions to show published or unpublished pages' content, extracontent or codeblocks elsewhere. More info about these functions' parameters on the documentation.

    If you need more fields like author or date, you probably should do this with the class object directly:

    $page = new ZenpagePage("");


    Then you can call each field with<!--?php echo $page--->getId(); ?> for example. Note that the title, content and extracontent fields support the multi-lingual feature, so that they need to be called like this:

    <?php $title = get_language_string($page->getTitle()); ?>


    Of course this works similar for news articles, too. For more info about the Zenpage object methods please see the the object model framework tutorial and the functions documentation.

    The CombiNews feature

    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.

    But you have some additional functions to use with them. For example there is:

    <?php is_GalleryNewsType(); ?>

    This will check if the entry is a news article or an image or a movie. More detailed info on the functions guide.

    Since images, movies or audio files do not have categories, but albums you can show this, too:

    <?php echo getNewsAlbumTitle(); ?>

    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.

    Download of example theme files

    1. basic-theme-files.zip (4.26 kB)
    2. basic-theme-files-zenpage-extra.zip (3.98 kB)

    Creative Commons LicenseThis work by www.zenphoto.org is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

    For questions and comments please use the forum or discuss on the social networks.

    Related items