Docstoc

CAMPSITE

Document Sample
CAMPSITE Powered By Docstoc
					CAMPSITE




 Published : 2011-03-22
 License : None

INTRODUCTION

                          1
1. Campsite for Editors and Journalists
2. What's New
3. Feature List




2
1. CAMPSITE FOR EDITORS AND
JOURNALISTS
Campsite is a multi-lingual enterprise content management system for on-line newspapers and
magazines, enabling scheduled publishing of multimedia. Built-in revenue generation features
include support for both trial and paid reader subscriptions. The interface is built with the
journalist, editor and publisher in mind, based on feedback from the news organizations around
the world that have deployed the software since the launch of the first version in 1999.
Campsite follows a print publishing model, so it structures websites as Publications, Issues,
Sections and Articles by default. Campsite was designed for medium-to-large on-line publications,
but it is capable of handling nimbler sites too.




With Campsite, you can edit articles using an advanced WYSIWYG interface, and manage articles
translated into different languages. A traditional editorial process ensures quality of content: the
journalist writes the article, the editor reviews the content, and then the article can be
published. The Campsite editorial interface works in most modern web browsers, including Mozilla
Firefox and Microsoft Internet Explorer. No browser plug-ins are necessary.




                                                                                                       3
You can also create your own definition of what a particular type of article should include. For
example, one article type might consist of "Intro", "Body", and "References", while another type
might include only "Body" and "Author Bio". You can incorporate images, audio and video into
your articles, for delivery directly in the browser window or as attachments for download.
Articles can be categorized with topics, and scheduled for release at a future date, or published
immediately.

Campsite offers full control over the look and feel of your web site via a flexible HTML5 and
CSS3 ready templating engine. The PHP object-oriented API enables your website developers to
build third-party plug-ins too. Built-in support for translation allows the user interface to be
adapted to support new languages quickly and easily.

Managers will appreciate the fine-grained access control for different types of staff users,
including journalists, editors, and subscription managers. Integrated revenue-generating features
include IP-based access control for paid group subscriptions.

Campsite is Open Source software released by Sourcefabric under the GNU General Public
License. It incorporates TinyMCE from Moxiecode Systems AB as its WYSIWYG text editor,
Christophe Dolivet's EditArea as a template editor, and PhotoViewer by Joseph Nicora for
thumbnail zooming.




4
2. WHAT'S NEW
Major upgrades to Campsite are noted by changing the second digit of the version number.
Minor bug fix releases are indicated by changing the third digit (e.g. Major release: 3.3 -> 3.4,
minor release: 3.4.1 -> 3.4.2).

Coming soon in version 3.5:

      Custom sorting in the article images list

What's new in version 3.4 "Luca":

      Image thumbnails scalable by pixel width and height on the fly, scaled versions are cached
      for faster display
      Installation of Campsite in sub-folders possible (e.g. http://domain/campsite/)
      Translate article types and display the names in the templates
      Create a custom 404 error page for pages not found
      Administrator content search
      Universal, customizable list of content for administrators and journalists
      Search engine optimization now allows to add any combination of article elements and
      topics in the URL
      Timezone handling optionally overrides server timezone
      Backup and restore controlled via the administrator interface. No shell access required

What's new in version 3.3 "Speedy":

      A major optimization of the code took place; all objects used in the template engine are
      cached now
      New article-field types: switch and numeric
      Better log of all back-end activity
      Pluggable caching mechanism
      Better on-line template editor (Editarea)
      Global setting for resizing images inserted via the TinyMCE editor
      Upgrade of the TinyMCE editor to the latest stable version, with a completely rewritten
      Paste from Word plugin
      New section delete options
      Enhancements to the Article Type management screens
      Improved management of user permissions
      Usability improvements to the Localizer (progress indicator and highlights to string groups
      needing attention

What's new in version 3.2 "David":

      Use Ajax to save article screen
      Swap out Xinha for TinyMCE
      Advanced article search
      Ajaxization of WYSIWYG editor
      Article Statistics: Most Commented
      Plugin localizer
      Password strength meter and automatic strong password generator
      Implementation of a blog plugin
      Improvements to the plugins API
      Rewrite the article statistics API to work in real time
      Add static Author field

What's new in version 3.1 "Tomás":




                                                                                                    5
      Implemented a cron jobs installer
      Implemented "all_subtitles" attribute for the article body fields display
      Implemented "topics_count" and "has_topics" attributes for the article object
      Improved the code handling the image upload, not to leave garbage in case of error
      Implemented special values for date, time and date/time types
      Implemented section based permissions for staff users
      Implemented "most read" articles statistics
      Show number of articles in each section screen
      Implemented the first step of the plugins API
      Implement a method to upgrade the database on new install
      Bug fixes

What's new in version 3.0 "Filip":

      The template engine was rewritten in PHP for better performance, more flexibility, easier
      development, plugin architecture, fewer dependencies and easy install
      The install procedure is much easier thanks to a web base installer
      A caching mechanism for database objects was implemented. This will result in fewer
      database queries and greater speed and scalability




6
3. FEATURE LIST
This list of features is provided as a guide to help you decide if Campsite is the right content
management system for your publication.

LANGUAGES
The Campsite administration interface has been translated into the following languages (in
alphabetical order):

    1.   Arabic
   2.    Belarusian
   3.    Chinese (Simplified)
   4.    Chinese (Traditional)
   5.    Croatian
   6.    Czech
    7.   Dutch
   8.    English
   9.    French
 10.     Georgian
   11.   German
  12.    Korean
  13.    Polish
  14.    Portuguese
  15.    Romanian
 16.     Russian
  17.    Serbian (Cyrillic)
 18.     Serbo-Croatian (Latin)
 19.     Spanish
 20.     Swedish

Further translations can be added using a tool built into Campsite called the "Localizer".

CONTENT FEATURES
   1. Multi-lingual content: all of the content that you create in Campsite can be translated:

         Articles
         Sections
         Issues
         Publications
         Topics (content categorization)
         File attachment descriptions

  Online WYSIWYG editor for article editing:

         Typical style formatting: bold, italic, etc.
         Special support for linking to existing (internal) articles
         Ability to split articles into multiple pages
         Insert images into your articles
         Copy & Paste clean text from Microsoft Word or OpenOffice.org (while preserving bold and
         italics)
         Insert subtitles, which can be used for breaking up the article (->pagination)

  Built with multiple simultaneous users in mind

         While a journalist is editing an article, it is "locked". A warning will be displayed if anyone
         else tries to edit the article at the same time. This prevents one journalist from deleting
         the work of another

                                                                                                           7
  Group articles into sections
  Group sections into an issue
  Release an issue all at once
  Allow subscribers to access only certain issues
  Scheduled Publishing: automatically publish articles or issues at some time in the future. For
articles, you can schedule the following actions:

       publish
       unpublish
       show the article on the front page
       remove the article from front page
       show the article on the section page
       remove the article from the section page

    Topics: Categorize your content

       Define however many topics you like
       Associate any number of topics to an article
       Topic can have subtopics, subtopics can have sub-subtopics, etc.
       Topics can be translated

    Dynamic, Flexible Article Types

       "Article Types" allow you to define your own article format - you aren't limited to just
       "Introduction" and "Body" fields, for instance. An Article Type consists of a series of data
       fields
       You can define any number and combination of the following field types:
              date field
              single-line text field
              multiple-line text field with WYSIWYG editor
              drop-down selection containing a list of topics
       Reorder how the fields are displayed in the admin interface
       Hide fields that are no longer in use
       Translate the field names
       Change the data type for a field

    Image Manager

       View/search all of the images in the system
       Edit image metadata
       Scale images any way you want on the fly. Scaled versions are cached

    File Attachments

       Attach files to articles
       Files can have descriptions
       You can specify whether the file should be displayed in the browser or popup a download
       window

    Comments

       Readers can make comments to articles
       Comments can be linked to a forum
       Flexible implementation: allow anyone to comment, just subscribers, logged in
       Comments can be moderated
       Built-in CAPTCHA for spam prevention

    Works with SSL on both the front-end and back-end

SUBSCRIBER MANAGEMENT
    1. Control access to your content via:


8
     User's IP Address (for corporate accounts)
     Login/password (individual users)

  Control what content your subscribers have access to:

     The entire issue
     Specific sections in each issue
     Specific sections in a particular language

  Ability to have a trial subscription period
  Set your own pay periods (the time between each payment made by a subscriber)

SITE DESIGN
Campsite has its own template language specifically made for online newspapers and
magazines. It allows you to customize your site however you want.

     You have access to the following data objects:
           publications
           issues
           sections
           articles
           topics
           current user
           current language (e.g. automatically show the user an article in their language)
     Control statements such as IF and LIST
     Include other templates

     Built on the SMARTY templating engine which allows easy customization and inclusion of
     third party modules

ADMINISTRATION
  1. Fine-grained access control, you can create different user types such as:

     journalists
     editors
     photographers
     photo editors
     subscriber managers
     site administrators

  Logging

     All administration actions are logged

  Security

     Login page secured against automated scripting attacks with a CAPTCHA
     Login password is encrypted when sent to the server

  Backup

     Command-line "backup" and "restore" scripts make it easy to backup your entire site and
     restore it with one command
     You can also easily transfer your site from one server to another using these scripts

  Automated Feedback and Bug Reporting

     If something goes wrong in the administration interface, a special screen will appear which
     allows you to submit the problem back to the Campsite team
     You can also submit feedback directly in the admin interface, such as suggestions or
     feature requests

                                                                                                   9
DEVELOPERS
     Completely open-source LAMP development stack (Linux, Apache, MySQL, and PHP)
     Easy to use object-oriented API to develop plugins or alternative interfaces
     Easy-to-read code
     Open development process - all planning, specs, and reviews are done in the open.
     Developing Campsite is a community process

SUPPORT
     Paid per-incident support is available from Sourcefabric (http://www.sourcefabric.org).
     Guaranteed support contracts ensure a 24-hour response time
     If you need additional features in Campsite, they can be ordered from Sourcefabric at a
     very reasonable cost and delivered in a timely manner
     Sourcefabric has a team of full-time developers working to make Campsite easier to use,
     with the features you want
     Community support is available via mailing lists and forums (http://forum.sourcefabric.org)

INSTALLATION
4. Requirements and Dependencies
5. Installation Steps
6. Backup & Restore
7. Installing the Demo Templates
8. Installing on Ubuntu
9. Installing Campsite from Debian packages
10. Installing Campsite on Windows Vista
11. Installing Campsite on Mac OS X
12. Installing Campsite on FreeBSD
13. Installing Campsite on PHP-CGI shared hosts
14. Automated tasks
15. Setting up a Campsite Replication Server




10
4. REQUIREMENTS AND DEPENDENCIES
In this chapter:

      Debian Dependencies
      Ubuntu Dependencies

To install the Campsite server, you need to have shell or ftp access to a Linux, FreeBSD or Unix
system. Campsite 3.2 is known to work on the following Linux distributions: Ubuntu, Fedora,
Mandriva, Debian.


Before installing Campsite, make sure you have the following applications up and running:

1. Apache web server -- your http daemon, serving your web site to the world
(http://www.apache.org). You will need version 2.0.x or newer.

For installation instructions, see the Apache web site. Installing Apache will generate the
httpd.conf file referred to further down. This file contains all relevant information for Apache to
handle the content on your Linux server. The adjustments described below need to be made in
order to tell Apache about the procedures for Campsite files and templates.

2. MySQL Database Server - this application handles the Campsite database. You will need
MySQL 5.0 or newer.

Two components of MySQL are needed for Campsite:
 * the server
 * client programs

All of those can be found on the MySQL website (http://www.mysql.com).

3. PHP 5.0 or newer - This is needed for Campsite administration interface. PHP is a module for
the Apache web server. The followind PHP modules must be installed:

      * php-cli - Command Line Interface module
      * php-mysql - functions for accessing the MySQL database server
      * php-gd - provides a module for handling graphics directly from the PHP scripts

4. Imagemagick - needed for creating thumbnails of images




DEBIAN DEPENDENCIES
To install and configure all needed Debian 3.1 libraries run the following command at your
command prompt:
apt-get install libdbd-mysql-perl mysql-client mysql-common
 mysql-server php5-mysql php5-cli php5-gd imagemagick




UBUNTU DEPENDENCIES
To install and configure all needed Ubuntu libraries run the following command at your command
prompt (by copying and pasting it into your terminal):

sudo apt-get install build-essential php5-cli php5-mysql
 apache2 libapache2-mod-php5 php5 mysql-server
 imagemagick php5-gd
                                                                                                      11
The file in php.ini may need to be reconfigured for the extensions mysql.so and gd.so. To do this
open up the file /etc/php5/apache2/php.ini and find the lines:

extension=mysql.so
extension=gd.so

If these two lines are commented out (ie proceded by semicolons), uncomment them by
removing the semicolons.




12
5. INSTALLATION STEPS
In this chapter:

       Downloading Campsite
       Configuring Apache
       Setup your php.ini file
       Upgrading
       Advanced/non-standard installation
       Troubleshooting

Here is what you need to do to install Campsite:

  1. Configure apache: create an apache virtual host (optional)
  2. Setup your php.ini file
  3. Copy the Campsite package to a directory on your server.
  4. Unarchive it using the command: tar xzvf <Campsite_source>.
  5. Enter Campsite directory: "cd campsite".
  6. Copy the content of implementation/site directory into the document root directory of the
     apache virtual host.
  7. Start a browser, point it to the                  URL and follow the steps.




DOWNLOADING CAMPSITE
The easiest way to download Campsite is to go to our Sourceforge page and download the files
direct from there.



CONFIGURING APACHE
Create an apache virtual host or use the default apache virtual host. You may skip this step if
you wanted to use the apache default host (localhost). Campsite does not work in subdirectories.
So you can not work with a local URL like http://localhost/campsite/ - if this is what you want to
do, read the hosts part beyond the apache configuration.

Example of virtual host configuration:
<VirtualHost *>
    DocumentRoot /var/www/campsite

    ServerName [site_name]
    ServerAlias [site_alias]
    DirectoryIndex index.php index.html
    <Directory /var/www/campsite>
            Options -Indexes FollowSymLinks MultiViews
            AllowOverride All
            <IfModule mod_access>
                 Order allow,deny
                 Allow from all
            </IfModule>
    </Directory>
</VirtualHost>

After you create a virtual host do not forget to restart apache.

Enabling the rewrite module under Ubuntu

If you are working on Ubuntu, trying to add the RewriteModule into the apache configuration
might create the following error:

Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the
server configuration

                                                                                                     13
In which case you need to enable mod_rewrite. Do this by opening a terminal and type:
sudo a2enmod rewrite

You will see in the terminal: Enabling module rewrite. Run '/etc/init.d/apache2 restart' to activate
new configuration!

Working on localhost: changing hosts file

If you installed campsite locally, e.g. http://localhost/campsite/, you need to change the hosts file
( sudo vim /etc/hosts ) and duplicate the line which says localhost, adding your [site_name] from
the apache conf (see above) there. If you used "campsite" as the [site_name], your hosts file
might start like this (Ubuntu 9.10 example):
127.0.0.1       localhost
127.0.0.1       campsite
# The following lines are desirable for IPv6 capable hosts

Now you can point your browser to http://campsite

SETUP YOUR PHP.INI FILE
You will need to adjust values in your php.ini file in order for Campsite to work properly. ⁞ On
Debian and Ubuntu systems, your "php.ini" file is usually located in "/etc/php5/apache2"
directory.

The following directives show what the values should be for each variable in the php.ini file.

Always turn off register_globals because it's a big security hole:
register_globals = Off

Find the "memory_limit" directive and set the amount of memory to at least 32MB:
memory_limit = 32M

Set maximum size of POST data that PHP will accept to a hig value:
post_max_size = 100M

Turn off magic quotes:
magic_quotes_gpc = Off

Allow HTTP file uploads:
file_uploads = On

Set the maximum allowed size for uploaded files to a large value so you will be able to upload
large attachments:
upload_max_filesize = 100M

Make sure the following extensions are enabled (they are enabled as long the line appears in the
php.ini file, and the line does not start with a semi-colon (';')):
extension=gd.so
extension=mysqli.so
extension=mysql.so




UPGRADING
In this section:

      Compatibility Issues




14
Upgrading from versions 1.x, 2.0.x, 2.1.x, 2.2.x, 2.3.x, 2.4.x and
2.5.x is not supported anymore. You will have to upgrade first to
Campsite 2.6 or 2.7 and then follow the regular procedure.

Upgrading from Campsite 2.6.x and 2.7.x versions:
Repeat the following steps for each instance:

  1. Backup the instance using campsite-backup-instance
  2. Perform a new Campsite 3.3 install
  3. Run the restore backup script from the admin interface

Read INSTALL file and follow the steps; read on Compatibility issues.

Upgrading from Campsite 3.0.x, 3.1.x and 3.2.x:

Drop the new sources over the existing install, open a browser
and make a request for the publication home page:
The upgrade will be performed automatically when you make the first
request to the publication site or to the Campsite admin interface.



Compatibility Issues

Since version 3.0 Campsite doesn't support multiple instances anymore. You will have to perform
one install for each Campsite instance. However, the install procedure was greatly simplified.

In version 3.0 the template language as modified extensively. The backup restore script will
provide an automated conversion of the old template files to the new format. For more details
on language changes please read the chapter "Template Language Version 3.0".

The 3.3 template language is fully backward compatible with versions 3.2, 3.1 and 3.0. The 3.3
version only brings additions to the language.




ADVANCED/NON-STANDARD INSTALLATION
In this section:

      Installing Campsite under Plesk
      Configuring Campsite to Work Over SSL



Installing Campsite under Plesk

To install Campsite under the Plesk control panel, follow the instructions in this wiki:

http://wiki.sourcefabric.org/display/CS/Install+Campsite+Under+Plesk



Configuring Campsite to Work Over SSL

This article will explain how to configure apache over an encrypted SSL connection.




                                                                                                  15
     1. Allocate a separate IP address for each Campsite installation you want to run over SSL.
        You will have to set this IP address to one of your server network interfaces. We don't
        provide detailed information about network interface configuration process here because
        it's outside the scope of Campsite. Read 'ifconfig' manual page for more details, search for
        configuring network interfaces on linux on Google or try this link:
        http://www.faqs.org/docs/linux_network/x-087-2-iface.html. We will refer to this IP address
        as [my_IP_address] in the following steps.

     2. Locate the Listen directive in the main apache configuration file and add the following new
        lines after it if they did not exist already:

        Listen 80

        Listen 443

     3. Locate the NameVirtualHost directive in the main apache configuration file and add the
        following new lines after it:

        NameVirtualHost [my_IP_address]:80

        NameVirtualHost [my_IP_address]:443

        In case there are duplicate NameVirtualHost directives remove the duplicates.

     4. Generate certificate and key for the SSL virtual host. We don't provide detailed
        information about this process here because it's outside the scope of Campsite. Read
        http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html for details. If your apache has SSL module
        loaded you can skip to: About Configuration and About Certificates. This step will generate
        at least two files: certificate file, referred here as [certificate_file] and certificate key file,
        referred here as [certificate_key_file]. Install these two files into your apache certificates
        directory, referred here as [certificates_directory].

     5. Edit the Campsite virtual host file.

     6. Duplicate the virtual host definition in this file: copy the whole section in between
        <VirtualHost [...]> and </VirtualHost>, including these tags and paste it at the end of the
        file.

     7. Edit the first virtual host definition and replace the existing <VirtualHost [...]> tag with:

        <VirtualHost [my_IP_addresss]:80>

     8. Edit the second virtual host definition and replace the existing <VirtualHost [...]> tag with:

        <VirtualHost [my_IP_address]:443>

     9. Edit the second virtual host definition and add the following lines into your virtual host
        definition:

        SSLEngine on

        SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP

        SSLCertificateFile [certificates_directory]/[certificate_file]

        SSLCertificateKeyFile [certificates_directory]/[certificate_key_file]

Note: When generating the SSL certificate at step 4 make sure you enter the FQDN ("Fully
Qualified Domain Name") of the server when OpenSSL prompts you for the "CommonName", i.e.
when you generate a CSR for a website which will be later accessed via
enter "www.foo.dom" here. The FQDN you supply as CommonName must be the same as the
value of ServerName in the Campsite instance virtual host.

The following is an example of a fully configured Campsite instance:

- main apache configuration file:

16
Listen 80
Listen 443
NameVirtualHost 192.168.2.101:80
NameVirtualHost 192.168.2.101:443

- Campsite instance virtual host configuration file:
<VirtualHost 192.168.2.101:80>
 DocumentRoot /var/www/campsite
 ServerName www.mydomain.org
 DirectoryIndex index.php index.html

 <Directory /var/www/campsite>
  Options -Indexes FollowSymLinks MultiView
  AllowOverride All
  <IfModule mod_access>
   Order allow,deny
   Allow from all
  </IfModule>
 </Directory>
</VirtualHost>
<VirtualHost 192.168.2.101:443>
 DocumentRoot /var/www/campsite
 ServerName www.mydomain.org
 DirectoryIndex index.php index.html

 <Directory /var/www/campsite>
  Options -Indexes FollowSymLinks MultiViews
  AllowOverride All
  <IfModule mod_access>
   Order allow,deny
   Allow from all
  </IfModule>
 </Directory>

 SSLEngine on
 SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP
 SSLCertificateFile /etc/apache2/ssl/server.crt
 SSLCertificateKeyFile /etc/apache2/ssl/server.pem
</VirtualHost>




Troubleshooting

In this section you can search for issues or bugs we know about in order to find out how to fix
them.

Error creating users: "The user account could not be created"

Since version 2.7 Campsite uses the LiveUser authentication/authorization toolkit. Unfortunately
this toolkit has some bugs that may leave the database in an inconsistent state, which will result
in the error message "The user account could not be created" being displayed when trying to
create a new user. In order to fix the database corruption run the following SQL script against
the Campsite database:
DELETE FROM pu
    USING phorum_users AS pu
        LEFT JOIN liveuser_users AS lu ON pu.fk_campsite_user_id = lu.Id
    WHERE lu.Id IS NULL;
DELETE FROM lur
    USING liveuser_userrights AS lur
        LEFT JOIN liveuser_users AS lu ON lur.perm_user_id = lu.Id
    WHERE lu.Id IS NULL;
DELETE FROM lpu
    USING liveuser_perm_users AS lpu
        LEFT JOIN liveuser_users AS lu ON lpu.perm_user_id = lu.Id
    WHERE lu.Id IS NULL;
UPDATE liveuser_users_auth_user_id_seq
  SET id = (SELECT MAX(Id) FROM liveuser_users);
UPDATE liveuser_perm_users_perm_user_id_seq
    SET id = (SELECT MAX(perm_user_id) FROM liveuser_perm_users);




                                                                                                     17
"Unable to create the database [db_name]" error message when installing Campsite

Please create a PHP script with the following script, run it and check the error messages:
<?php
$dbName = 'my_test';
$dbConn = mysql_connect("localhost", "root", "");
if (!$dbConn) {
    echo "Can not connect to MySQL with root user and no password.\n";
    echo "ERROR: " . mysql_error($dbConn) . "\n";
    exit(1);
}

$res = mysql_query("CREATE DATABASE `$dbName` CHARACTER SET utf8 COLLATE utf8_bin");
if (!$res) {
    echo "Can not create a database. Please verify if you had the privilege "
       . "to create a database.\n";
    echo "ERROR: " . mysql_error($dbConn) . "\n";
    exit(1);
}
echo "Created database '$dbName'.\n";
?>

Please make sure you have MySQL 5.0 or newer running, Campsite does not work on older
versions.

Another reason could be that the root user may not have the privilege to create a database if
connected through a TCP/IP socket. I know it sounds weird but I know a user of Campsite
encountered this problem.

Write rights for the apache user

If you get an error like this, you need to change the access rights:

Notice: Campsite error: unable to write to $compile_dir '/var/www/campsite/templates_c'. Be
sure $compile_dir is writable by the web server user. in
/var/www/campsite/install/classes/CampTemplate.php on line 89

The installer

sets this up automatically in most cases, but in some cases, you will need that the apache user
needs write permissions for the following Campsite folders:

      document root (e.g. /var/vhosts/httpdocs)
      backup (/path/to/document_root/backup)
      conf (/path/to/document_root/conf)
      files (/path/to/document_root/files)
      images (/path/to/document_root/images)
      plugins (/path/to/document_root/plugins)
      templates (/path/to/document_root/templates)
      template_cache (/path/to/document_root/templates_cache)




18
6. BACKUP & RESTORE
In this chapter:

      Backup & Restore in the admin interface (Version 3.4 and newer)
      Creating a backup archive via shell
      Restoring a backup archive via shell

BACKUP & RESTORE IN THE ADMIN INTERFACE
In Campsite Version 3.4 and newer, backup and restore can be managed through the admin
interface. A backup contains the database, templates, images, attached files and configuration
files.

Select "Backup/Restore" under the pulldown menu "Actions". You will see a page similar to this:




You have the possibility to:

      Download -- download the tarball containing the database, templates, images, attached
      files and configuration files.
      Restore -- this will revert entire site, the database, templates, images, attached files and
      configuration files to the stored version. All changes will be lost.
      Delete -- this will delete the tarball containing the database, templates, images, attached
      files and configuration files.
      Make new backup -- a popup screen will inform you on the status of the backup. After
      the finished backup it will contain information similar to this:
#!/usr/bin/php

Campsite Backup Utility
-----------------------
Backup script version: 3.4.0
Backing up campsite
 * Backing up the database...done.
 * Backing up the templates...done.
 * Backing up images...done.
 * Backing up file attachments...done.
 * Backing up configuration files...done.
 * Creating tarball...done.
 * Cleaning up...done.

Backup saved to file:
  /var/www/campsite/backup/backup-campsite-2010-07-14-12-51-43.tar.gz


CREATING A BACKUP ARCHIVE VIA SHELL
For backup purposes you can create archives using the following command:
   [campsite_directory]/bin/campsite-backup [--silent] [--default_dir]

The optional arguments are:

      --silent: don't display any message, whether successful or not
      --default_dir: save the backup archive in the backup default directory
      [campsite_directory]/backup; by default it will create the archive in the current directory


                                                                                                     19
The archive file name is backup-campsite-[date_time].tar.gz and contains the whole instance: the
database, templates, images, attached files and configuration files.

RESTORING A BACKUP ARCHIVE VIA SHELL
Backup archives can be restored by using the "campsite-restore" command. Everything in the
instance will be restored from the archive as it was when the backup was created. Changes
made since the backup will be lost.

This script will replace existing data installation with that in the backup file. You must run this
script from a directory that you have write access to because this script needs to create a
temporary directory. Note that your backup database and files will automatically be upgraded if
they are older than the currently installed version of Campsite.

Note: For multiple installations of Campsite on a single server, you must run this script from the
installation directory where you want to restore the data. For example, if you have installed
Campsite in two locations: /var/www/cs1 and /var/www/cs2, and you want to restore the data
for the 'foo' installation, you must run /var/www/cs1/bin/campsite-restore, and NOT
/var/www/cs2/bin/campsite-restore.

Parameters:

versions 3.0 to 3.3: <backup_file>

versions 3.4 and newer: -b <backup_file>
      Specifies the tarball created by the 'campsite-backup' script. Give the full or relative path
to the file.

   [-t <destination_database_name>]
       If this is specified, the script will use the database name specified instead of the one
specified in the backup file. This is useful for site-to-site transfer of a website, that is, moving
your website from one server to another.

   [-e]
      Use the existing configuration files instead of the ones in the backup file. In other words,
the existing config files in the current installation will not be replaced.

     [-f]
            Dont prompt, assume 'yes' to questions.

     [-c <charset>]
         Convert the database data from <charset> to UTF-8.

     [-s]
         Convert the database data from the database server character set
         to UTF-8.

     [-l]
            List all available charsets and exit.




20
7. INSTALLING THE DEMO TEMPLATES
We provide a few demo sites to get you started: download them here.

You can find more detailed information on the sample templates for our demo publication "The
Custodian" here.

Restore the demo package using the campsite-restore command. For more details read
"Restoring a backup archive" in Backup chapter. All demo packages have the following default
account: "admin", with password "admn00".

Do not forget to add your site alias to the publication defined in the demo package:
Content/Publication menu in the admin interface. For more details read the chapter "Creating a
Publication".




                                                                                                 21
8. INSTALLING ON UBUNTU
Installing Campsite on Ubuntu is fairly easy, provided you follow the right steps. Here is what you
need to do to install Campsite on Ubuntu 9.10 "Karmic Koala:"

CONFIGURE APACHE: CREATE AN APACHE VIRTUAL HOST
(OPTIONAL)
In this case, there are other web apps on the install, so we will put the Campsite install directory
in /var/www/localcampsite.
cd /var/www/

and
mkdir localcampsite

The first step was to remove the existing localhost symbolic link which comes pre-installed with
Apache:
sudo rm /etc/apache2/sites-enabled/000-default

Set up the virtual host in apache so that it knows to look in our /localcampsite directory by
creating a file named localcampsite in /etc/apache2/sites-available:
cd /etc/apache2/sites-available

and then:
sudo gedit localcampsite

Copy and paste this text into the document (if you're using nano you can paste by using the right
click):


NameVirtualHost localhost
<VirtualHost localhost>
     DocumentRoot /var/www/localcampsite
#"localcampsite" can be whatever you want to name your directory
     ServerName localcampsite
#   ServerAlias [site_alias]
     DirectoryIndex index.php index.html
  <Directory /var/www/localcampsite>
     Options -Indexes FollowSymLinks MultiViews
     AllowOverride All
     <IfModule mod_access>
     Order allow,deny
     Allow from all
     </IfModule>
  </Directory>
</VirtualHost>


Save and close.

We need to create a symbolic link between sites available and sites enabled:
sudo ln -s /etc/apache2/sites-available/localcampsite /etc/apache2/sites-enabled/

Whenever you make changes to Apache, you have to restart it:
sudo /etc/init.d/apache2 restart


SETUP YOUR PHP.INI FILE



22
You will need to adjust values in your php.ini file in order for Campsite to work properly. On
Debian and Ubuntu systems, your "php.ini" file is usually located in "/etc/php5/apache2"
directory.
cd /etc/php5/apache2

and then
sudo gedit php.ini

The php.ini file has a lot of different settings. You can use your text editor's "find" function to
jump directly to each of these. The following directives show what the values should be for each
variable in the php.ini file.

Always turn off register_globals because it's a big security hole:
register_globals = Off

Find the "memory_limit" directive and set the amount of memory to at least 32MB:
memory_limit = 32M

Set maximum size of POST data that PHP will accept to a hig value:
post_max_size = 100M

Turn off magic quotes:
magic_quotes_gpc = Off

Allow HTTP file uploads:
file_uploads = On

Set the maximum allowed size for uploaded files to a large value so you will be able to upload
large attachments:
upload_max_filesize = 100M

Make sure the following extensions are enabled (they are enabled as long the line appears in the
php.ini file, and the line does not start with a semi-colon (';')):
extension=gd.so
extension=mysqli.so
extension=mysql.so

DOWNLOADING CAMPSITE
The easiest way to download Campsite for free is to go to our Sourceforge page and download
the files direct from there. Although there are Debian packages available, in this case it's just as
easy to use the source files.

Once they're downloaded, unarchive the file using this command:
tar xzvf /path/to/your/downloaded/file/<Campsite_source>

This will create a directory called "campsite." Enter that directory:
cd campsite

6. Copy the content of implementation/site directory into the document root directory of the
apache virtual host:
sudo cp -a <path to local campsite/implementatation/site> /var/www/localcampsite

Note that your command cannot have a trailing slash. It's ok to have "localcampsite" instead of
having these files in the www root directory. But because we do, we have an additional step of
setting up the virtual host.

Change the ownership of everything in the campsite directory file to be www-data:
cd /var/www/localcampsite


                                                                                                       23
and then:
chown -R www-data *

Start a browser, point it to the http://localhost URL and follow the steps in the web page, and
you're done!




24
9. INSTALLING CAMPSITE FROM DEBIAN
PACKAGES
If you want to install Campsite from the .deb packages, download them from:

http://sourceforge.net/projects/campsite/

Here is a little section on trouble shooting, if you experience any problems after the installation:

1. On your local machine: http://campsite/ in the browser doesn't work at all

As "root" create the file: /etc/apache2/sites-available/campsite

with the following content:
<VirtualHost *:80>
    DocumentRoot /var/www/campsite
    ServerName campsite
#    ServerAlias campsite
    DirectoryIndex index.php index.html
    <Directory /var/www/campsite>
            Options -Indexes FollowSymLinks MultiViews
            AllowOverride All
            <IfModule mod_access>
                 Order allow,deny
                 Allow from all
            </IfModule>
    </Directory>
</VirtualHost>

Open as "root": /etc/hosts

and add the line:
127.0.0.1           campsite

Restart apache:
sudo /etc/init.d/apache2 restart

Empty your browser cache and point your browser again to http://campsite/

2. Pointing your browser to http://campsite/ for installation throws the errors:
Warning: require_once(/var/www/campsite/conf/install_conf.php) [function.require-once]:
failed to open stream:
Permission denied in /var/www/campsite/install/classes/CampInstallationBase.php on line 18

Fatal error: require_once() [function.require]: Failed opening required
'/var/www/campsite/conf/install_conf.php'
(include_path='.:/usr/share/php:/usr/share/pear') in
/var/www/campsite/install/classes/CampInstallationBase.php on line 18

Change the user rights of the campsite folder and subfolder / files to be readable and writeable
by apache.

3. Pointing your browser to http://campsite/ for installation throws the errors:
Notice: Campsite error: the $compile_dir '/var/www/campsite/templates_c' does not exist, or
is not a directory. in /var/www/campsite/install/classes/CampTemplate.php on line 89

Create the folders "templates" and "templates_c" in the campsite folder, set the rights to
readable and writeable for apache.

4. The installation routine shows the error on the first screen:
Cron Jobs Writable ⁞       No
                          You will need to grant permissions to folder
                          /var/www/campsite/install/cron_jobs

                                                                                                       25
If the folder does not exist: create it. And set the rights to readable and writeable for apache.




26
10. INSTALLING CAMPSITE ON WINDOWS
VISTA
TIPS AND TRICKS FOR MAKING CAMPSITE INSTALL ON
VISTA (NOT RECOMMENDED FOR PRODUCTION SERVERS)
The Campsite content management system is an extremely flexible and powerful tool for news
websites. And since the 3.0 version of Campsite, it can be installed under Windows relatively
easily. This howto has been written for users of Windows Vista, but the steps should be similar,
if not easier, for other versions of Windows as well.

The main advantage of having Campsite installed under Windows is that it greatly simplifies the
process of creating and altering site templates; proprietary design and image editing tools such
as Photoshop, Illustrator and Dreamweaver run under Windows but not on Linux. Having a local
version of Campsite running means that a template designer can easily alter site graphics
without having to either use a remote server or reboot into Linux.

NOTE: This howto is not intended for production servers running under Windows.



PREREQUISITES

To install Campsite under Windows, you will need the Windows versions of the following software
packages:


      Apache 2.2 (this installation used apache-2.2.8-win32-x86-openssl-0.9.8g.msi from
      http://httpd.apache.org/download.cgi)
      PHP 5.25 (http://www.php.net/get/php-5.2.5-win32-installer.msi/from/a/mirror)
      MySQL (this installation used mysql-essential-5.0.51a-win32.msi, downloadable from
      http://dev.mysql.com/downloads/mysql/5.0.html#win32)
      Campsite 3.1 (http://sourceforge.net/project/showfiles.php?group_id=66936)

Optional programs:

      7-zip (for opening and working with tar.gz files):
      http://sourceforge.net/project/showfiles.php?group_id=14481&package_id=29413
      Resource Hacker (for making changes to MySQL so that it will install under Windows Vista):
      http://www.angusj.com/resourcehacker
      Notepad++ (for making changes to various text files. It's like gEdit under Linux):
      http://downloads.sourceforge.net/notepad-plus/npp.4.8.Installer.exe?
      modtime=1204074249&big_mirror=0

INSTALLING MYSQL UNDER WINDOWS VISTA
MySQL has a number of known issues installing under Windows Vista. You must:

      Disable User Access Control (UAC) in the Control Panel. Microsoft does not recommend
      doing this for production computers. This PDF explains how:
      http://port25.technet.com/videos/research/MySQL_Windows.pdf
      There is a known issue regarding side-by-side installation if you try to install MySQL
      directly from the .msi package. You will have to change a file in the MySQL installer in
      order for it to install properly. The steps below are taken from a post to the MySQL
      forums at this address: http://forums.mysql.com/read.php?11,195569,195569#msg-195569



                                                                                                   27
To install MySQL Server 5.0.51a in Vista

  1. Disable the UAC in Windows Control Panel->User Accounts
  2. Use mysql-essential-5.0.51a-win32.msi
  3. In the final step uncheck "Configure MySQL Server now"
  4. Download and run Resource Hacker

  5. Open ...\MySQL Server 5.0\bin\MySQLInstanceConfig.exe with Resource Hacker
  6. Navigate to 24\1\1033
  7. Change <requestedExecutionLevel level="asAdministrator" uiAccess="false"> to
<requestedExecutionLevel level="requireAdministrator" uiAccess="false">
  8. Press "Compile script"
  9. Exit Resource Hacker and save the result (overwrite the initial MySQLInstanceConfig.exe)
 10. Now MySQLInstanceConfig.exe should start normally.
 11. Configure the server.
 12. Sometimes the server doesn't start:

      a) Check Windows Firewall settings (3306/TCP)
      b) Try changing the compability mode for the file ...\MySQL Server 5.0\bin\mysqld-
      nt.exe to Windows XP-SP2.

 13. That's all.

Go through the MySQL installation process and make a note of your MySQL root password. You
will need this later.

INSTALLING APACHE 2.2

Apache 2.2 installs without problems using the Windows Installer under Windows Vista. Once
installed, it even has a small icon for starting, restarting and stopping Apache which runs in the
system tray. The Apache folders are in this directory:


C:/Program Files/Apache Software Foundation/Apache 2.2/htdocs

(This is the equivalent of /var/www/ under Linux)

You will have to change your Apache virtual host configuration. This involves making changes to
two files, httpd-vhosts.conf and httpd.conf. You can find httpd.conf in C:/Program Files/Apache
Software Foundation/Apache 2.2/conf

and you will find httpd-vhosts.conf in C:/Program Files/Apache Software Foundation/Apache
2.2/conf/extra

Open C:/Program Files/Apache Software Foundation/Apache 2.2/conf/httpd.conf

Make a backup of this file. Give it a name like 'httpd.conf.backup'

Reopen the httpd.conf file. Search for the line that says:
#Virtual Hosts

#Include conf/extra/httpd-vhosts.conf


Remove the # mark from the line to uncomment the Virtual Hosts directive:
#Virtual Hosts
Include conf/extra/httpd/vhosts.conf


In that file you should also make sure that the mod_dir.so and mod_rewrite.so modules are
loaded in order for Campsite to work properly:

28
LoadModule dir_module modules/mod_dir.so
LoadModule rewrite_module modules/mod_rewrite.so


Save and close.

Open the file for virtual hosts under Apache in C:/Program Files/Apache Software
Foundation/Apache 2.2/conf/extra/httpd-vhosts.conf

There are a number of directives Campsite needs in order to run. Here is how I set up my
Apache virtual host using the name of 'mycampsite' on my local host:

<VirtualHost *:80>
    ServerAdmin webmaster@mycampsite.localhost
    DocumentRoot "C:/Program Files/Apache Software Foundation/Apache 2.2/htdocs/mycampsite"
    ServerName mycampsite.localhost
    ServerAlias www.mycampsite.localhost
    DirectoryIndex index.php

    <Directory "C:/Program Files/Apache Software Foundation/Apache 2.2/htdocs/mycampsite">
            Options -Indexes FollowSymlinks MultiViews
            AllowOverride All
                Order allow,deny
            Allow from all
    </Directory>

    ErrorLog "logs/mycampsite.localhost-error.log"
    CustomLog "logs/mycampsite.localhost-access.log" common
</VirtualHost>


You must make separate virtual hosts for every Campsite instance you want to run.



EDITING THE WINDOWS SYSTEM'S 'HOSTS' FILE

In order for mycampsite.localhost to be visible, you need to tell Windows that you've added this
new subdomain to 'localhost'. To do this, you must go to C:/Windows/System32/drivers and edit
the file. Or you can go to C:/Windows/System32 and search for 'hosts'.


Your file will look like this in the main part:

127.0.0.1   localhost
::1       localhost

You need to add a line to include your site name (in this case it was 'mycampsite'):

127.0.0.1       localhost
127.0.0.1       mycampsite.localhost
::1           localhost

You may need to restart for this to take effect.



INSTALLING PHP
Installing PHP was fairly straightforward.

                                                                                                   29
Select Apache 2.2 as the version you are using and point it to the Apache configuration directory
is located (C:/Program Files/Apache Software Foundation/Apache 2.2/conf).

During the installation process, you will be asked if you want to install PHP extensions. You will
need the following:

      GD2
      MySQL

They are located in the Extensions tree and are not installed by default, so you will have to find
them in the tree and select them for installation.

You might need PEAR, so it's a good idea to enable that as well under 'Extras-> PEAR Install'.

If you miss it the first time around, you can always go back and re-enable them by going to
Control Panel -> Uninstall -> PHP5 -> Change and this will restart the setup.

INSTALLING CAMPSITE
If you haven't done so already, download the latest version of Campsite:
http://sourceforge.net/project/showfiles.php?group_id=66936


Unpack the files using 7-zip.

The Campsite INSTALL file included in the tarball is written for Unix users, and things are a bit
different under Windows. For example, you will have to copy the implementation/site folder to
your Apache document root. If you did not change anything, the Apache document root will be in
this directory: C:/Program Files/Apache Software Foundation/Apache 2.2/htdocs

In a separate window, go to where you unpacked the Campsite 3.1 tar file (in this case the folder
was named campsite-3.1.0.tar), open the folder marked 'implementation' and then the folder
marked 'site'. Select all the files in implementation/site and copy them.

Go to the Apache document root (C:/Program Files/Apache Software Foundation/Apache
2.2/htdocs) and create a new folder with the name of your Campsite implementation. In this case
the folder was named 'mycampsite'. Open that folder and paste the files you copied from the
implementation/site folder into your new folder.

Rename the file htaccess to .htaccess and be sure your apache installation is able to read it in
order for Campsite to work well on this platform.

If all the other programs (Apache, MySQL, PHP) have been installed correctly, you should be able
to start the Campsite web installer by opening this address in your browser:
mycampsite.localhost

follow the steps in the Campsite web installer and you should be on your way.

Once the installation is done, you can open your Campsite administration interface in a browser
at this address:
mycampsite.localhost/admin


NOTES:
Because this howto is using the MySQL database only for Campsite and only for
testing/development, it used the MySQL root username and password. You should use a
different username/password if you will be using MySQL for other purposes on your Windows
install.

For users of previous versions of Campsite, you have to pay special attention to the last page of

30
the web config. The old default username/password combination of admin/admn00 has changed.
Now you set your password on the last page of the web installer so that your username is
admin and the password is whatever you set.




                                                                                             31
11. INSTALLING CAMPSITE ON MAC OS X
Installation using MAMP

     download and install MAMP. The installation works in the same way like for other Mac OS X
     applications. Just open downloaded image and drag&drop the MAMP folder to your
     Applications folder.
     now you need to do changes to php.ini according to campsite installation manual. It seems
     that everything should work with default values except memory_limit parameter. So change
     that value to something bigger. Edit file /Applications/MAMP/conf/php5/php.ini
     memory_limit = 32M

     download Campsite tarball and unpack it. Campsite folder will be created.
     copy content of campsite/implementation/site folder into Apache document root folder:
     /Applications/MAMP/htdocs
     start MAMP and make sure that Apache and MySQL servers are running
     start your web browser and point it to http://localhost:8888 (that is the default port
     number of Apache from MAMP), you should see configuration wizard of Campsite
     enter all needed values into the wizard, the MySQL default port number is 8889
     after finishing the wizard you should be able to login to admin interface on
     http://localhost:8888/admin

Known issues

As for Campsite 3.1.2 and MAMP 1.7.2 the demo templates and database are not installed by
wizard during the installation process. If you want to use them, you need to install them
manually.




32
12. INSTALLING CAMPSITE ON FREEBSD
Most FreeBSD admins will find it very easy, as campsite is in FreeBSD ports (www/campsite) and
all, you need to do is standard port install:
#cd /usr/ports/www/campsite
#make install clean




                                                                                                 33
13. INSTALLING CAMPSITE ON PHP-CGI
SHARED HOSTS
Installing Campsite on hosting setups that run PHP as CGI is possible but is not always
straightforward.

Given that such setups vary from provider to provider, we have started a wiki that collects
installation instructions and issues that may arise in such environments. The wiki can be found
here:

http://wiki.sourcefabric.org/display/CS/Install+on+Shared+Hosting+Using+PHP-CGI




34
14. AUTOMATED TASKS
Campsite has tools that perform the following automated tasks:

  1. sending emails to administrative users containing the latest events that took place in
     Campsite
  2. sending emails to subscribers alerting them when their subscription ends
  3. automatic changing of the status of issues and articles scheduled for certain actions
  4. automatic indexing the article content (update the search engine database)
  5. generating statistics

The automated tasks are scheduled using the crontab utility, run as apache user (www-data on
some systems).

1. Sending emails to administrative users containing the latest events that took place in Campsite
is managed by the utility events-notifier located in Campsite's bin directory. This utility is
scheduled to run every two minutes.

2. Sending emails to subscribers alerting them when their subscription ends is managed by the
utility subscription-notifier located in Campsite's bin directory. This utility is scheduled to run
every eight hours.

3. Automatic changing of the status of issues and articles scheduled for certain actions
(publish/unpublish/show in front page etc.) is managed by the utility campsite-autopublish located
in Campsite's bin directory. This utility is scheduled to run every minute.

4. Automatic indexing the article content is managed by the utility campsite-indexer located in
Campsite's bin directory. This utility is scheduled to run every four hours.

5. The statistics gathering script is managed by the campsite-statistics utility, located in the
Campsite's bin directory. This utility is scheduled to run every four hours.




                                                                                                      35
15. SETTING UP A CAMPSITE REPLICATION
SERVER
The Replication Server concept was developed as a part of the Sourcefabric Radio Package
project (a complete open source solution for a radio station (see
http://wiki.sourcefabric.org/display/CC/Radio+Package).

Facts

Since Internet connectivity is not that good in some places, radio stations need to be able to
create stories on their local intranet and then send them to the main web server (outside of the
intranet) whenever connectivity is available. All media from the article must be uploaded to the
web server.

The following must be synchronized:

        Database (using MySQL replication)
        images folder
        files folder (attachments)
        look folder (templates)
        And also any Campcaster storage server files that have been added as attachments to
        Campsite articles.



Campsite Installation

All you need to do is run a normal Campsite installation on both the master and slave servers.
The most important thing at this point is to set the same instance name (campsite is the default)
for both installations.

Follow the "Installation" section from the Campsite manual to do all of this in a right way.



Campsite MySQL database replication

MySQL server has built-in support for replication, meaning that you can have on-the-fly copies of
data stored in a main database server --known in this context as a Master server-- in anothers
servers --the Slave servers--. Latest releases of MySQL server --5.x-- allow you to create really
complex replication scenarios, but this is not our case. All what you need to synchronize two
campsite servers is to use a simple MySQL replication scheme, known as Master Master
replication.

When using replication, all updates to the tables that are replicated should be performed on the
master server.

This way and to be clear, Local Campsite server will be our 'Master 1' and 'Slave 2', and the
Online Campsite server will be the 'Slave 1' and 'Master 2'.

We really need to implement this scheme because of the article comments management. More
details about this in the section Handling Article Comments at the end of this document.



Requirements

MySQL >= 4.1.0

Make sure MySQL versions installed on master and slave are compatibles to do replication. Take
a look at http://dev.mysql.com/doc/refman/4.1/en/replication-compatibility.html.

36
Setting up

In general, what we need to do is:

      Ignore ArticleComments, all Phorum tables ( phorum_* ) and SystemPreferences when
      replicating from Local to Online.
      Replicate all the rest campsite tables from Local to Online.
      Replicate ArticleComments and all the Phorum tables ( phorum_* ) from Online to Local.

So, here we go.

1- Create an account on the 'Master 1' server that the 'Slave 1' can use to connect.
   mysql>⁞ GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.*
       -> TO 'replication_user'@'slave1server.yourdomain.com'
       -> IDENTIFIED BY 'a_strong_password';

      Change 'replication_user', 'slave1server.yourdomain.com' and 'a_strong_password' to
      whatever you want to use and suit your installation.

2- Create an account on the 'Master 2' server that the 'Slave 2' can use to connect.
   mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.*
       -> TO 'replication_user'@'slave2server.yourdomain.com'
       -> IDENTIFIED BY 'a_strong_password';

      Change 'replication_user', 'slave2server.yourdomain.com' and 'a_strong_password' to
      whatever you want to use and suit your installation.

3- Add the following lines to the MySQL configuration file on the 'Master 1' and on the 'Master 2'
servers. The MySQL configuration file path is usually '/etc/mysql/my.cnf', if you installed MySQL
from the standard packages.
   master 1:

   [mysqld]
   server-id = 1
   log-bin

   master-host = master2server.yourdomain.com
   master-port = 3306
   master-user = replication_user
   master-password = a_strong_password

   replicate-do-db = campsite
   replicate-do-table = campsite.ArticleComments
   replicate-wild-do-table = campsite.phorum_%

      The value for master-host can be the valid fqdn (fully qualified domain name) or the
      IP address of your 'Master 2' server.
   master 2:

   [mysqld]
   server-id = 2
   log-bin

   master-host = master1server.yourdomain.com
   master-port = 3306
   master-user = replication_user
   master-password = a_strong_password

   replicate-do-db = campsite
   replicate-ignore-table = campsite.ArticleComments
   replicate-ignore-table = campsite.SystemPreferences
   replicate-wild-ignore-table = campsite.phorum_%

      The value for master-host can be the valid fqdn (fully qualified domain name) or the
      IP address of your 'Master 1' server.

      Note all of the above [mysqld] entries are replication specific. You usually have
      another couple of entries there, but it does not matter for replication purposes.

                                                                                                     37
4- We need to make sure both 'Master 1' and 'Slave 1' will have the same Campsite database at
the same status when starting replication.

       If you are doing a new installation on both 'Master 1' and 'Slave 1' and you are totally
       sure that you are installing the same Campsite package and databases are exactly
       the same, you can skip this step and continue on 4-. If you do not, continue here.

       We have got to make a dump of the 'campsite' database from our 'Master 1' server,
       then we will copy it to the 'Slave 1' server. Let us use the mysqldump utility to do
       this.
     $ mysqldump campsite > /tmp/campsite_dump.sql --extended-insert \
     > --master-data -u mysql_user -p

       You will be prompted to enter the corresponding password for your MySQL user
       (default user is the current logged in user). Remember, you need to run this
       command as a MySQL user with the granted privileges required to do this.

       This will create a text file --/tmp/campsite_dump.sql-- containing SQL statements to
       create the 'campsite' database tables with data.

       Now, copy/transfer the dump file to the 'Slave 1' server, make sure MySQL is running
       there. If you already have a 'campsite' database on the 'Slave 1' it is time to drop all
       of the tables on it --do not forget backing up, maybe you still need it--. Finally, enter
       something like the following on the 'Slave 1':
     $ mysql campsite < /tmp/campsite_dump.sql -u mysql_user -p

       This will execute all of the SQL statements in the dump file, which will include the
       CREATE and INSERT statements. Once the dumped-up databases are loaded onto
       the 'Slave 1' server, go to the final step.

5- Restart both mysql 'Master 1' and 'Master 2', then execute the following SQL statement while
logged in as root on both of them:
     mysql> START SLAVE;

6- Check replication works

       Setting up and getting work this simple kind of replication is quite easy. If you
       followed the above indications then replication would have to be working well now.
       However, you can check this by running the SHOW MASTER STATUS command on
       the masters and SHOW SLAVE STATUS on the slaves. Those commands will give you
       some information about the current status of both the Master and Slave servers.

If you are experiencing troubles and replication does not work as it should, please take a look at
the corresponding section in the MySQL manual and the other links referenced at the end of this
document.



Syncing Articles-related Files⁞

This Radio Package feature allows you to be able to synchronize Campsite Article-related files
between the Local server and the Online server over the Internet. Our goal is to ensure no user
intervention is required when the server is restarted (for passwords or keys).

Please note these instructions are specific to Ubuntu Linux versions 4.01 and later. However, it
should be run quite well on any *NIX type OS.



Requirements

Just simple like this:



38
       rsync
       OpenSSH
       cron



Setting up⁞

Keep this in mind:

       remoteuser = the user to be use on the Online server
       remotehost = the Online server (hostname or IP address)
       localuser = the user to be use on the Local server
       localhost = the Local server (hostname or IP address)

The remote user must have write access to the Campsite instance HTML directory on the
remote host. The local user must have read access to the Campsite instance HTML directory on
the local host. The default value of this directory is '/var/www/campsite/html'. You can achieve
this by adding the remote/local user to the apache group (default is www-data on Debian/Ubuntu
and apache on RedHat). On the remote machine you have to run the following command also:
  chmod g+w /path/to/campsite/instance/html/directory/ -R

1- Test whether rsync over ssh works at all.
   $ rsync -avz -e ssh remoteuser@remotehost:/remote/dir /local/dir/

       Type the corresponding password when prompted.

2- Configure the Local server.

       We need to generate a private/public pair of keys to allow a ssh connection without
       asking for a password.
   $ cd ~
   $ mkdir .campsite-rsync
   $ ssh-keygen -t dsa -b 1024 -f ~/.campsite-rsync/localhost-rsync-key
   Generating public/private dsa key pair.
   Enter passphrase (empty for no passphrase):
   Enter same passphrase again:
   Your identification has been saved in /home/localuser/.campsite-rsync/localhost-rsync-key.
   Your public key has been saved in /home/localuser/.campsite-rsync/localhost-rsync-key.pub.
   The key fingerprint is:
   2e:28:d9:ec:85:21:e7:ff:73:df:2e:07:78:f0:d0:a0 localuser@localhost

       You have got to create an empty passphrase, so just press enter when asked for it
       to generate the keys. Make sure to do this to avoid no other unauthorized user can
       read the private key file.
   $ chmod 600 .campsite-rsync/localhost-rsync-key

       Now we will put the public key into the 'authorized_keys' file on remotehost (a.k.a.
       our Online server) specifically the one for remoteuser.

       Let us use scp to transfer the file over from localhost to remotehost.
   $ scp .campsite-rsync/localhost-rsync-key.pub remoteuser@remothost:~/

3- Configure the Online server.

       SSH'ing over to remotehost. Once we are on /home/remoteuser/ we need to make
       sure that every directory and file that we need to authorize connections with the
       transfered key exist.
   $   if [ ! -d .ssh ]; then mkdir .ssh ; chmod 700 .ssh ; fi
   $   mv localhost-rsync-key.pub .ssh/
   $   cd .ssh/
   $   if [ ! -f authorized_keys ]; then touch authorized_keys ; chmod 600 authorized_keys ; fi
   $   cat localhost-rsync-key.pub >> authorized_keys




                                                                                                   39
Now, we can make connections to the Online server from anywhere. We can edit
'authorized_keys' to increase security by adding somethink like this --use your preferred text
editor-.

Change the public key, that looks like this:
     ssh-dss AAAB3NzaC1kc3MAAAEBAOy99zr4UZxKVTcVIZOoUdUNa5LWUn4urIdY4bxP4SuLbcJZumIqyrkV
     YmoT0Qk8l1peRvLkpyE/G5TAyKeS0wpxm28mEF2oRcLx5/ItD2hwfm53irUKYAjiaLwHkAtDZyHUQyZiKku
     s4LqZo2eo196diq3UYxebKX3p6N+l10yBvZr8NGxtyf+QVybxaIKw7qcnUEz+jldV3zY/+wyO/LVtuiD0qN
     W6yG2jv4kYf4ENTz5auMdh5rSv9TXVigDV5DGOHhIKMlQ4Oee0tZ6K82S3yq9mhjOm8KXRmEgr+GQaG/4Yg
     dBmhPeKfneAfbHwD41vb0fvMjpxX9zVX+V4EpEAAAAVAOIO/+vd01P/UyC1KRQz9J10VqfRAAABAE/d1adp
     YnBaH2qxpvyom54eDig6wltril7BjxxEkP9HJS1+03MIJLDE0ZZPfxyiZl4n2SzPMp7uxhd0llywud6dIiF
     GMZ2u8YyJcuRs2dEwIz5CyNtGdTks8G8d3nTRhJEwkXexG83c+/RzGFZZW1ZnBwlvkfRedU2dELwV9ofQpV
     lQhnl0H5eM1M2U0O0pLHADp89ViuoKle4hFpBzPQQ4h+j6bVeemlvvZVNilGnEwatEpRrmtMcpet1yZEqFD
     darGlh/+V5MSjALw4f1E4BYWo23r2qBnoZl6+1MP26SDysXJzxAbA1yvmwbCVZFsTsPlyHhasn5cR25z11g
     Ob8AAAEAB0tCrUN5V1LgohyVmlIWBOa4nFle+tEBLIPC5Bbqgm4LVQ3MUBs4CADeaJHGirSC5JuJuyJXPGQ
     JOSpOdLk/q4ZaJp0SlxcVqXGX1hHIlHE7NuqFPc4+TgPETRaPztTvvg5zA0kTo8CP4qeYtcIt+Mm7F4YGir
     ySeMspPN3Xwh7/0rgDrY/t+FwxPmSRKEIWo1Tztx89+u4yb2FHLB8Hku157GHz502P47jhSYgk2WgoKrJhF
     BrhjvKClVBu8oD7OA10nI9ZNGa4j1OfdTUUukGHoGxJhXhkVXR+mPJMRr6AD6dr/oadObF2Fe6itfRq2KYr
     BGA0M4KNE6LH/2RfAQ== holman@mutant

       to:
     from="local_IP",command="/home/remoteuser/.campsite-rsync/validate-rsync" ssh-dss
     AAAAB3NzaC1kc3MAAAEBAOy99zr4UZxKVTcVIZOoUdUNa5LWUn4urIdY4bxP4SuLbcJZumIqyrkVYmoT0Qk
     8l1peRvLkpyE/G5TAyKeS0wpxm28mEF2oRcLx5/ItD2hwfm53irUKYAjiaLwHkAtDZyHUQyZiKkus4LqZo2
     eo196diq3UYxebKX3p6N+l10yBvZr8NGxtyf+QVybxaIKw7qcnUEz+jldV3zY/+wyO/LVtuiD0qNW6yG2jv
     4kYf4ENTz5auMdh5rSv9TXVigDV5DGOHhIKMlQ4Oee0tZ6K82S3yq9mhjOm8KXRmEgr+GQaG/4YgdBmhPeK
     fneAfbHwD41vb0fvMjpxX9zVX+V4EpEAAAAVAOIO/+vd01P/UyC1KRQz9J10VqfRAAABAE/d1adpYnBaH2q
     xpvyom54eDig6wltril7BjxxEkP9HJS1+03MIJLDE0ZZPfxyiZl4n2SzPMp7uxhd0llywud6dIiFGMZ2u8Y
     yJcuRs2dEwIz5CyNtGdTks8G8d3nTRhJEwkXexG83c+/RzGFZZW1ZnBwlvkfRedU2dELwV9ofQpVlQhnl0H
     5eM1M2U0O0pLHADp89ViuoKle4hFpBzPQQ4h+j6bVeemlvvZVNilGnEwatEpRrmtMcpet1yZEqFDdarGlh/
     +V5MSjALw4f1E4BYWo23r2qBnoZl6+1MP26SDysXJzxAbA1yvmwbCVZFsTsPlyHhasn5cR25z11gOb8AAAE
     AB0tCrUN5V1LgohyVmlIWBOa4nFle+tEBLIPC5Bbqgm4LVQ3MUBs4CADeaJHGirSC5JuJuyJXPGQJOSpOdL
     k/q4ZaJp0SlxcVqXGX1hHIlHE7NuqFPc4+TgPETRaPztTvvg5zA0kTo8CP4qeYtcIt+Mm7F4YGirySeMspP
     N3Xwh7/0rgDrY/t+FwxPmSRKEIWo1Tztx89+u4yb2FHLB8Hku157GHz502P47jhSYgk2WgoKrJhFBrhjvKC
     VBu8oD7OA10nI9ZNGa4j1OfdTUUukGHoGxJhXhkVXR+mPJMRr6AD6dr/oadObF2Fe6itfRq2KYrBGA0M4KN
     E6LH/2RfAQ== holman@mutant

       Note at the beginning of the line. 'local_IP' is the IP address of the Local server, and
       '/home/remoteuser/.campsite-rsync/validate-rsync' is a script that you can create --
       on the Online server-- by:
     $ mkdir .campsite-rsync
     $ cd .campsite-rsync
     $ vim validate-rsync    // or your preferred editor

       and this is its content:
     #!/bin/sh

     case "$SSH_ORIGINAL_COMMAND" in
     *\&*)
          echo "Rejected"
          ;;
     *\(*)
          echo "Rejected"
          ;;
     *\{*)
          echo "Rejected"
          ;;
     *\;*)
          echo "Rejected"
          ;;
     *\<*)
          echo "Rejected"
          ;;
     *\`*)
          echo "Rejected"
          ;;
     rsync\ --server*)
          $SSH_ORIGINAL_COMMAND
          ;;
     *)
          echo "Rejected"
          ;;
     esac




40
      If 'localhost' has a variable IP address, or shares its address (via NAT or something
      similar) with hosts you do not trust, omit the 'from="local_IP",' part of the line
      (including the comma). This way, 'rsync' will be possible from connections using this
      key.

      Make sure that the 'validate-rsync' script is executable by 'remoteuser' on
      'remotehost'.

      Check you do not allow SSH root access from anywhere, this is always a good
      security practice. You need to have an entry like this in the SSH daemon
      configuration file to do that:
   PermitRootLogin no

4- Let us test if all of the stuff above work well. Run the following command on the local server:
   $ rsync -avz -e "ssh -i /home/localuser/.campsite-rsync/localhost-rsync-key" \
         /home/localuser/somefile remoteuser@remotehost:/home/remoteuser/remote_dir

      If it does not work, probably it is because of the file permissions, so check them for
      each file mentioned before.

5- What to transfer.

      Files to be synchronized are those contained into 'images', 'files' and 'look' Campsite
      directories. They will be transfered over from Local server to Online server. We need
      to create a file on the Local server with the list of directories and files to be sent.
   $ vim /home/localuser/.campsite-rsync/rsync-files-to-sync.txt

      This is the content you need to put in:
   images
   files
   look

      That is it, make sure each entry is on a new line. Save and close the file.

6- Cron Job setup.

      Now we create the cron script 'rsync-campsite-afiles' like this:
  #!/bin/sh

  RSYNC=/usr/bin/rsync
  SSH=/usr/bin/ssh
  KEY=/home/localuser/.campsite-rsync/localhost-rsync-key
  RUSER=remoteuser
  RHOST=remotehost

  LCAMPSITE_WWW_PATH=/path/to/local/campsite/html/instance/dir
  RCAMPSITE_WWW_PATH=/path/to/remote/campsite/html/instance/dir
  FILESFROM=/home/localuser/.campsite-rsync/rsync-files-to-sync.txt

  $RSYNC -razO -e "$SSH -i $KEY" --files-from=$FILESFROM "$LCAMPSITE_WWW_PATH" \
       "$RUSER@$RHOST:$RCAMPSITE_WWW_PATH"

      The cron script is easy to understand, all what you need to know about it is:
  RSYNC: The full path to the 'rsync' binary file
  SSH: The full path to the 'ssh' binary file
  KEY: The full path to the SSH private key
  RUSER: The name for the user on the Online server
  RHOST: The hostname for the Online server
  LCAMPSITE_WWW_PATH: The full path to the Campsite instance HTML directory on
                      the local server (the usual value is:
                      /var/www/campsite/html)
  RCAMPSITE_WWW_PATH: The full path to the Campsite instance HTML directory on
                      the remote server (the usual value is:
                      /var/www/campsite/html)
  FILESFROM: The full path to the file containing the files/directories
             name to be synced

      Set executable permission on it:
   $ chmod 755 /home/localuser/.campsite-rsync/rsync-campsite-afiles

                                                                                                     41
       Finally, we create an entry for this new cron job:
     $ crontab -e

       line to insert:
     * * * * * /home/localuser/.campsite-rsync/rsync-campsite-afiles

       for a by minute synchronization.



Handling Article Comments

If you are setting up a Local and Online servers environment, you need to take care of article
comments. Why? Well, static and dynamic pages must be generated by working on the Local
server, that is why we need to replicate data over from the Local to the Online server to keep it
up to date.

On the other hand, we have got users from all around the world visiting our Website and,
hopefully, most of them would like to post comments on the published articles, and they just can
do that.

Said that, we will need to be able to replicate those article-comments-related tables back to the
Local server.

All the stuff above means that comments management will be enabled in our Local server only
whether we are online and able to reach our Online server.

This is what you need to do in order to set up comments replication:

       Create a database user on the Online Server to connect from the Local server.
   mysql> GRANT ALL PRIVILEGES ON campsite.* TO 'dbuser'@'localserver' IDENTIFIED BY
'somepassword';

Now, on the Local server:

       Login to the Campsite admin interface and go to System Preferences.
       Check Yes for Setting up a Campsite Replication Server?
       Fill the form fields for the Campsite Online Server Database as follows:
               Database Host: The IP address or hostname of your Online server.
               Database User: (dbuser) This is your user for the MySQL server at your Online
               server.
               Database Password: (somepassword) The valid password for the database user.
               Database Port: The port to connect to the remote database server (default is 3306).

That is it, Campsite will show whether you are able or not to manage article comments on the
Local server.

Finally

Please, run tests enough to check everything works well, after that you will can go in productive
=)



Resources

       MySQL Replication Manual http://dev.mysql.com/doc/refman/4.1/en/index.html
       MySQL Replication Jeremy Zawodny http://dev.mysql.com/books/hpmysql-
       excerpts/ch07.html
       rsync man page or man rsync on your *NIX shell
       ssh Manual http://www.openssh.com/manual.htm

PUBLISHING WITH CAMPSITE

42
16. Getting Started
17. How Permissions Change the Interface
18. Main Menu
19. Creating a Publication
20. Creating a New Issue
21. Creating a Section
22. Creating Articles
23. Editing Articles
24. Using the TinyMCE Editor
25. Managing Content
26. Publishing Articles
27. Publishing an Issue
28. Article Comments
29. Moderating comments




                                           43
16. GETTING STARTED
Campsite enables you to host multiple, multi-lingual publications on the same web server. The
process of setting up a new on-line publication with Campsite can be divided into three steps:

     1. Configuring the publication, and specifying the templates to be used
     2. Establishing the structure of your publication, with issues and sections
     3. Adding content, managing content, and publishing it

This part of the Campsite manual is aimed at editors and journalists working their way through
these three steps. It assumes that the web server you will use is already up and running with
Campsite, and that templates have been designed for your publication. If you do not yet have
your own Campsite server running, you can follow the steps in this manual using the Campsite
demonstration server and sample templates provided by Sourcefabric.

The first step begins with logging in to the administration interface of your Campsite server. This
is a special interface which is only available to the staff of your publication. Readers who
subscribe to your online publication will log in using the home page of your website instead.

By default, the URL you should enter into your web browser for the administration interface is
the name of your website, followed by 'admin'. For example:

http://www.example.com/admin/

Your system administrator should already have provided you with a login account name and
password. Below the Account name and Password fields, click the drop-down menu to select an
interface language other than the default of English, if you wish. Then click the Login button.




Alternatively, the Campsite demonstration server can be found at:

http://campsite-demo.sourcefabric.org/admin/

Please remember that the demonstration server is a public site, so don't enter any private
information there. A variety of guest login accounts are set up on this system, and the
passwords for these accounts are shown on the login page.


44
45
17. HOW PERMISSIONS CHANGE THE
INTERFACE
The appearance of the Campsite administration interface changes, depending on the permissions
that a particular staff member has. Each user sees only the options that he or she has the
authority to use. A typical staff user (a section editor or journalist) will only see some of the
options available to a fully authorized administrator (such as the publisher, or senior manager).

When you log into the Campsite administration interface, you will see the administration home
page. This is completely different from the publication home page that readers and subscribers
see. At the top of the screen, you will see the navigation menu, containing the options available
to you.

Here is how two typical users would see the navigation menu differently. Firstly, here's how the
Actions sub-menu looks when an administrator is logged in:




And this is how the same Actions sub-menu looks when a journalist is logged in:




46
47
18. MAIN MENU
The main Campsite menu contains a link to the administration Home page and up to six sub-
menus, depending on the permissions of the user who is logged in. These sub-menus are
Content, Actions, Configure, Users, Plugins and Help. The menus shown below are for an
administrator user, who has access to all sub-menu options.

HOME
On the left hand side is a list of quick links to different selections of articles; for example, articles
that you have submitted yourself, or pending articles.




Clicking on any of these links makes a table of the relevant articles appear on the right hand side
of the window.




48
CONTENT
Here you can find the publications on the server, reader comments, the image archive, and the
Universal List, a place where you can browse all of the articles in the Campsite database. For
each available publication, there are quick links to the latest three issues, and a full list of
sections within each issue. In the screen shot below, a sample publication called 'the Custodian'
has been set up, with two issues in both English and Spanish. Within issue 2 of the English edition,
there are six sections shown.




ACTIONS
This menu provides quick access to the most commonly used functions, including 'Add new
article' and 'Change your password'.




                                                                                                       49
CONFIGURE
Here you can configure the preferences for your publication. Templates are the files which
determine how Campsite displays content to readers and subscribers. Article Types describe the
format of your articles, while Topics allow you to categorize your articles. The Languages option
specifies the languages that journalists have to choose from when creating articles. Countries
enables you to specify the name of a country in the local language for each territory. The
Localizer allows you to translate the administration interface. Clicking Logs will show you the
recent activity of all staff users, including the IP address that they have logged in from.




USERS
Here you can add and edit staff users, and manage subscribers. You can also define staff user
types, or synchronize user accounts between Campsite and Phorum, a popular web forum
system.




50
PLUGINS
This sub-menu provides access to additional functionality for Campsite, including blog, interview
and poll plugins.




HELP
Links you to the on-line version of this manual, as well the latest news and information about
Campsite on the Sourcefabric website. You can also send a support request email by clicking on
'Feedback'.




                                                                                                    51
19. CREATING A PUBLICATION
Campsite content is organized in a hierarchical structure, which conforms to the tradition of
newspapers and magazines: Publications, Issues, Sections and Articles. Each publication is made
up of issues; each issue is in turn made up of sections, which are comprised of articles. A
'breadcrumb trail' of links is present on every screen, which enables quick navigation between
different levels of the publishing hierarchy.

For example, after creating a publication named the "Prague Times", by clicking on "Prague
Times" in Campsite's list of publications, you enter the list of issues for that newspaper. By
clicking the name or number of a particular issue, you enter its list of sections. By clicking the
name of a section you enter the article list. By clicking the article title in that list, you can edit
the article.

To create a new publication, click Content on the main navigation menu, and then click
'Publications' from the sub-menu. On the Publication List page that appears, click on 'Add new
publication'.




If your login account does not have administrator rights, you will not be able to see the 'Add new
publication' option. You may need to ask your system administrator to enhance your access
rights. Bear in mind, however, that a good administrator would be reluctant to hand over those
rights to more than a handful of people. If you are not among those select few, your Publications
List will only contain the publications already hosted on your Campsite server.

The Add new publication window has three areas; General attributes and Comments on the left,
and Subscription defaults on the right. There's a Save button beneath these areas.




52
GENERAL ATTRIBUTES
  Name of the publication (e.g. "Prague Times")
  Default Site Alias is the name of the web server on which your publication will be hosted
  (e.g. campsite.example.com). Campsite enables multiple publications to be hosted on the
  same web server, providing that a unique alias has been set up for each publication by
  your system administrator
  Default Language sets the default language of the publication for readers
  URL type selects between the display of full path URLs, or short URLs which are better for
  pasting into newsletters and social media posts

COMMENTS




                                                                                               53
      Comments enabled? Check this box if you would like your readers to be able to
      comment on articles
      Article comments default to enabled? If you check this box, then article comments for
      any new article will default to "enabled"
      Subscriber comments moderated? If you check this box, comments by subscribers will
      be hidden from readers until they have been reviewed by a staff member
      Public allowed to comment? Check this box if non-subscribers will be allowed to make
      comments on articles
      Public comments moderated? If you check this box, non-subscriber comments will be
      hidden from readers until they have been reviewed by a staff member
      Use CAPTCHA to prevent spam? The reader must type in random letters or numbers
      shown before they can post a comment
      Moderator address If comments are moderated, each time a comment is posted an email
      is sent to this address, such as editor@example.com
      From address is the sender email address shown on the email sent to the moderator,
      which should be a valid address in case of bounces. An address such as
      robot@example.com is suitable




SUBSCRIPTION DEFAULTS
The rest of the fields are related to subscriptions, which you can adjust later if you wish. First,
you have to select a time unit for your subscriptions; which could be days, months, weeks or
years.

You can set two types of subscriptions: paid and trial. Paid subscriptions have the following
properties:

      Currency: the subscription currency. Even if a subscription request is sent and the
      currency setting is changed before payment, the information about the subscriber's
      payment due is correctly recorded
      Time unit cost per one section:
            for one language: the price for access to a particular section in a single language
            for all languages: the price for access to a section in all available languages
      Default time period: the usual duration of the paid subscription. This value is used when
      a reader subscribes through the website. The period for a particular subscription can be
      modified from the administration interface

After clicking the Save button, Campsite will confirm that the new publication has been created.




54
On the right hand side under the "Subscription defaults" fields, there will now be a link "Set
subscription settings by country" which will enable you specify different default time periods for
individual countries. This link opens the "Subscription Settings by Country" page, which has a link
"Set subscription settings for a country".




If you follow this link, it opens a page with a drop-down menu for selecting the country in
question, plus fields for the default trial and paid subscription lengths.




Clicking the Save button returns you to the "Subscription Settings by Country" page, which
should now show the setting you have just made.




                                                                                                      55
56
20. CREATING A NEW ISSUE
Once you have successfully created your publication, click on its name in the Publication List (e.g.
"Prague Times"). This will lead you to the Issue List, which will be empty to begin with.




Click on the 'Add new issue' link. If you are creating the very first issue, you will see a page with
fields for basic information which you will need to enter.




The Name is the name of the issue in the particular Language you specify in the drop-down box
underneath. The Number is a unique identifier for this issue. If this is the first issue you've ever
published, then number "1" would be fine. The issue number cannot be changed once it is
specified.

If you are planning to add older issues of your publication at a later stage to the same Campsite
server, you may consider continuing the series. For example, if you just published issue 154 of
the "Prague Times" before moving to Campsite, you should assign number 155 to the first issue
you are creating with Campsite.

The URL Name is only useful if you specified the "URL type: short names" option when you
created your publication. This name will show up in the reader's browser address bar. For
example, if you enter "2011_1" here, the address for the issue might look like this:
http://campsite.example.com/2011_1




                                                                                                        57
Clicking the Save button takes you to the Change Issue Details page, where various options for
the issue are set. On the left hand side, there are settings for the default templates for the
front page, sections and articles. If you do not have your own templates yet, you can select
templates from the 'classic' sample set that are provided with Campsite. Reader polls can also
be set up and edited on this side of the page.




On the right hand side of the Change Issue Details page are boxes which enable you to set the
publishing schedule for the issue. An issue can be set to be published at a specific date and time,
and unpublished at another date and time.




58
COPYING A PREVIOUS ISSUE
If this is not the first issue you've created, you will see a different page after clicking the "Add
new issue" link in the Issue List:




"Use the structure of the previous issue" will be the usual option to choose once you are ready
to publish additional issues, because it automatically creates a new issue with the same sections
as the preceding one. Clicking this option opens a page which enables you to specify the new
issue number.




                                                                                                       59
The sections of the new issue will be empty, so that you can begin to add articles. Before that,
the first step is to set the name of the new issue, because this field is not automatically
updated: it will start out with the same name as the last issue. After changing the Name field,
click the Save button to update the new issue.




The previous templates are not copied to the new issue automatically, so the new issue must be
linked to at least a template for the front page.




60
21. CREATING A SECTION
By clicking on the name of an issue in the Issue List, you will enter the Section List. At first, a
new issue will have no sections.




If you click on the 'Add new section' link, you will see the corresponding page appear.




                                                                                                      61
Here you must specify the Name, section Number, and URL name. While you can change the
name of the section later, the section number is set at the time when the new section is added.
The URL name will be part of the URL if you are used the "short names" option when you
created the publication.

The section Description is optional. This field is useful for displaying content that doesn't change
very often. The information in this field will only be displayed on your site if the template you are
using supports it. If you would like to make the new section available to all existing subscribers,
you should check the box for this option. Then click the Save button.

Your next step is to set the templates for the new section on the Configure Section page.




Here, you may wish to select custom templates for this new section and its articles from the
drop-down menus. If you don't have custom templates for specific sections, you can use general
section and article templates instead.



62
63
22. CREATING ARTICLES
The Article List for a particular section can be found by clicking on Content in the main Campsite
navigation menu, and following the hierarchy of Publications, Issues and Sections. Alternatively,
use the 'breadcrumb trail' of links just below the main navigation menu. You can create a new
article by clicking the "Add new article" link at the top of the Article List.




The "Add new article" page contains three fields for entering basic information about the article
you will create.




      Name: The title of the article. You will be able to rename the article at any time in the
      future

      Type: Select one of the available article types from the drop-down menu. If you have not
      set up any article types yet, only the default of "News Article" will be available. The choice
      you make at this stage cannot be altered later

      Language: Select the language the article will be written in. A drop-down list will contain
      the additional languages you have defined for this publication, if any. The language choice
      you make at this stage is final, though you can create a translation into another language
      later

When you click the 'Save' button, you will be taken to the Edit Article page.



64
23. EDITING ARTICLES
The appearance of the "Edit article" page depends on the article type you are working on. Below,
the default "News Article" type is shown. At the top left are the Actions and Status drop-down
menus.




Actions menu

The Actions menu contains short-cuts to commonly used functions:

      Unlock: When you begin editing an article, you automatically "lock" it to prevent conflicting
      edits from other users on the server. Using the Unlock option means that other authorized
      users can edit the article again
      Delete: Removes the article permanently from the Campsite server
      Duplicate: Copies the article to any publication, issue, or section on the same Campsite
      server
      Translate: Creates a new copy of the article for translation into another language
      Move: Moves the article to another publication, issue or section on the same Campsite
      server

Status menu

The status drop-down menu indicates the copy flow state of the article. There are three states
that the article can be in:

      New: The article is still being written. Once the contributors are ready for the article to be
      seen by the editor, they should change the status to "Submitted"
      Submitted: The article is under review by the editor or editors. Once the editors decide
      that the article is ready for the public to see, the status should be changed to "Published",
      or scheduled for publication at a later date and time
      Published: The article is now viewable by the public on the publication's website

Language menu

If multiple languages have been configured for the publication, a drop-down menu will enable fast
switching between translated versions of the article. If not, the language of the article will be
displayed here.

Edit/View buttons

There may be times when you want to view articles rather than edit them. In this case, clicking
the "View" button speeds up the page display process. It also enables you to view an article
when it is locked by another user on the server.

THE EDITING AREA
Below the Actions and Status drop-down menus is the editing area for the article. It begins with
three buttons; Preview, Save All, and Save and Close. Preview opens a pop-up window
showing how the article will appear to the reader once it is published. Save All saves the fields in
the edit area without closing the page, whereas Save and Close both saves the page and closes
it, unlocking the page for other authorized users to edit further.


                                                                                                       65
The "News article" type has the following fields:

      Name: The title of the article
      Author: This drop-down menu enables you to credit multiple contributors, including Author
      or Writer, Photographer, Editor, and Columnist. Type the contributor name in the box to
      the right. Click the green plus sign icon to include additional contributors
      Created by: the name of the Campsite user who created this article. You cannot change
      this field
      Reads: A number indicating the popularity of this particular article. An article which has
      not yet been published will display N/A here
      Type: Refers to the "article type", i.e. the format of the article. You cannot change this
      field once it has been assigned
      Number: The article's unique identification number
      Link to public page: If the article is published, this link displays the URL that the readers
      will see
      Creation date: Since this field can order the way your articles are displayed to readers,
      you can change this date if you choose
      Publish date: If displayed as N/A, this article hasn't been published yet
      Show article on front page: Check this box if you want the article to be displayed on
      your publication's homepage
      Show article on section page: Check this box if you would like the article to be displayed
      on the relevant section page
      Visible to non-subscribers: Check this box if you want to make the article visible to
      readers who have not yet subscribed
      Comments: Enable readers to make comments on the article, if you wish. Your templates
      must be designed to allow this feature. The drop-down box can have one of three values:
      enabled, locked, or disabled. "Locked" means that no one can post comments, but any
      existing comments are still shown
      Keywords: words that describe your article to search engines
      Deck: a sub-heading or article teaser
      SMS: a short version of the article, suitable for sending via a text message gateway to
      phones which support the Short Message Service. The length of an SMS text message
      depends on the alphabet used, from a maximum of 70 characters in Chinese or Cyrillic
      alphabets, up to a maximum of 160 characters in the Latin alphabet
      Body: the main section of the article




66
Other article types may contain different fields. Whenever you edit any of the fields, you will
need to click either the Save All button at the top and bottom of the edit area, or any of the
Save buttons to the left of individual fields. If the text content of a field has not been updated
since the last save of the article, the individual button displays the label Saved.




Note that date fields have a fixed syntax of YYYY-MM-DD (four year digits, two month digits and
two day digits, in that order). If you enter dates in any other format, you may get incorrect
results.

THE SIDEBAR
                     To the right side of the edit area is a vertical bar containing further options
                     for the new article. Click the link to the right of the green cross icon to open
                     a pop-up window for the relevant action. Click the white cross in a red
                     square icon to remove an item or event that was previously attached to
                     the article.

                     Saved: Displays the last time the article was saved
                     Publish Schedule: Schedule the article to be published or unpublished at a
                     certain date and time
                     Comments: Displays how many comments have been made on the article,
                     and enables you to toggle whether the comments are shown at the bottom
                     of the Edit Article page
                     Images: You can attach images to your article which can be included
                     directly into an article body field, or used in the template
                     Files: You can attach any kind of file you wish to the article. The article
                     template must be set up to display these files if users are to have access to
                     them
                     Topics: Select from a list of topics and subtopics defined by your Campsite
                     administrator by clicking on the Edit link. Topics allow you to set attributes
                     for the article, which may be used to display the article in a certain way
                     Audioclips: If this feature has been enabled, you can attach audio files from
                     a Campcaster broadcast automation server to Campsite articles. Audio
                     clips can be reordered by dragging and dropping, then clicking the save icon
                     Polls: add a specific reader voting poll to a specific article




PREVIEWING THE ARTICLE
While you are editing the article, you can see what it will look like when it is live on the web site
by clicking the Preview button. The layout that readers will see when they visit your web site is
controlled by the templates which your system administrator has installed. To be able to
preview article and publication layouts, make sure you have configured the issue in question with
the appropriate front page and article templates.




                                                                                                        67
At the bottom of the preview window, you can see information from Campsite's template
parser. If any problems occur while generating the web pages, the parser will display error
messages. These should help you to identify any problems in the template structure, which you
should report to your system administrator or template designer. Once you're finished with the
preview window, click the icon in the upper corner of the window bar to close it, in the normal
way.




68
24. USING THE TINYMCE EDITOR
The body field editor in Campsite (a program called 'TinyMCE') allows contributors to perform
extensive article formatting from within a web browser. You may be familiar with most of the
functions of TinyMCE from using word processors such as Microsoft Word or OpenOffice.org:
functions such as bold, italic, underline, and text alignment. Move your mouse over the icons to
see a tooltip explaining what they do. Standard formatting keyboard shortcuts also work (e.g.
ctrl+b for bold, ctrl+i for italic).




The editor field you see on your own Campsite installation may look different than the one
pictured above, depending on the extent of your user rights. Typically, the editor you'll see is the
one that contains all the functionality you need for your site, but if you feel something vital is
missing, discuss it with your Campsite system administrator.

There are two Campsite-specific features in the editor. The first is Insert internal link, which
allows you to include links to articles within your Campsite publication.




Clicking this icon opens a pop-up window with drop-down menus enabling you to select a specific
language version of a publication, issue, section and article to link to.




                                                                                                       69
After you click the Insert button, the internally linked text will be shown in blue and underlined,
like a web link.




The second Campsite-specific feature is Campsite Subhead, which allows you to break your
text into different pages. (Your templates must be configured to use this option).




Enter the text for the subhead into the editing window, select it with the mouse, then click the
Campsite Subhead icon. The subhead text will now be shown with a dashed outline.




70
25. MANAGING CONTENT
The "Article List" page is displayed when you enter a particular section via the Content menu, by
following the hierarchy of publications, issues and sections. Alternatively, use the breadcrumb
trail to jump to the section that you're interested in, and then click the "Go to Articles" link.




To edit a specific article, simply click on its title, and you will be taken to the "Edit Article" page.
A locked article is one that is being edited at that moment, as shown in the list by a padlock icon
to the left of its title. Articles that are being edited by other contributors are marked with a pink
background, in addition to the padlock icon.




                                                                                                           71
To find out who is editing the article and when it was locked, click on the article title in the list. A
page will open with buttons offering the option of unlocking or simply viewing that particular
article.




MULTIPLE ACTIONS
The Article List allows you to perform other actions besides editing the article, and you can
perform these actions on multiple articles at once. To perform an action on one or more articles,
click the checkbox to the left of the article number and title. The articles you have selected will
be highlighted with an orange background.




Now that you have selected the articles, go to the "Actions..." drop-down menu at the top of the
list, and select the action you would like to perform:




72
For example, if you select "Status: Publish with issue", Campsite will publish the selected articles
at the time the issue they are a part of is published. The page will refresh, and a message will
display "Article status set to 'Published'".




Some actions will take you to another page, because they require further input from you. The
article list also allows you to rearrange articles as they appear on your section page, if your
template supports this feature. To move an article's position in the list, use the blue arrow
buttons or select the position number from the drop-down menus in the Order column.




                                                                                                       73
Over on the right hand side of the Article List are additional columns which relate to other
functions, such as the Campsite user that created the article, and its publishing status. On the
far right side of each row in the list is a magnifying glass icon which opens a preview of the
article, and a flag icon which opens the "Translate article" page.




THE UNIVERSAL LIST
Campsite includes another tool which provides an overview of content across all publications on
the server. The Universal List is accessed via an entry on the Content menu, and has an
interface somewhat like a search engine. You can filter the search options according to a specific
publication, issue or section. Once you have set this initial filter, you can then filter by other
criteria, such as the author or date of the article.




74
26. PUBLISHING ARTICLES
An article in Campsite can have one of four different states: New, Submitted, Published, or
Publish with issue. When you create an article, the Status: drop-down menu at the top of the
editing area is set to New by default. Once your article copy has been drafted and is ready for
the editors to see, click on this drop-down menu and change the Status: to Submitted.




After changing the status to Submitted, the page will be reloaded, and a message will indicate
that the change in status of the article has been recorded. The editors will be able to see the
fresh submission when they log in to Campsite. Articles which are ready for editing are listed in
the default Submitted Articles view on the administrator homepage.




In addition, if their user accounts have been configured for notifications, an email will be sent to
the editors to inform them about the new submission.

Once the editors have made any required changes and are happy with the way the article reads
and appears, they can publish the article by changing the drop-down Status: menu to Publish
with issue. Again, the page will be reloaded, and a message will indicate that the article's status
has changed.




                                                                                                       75
When an article status is set to Publish with issue it becomes visible on your public web site,
as soon as the issue it belongs to is published. This feature enables co-ordinated publishing of
complementary articles when a complete issue is ready for the public. You can check the
publication status of a particular issue in the Issue List. If the issue in question has already been
published, then new articles can be seen by the public immediately after their status is changed
to Publish.

The whole process is fully reversible, so you can unpublish articles on your site (or even change
their status to New) as easily as you can publish them. Note that only authorized users are
allowed to publish articles, so you will not be able to access this option if your system
administrator has not granted you this permission.

SCHEDULED ARTICLES
You also have the option to publish (or unpublish) an article at a specific date and time in the
future. You can do this from the Edit article page, using the Add Event link in the sidebar:




After clicking on Add Event, a pop-up window will appear with a calendar and a series of three
possible actions for the date and time that you choose: Publish/Unpublish, Show on front
page/Remove from front page, and Show on section page/Remove from section page.

76
Choose the date by clicking on the calendar, or enter a date code manually. Then enter the time
for the event, and choose one or more actions to perform at the time you have chosen. After
you click the Save button, the pop-up window will close, and the event will appear under Publish
Schedule in the sidebar of the Edit article page:




                                                                                                   77
Once the event is created, the actions will be performed automatically for you on the date and
at the time you specified. Over on the left hand side of the Edit article page, the Status drop-
down menu will change to Published. In advance of the publish event date and time, a clock icon
will be shown.




After the event time, the clock icon will disappear and the event will no longer be shown under
Publish Schedule in the sidebar.




78
27. PUBLISHING AN ISSUE
You can draft and edit articles for a particular issue on your Campsite server without any of the
material being available to the public. You can then publish an entire issue all at once, and there
are two ways to do it: immediately, or by scheduling the issue to be published at a specific date
and time in the future. Note that within an issue, you can publish or unpublish each article
individually; for instance, to hide an article even if the issue it belongs to has already been
published.

PUBLISHING IMMEDIATELY
To publish an issue straight away, click the Publish link for the relevant issue and language
edition in the Publish Date column of the Issue List.




A pop-up dialog will ask you to confirm that you want to publish the issue in question, because
this action implies that any articles which are part of the named issue will become available to
the public instantly.




After clicking the OK button, the issue will be published, and the Issue List will be updated with
the publication date and time of that particular issue.




                                                                                                      79
To reverse the process, click the Unpublish link. Again, a pop-up dialog will ask if you are sure
you want to change the issue's status.

SCHEDULED PUBLISHING
To schedule an issue to be published automatically at a specific date and time in the future, click
on the Schedule link for the issue and language edition you require in the Publish Date column
of the Issue List. This will open the Change issue details page, where you can set the date
and time for this particular issue to be published. Over on the right hand side of the page are the
Issue Publishing Schedule and Schedule a new action boxes.




Click the small calendar icon to the right of the Date: field to select a specific day for publication.
Set the time you require, and select either Publish or Unpublish from the drop-down Action
menu. Then click the Save button. The Issue Publishing Schedule box will update to display
the newly scheduled action.




80
Note that you can also set the issue to be unpublished at a specific date and time in the future
as well. This event will be displayed in the Issue Publishing Schedule box.




To cancel a scheduled action, click the corresponding white cross in a red box icon in the Delete
column. You will be asked to confirm the deletion.




An event date and time that has already passed will be shown crossed out. If you click on the
date/time link for a future event, the Issue Publishing Schedule page will open, and you will be
able to edit the event. Click the Save button to confirm the schedule change.




                                                                                                    81
82
28. ARTICLE COMMENTS
Reader comments can be switched on and off for a whole publication, for a particular article
type, or for each individual article. You can also take advantage of Campsite's management
features to moderate (or bypass moderation for) comments from subscribers, or members of
the general public.

COMMENT SETTINGS IN THE PUBLICATION LIST
To set the default comment setting at the publication level, go to Content on the main
navigation menu, and then click Publications. In the Comments enabled column of the
Publication List page which appears, publications in which readers can post comments are shown
with a green light icon. Click on the Configure icon for the publication you wish to enable or
disable comments for.




                                                                                                 83
This action opens the Configure publication page. In the Comments section, there is a
checkbox labeled Comments enabled? and a variety of options which enable you to fine-tune
comment settings.




84
COMMENT SETTINGS FOR ARTICLE TYPES
Perhaps you want to enable comments for all articles of a particular type, for example blog, but
not enable them for another type, such as news_article. Click Configure in the main navigation
menu, and then click Article Types from the submenu. On the Article Types page which
appears, clicking the red or green light icon in the Comments enabled? column toggles the
setting for each article type.




After you click on a green light icon, you will be asked if you are sure you want to deactivate
comments for that article type.




COMMENT SETTINGS FOR INDIVIDUAL ARTICLES
Comments can be enabled or disabled for a number of individual articles at once, using the
Article list page. Click Content on the main navigation menu, then use the submenus to
navigate to the publication, issue and section that you require. In the Article list page that
appears, use the checkboxes in the left side column to select the articles you want to enable or
disable comments for. Then use the drop-down Actions menu and click on Toggle: 'Comments'.




                                                                                                   85
86
29. MODERATING COMMENTS
To prevent spam or defamatory posts from appearing in your online publication, it's often
necessary to moderate comments from readers before they are published. A CAPTCHA can
prevent some automated spam, but it cannot prevent spam being entered into your publication's
comment form manually.




If you have configured your publication so that subscriber or public comments are moderated,
the reader will see a message indicating that their comment has been sent for approval before it
will be published - or not, as the case may be.




                                                                                                   87
The list of reader comments can be found by clicking Content, then Comments, on the main
navigation menu.




On the left hand side of the Comments page are two tabs; one for New comments, and one for
Published comments. The New tab is the default, and beneath this any new comments are
listed. The default list length is 20 comments per page. There is a Search field to help you find a
specific range of comments, perhaps on a topical subject. Search results can be sorted by Date
posted, Article name, Author or Thread, using the drop-down menu to the right of the Search
field. The sort direction can be changed by clicking on the blue arrow icon next to the drop-down
menu.




On the right-hand side of the Comments page is an area displaying the text and metadata of
the current comment under review, as indicated by a small yellow arrow icon in the comment
list.




88
A row of radio buttons above the comment text enable you to update the New comment's
status to Approved, or Delete if it is spam. Alternatively, the comment can be hidden, or the
user that made the comment banned from the publication. Clicking the Show article link, next
to the magnifying glass icon, enables you to see the comment in the context of the original
article. You can also click on the Article link to open the Edit article page for that particular
story.

CAMPSITE ADMINISTRATION
30. System Preferences
31. Templates
32. Article Types
33. Topics
34. Languages
35. Countries
36. The Localizer
37. Logs
38. User Management
39. Plugins




                                                                                                    89
30. SYSTEM PREFERENCES
The System Preferences page is accessed via Configure in the main Campsite navigation menu.




This page allows you to control some advanced aspects of your Campsite server, so it is
recommended that access is reserved for administrators only.

GENERAL SETTINGS
The first section of the System Preferences page is for General Settings.




90
Here is what each of the options means:




                                          91
      Site On-Line:These Yes and No radio buttons enable you to put the whole Campsite
      server on-line or off-line, for example in case of scheduled server maintenance
      Site Title: The default name for your publication's website. Your designer can configure
      your publication's templates to display this information
      Site Meta Keywords: The default keyword meta tags in your header template, for search
      engine optimization
      Site Meta Description: The default description meta tag in your header template, also for
      search engines
      Time Zone: This field enables you to override the server's own time zone setting, which is
      typically set to Greenwich Mean Time (GMT). You may wish for your Campsite interface to
      display local time instead, for instance when scheduling publication time for a particular
      issue
      Database Cache Engine:enables or disables the APC cache, which can improve Campsite
      performance
      Template Cache Handler: Select DB to enable the cache for templates
      Image cache lifetime: The time that images will be cached for, from 30 seconds to
      infinite
      Allow password recovery: Whether users can get a password reminder by email. Note
      that if this feature is enabled and your email account is compromised, your Campsite
      publication can easily be compromised in turn
      Secret Key: The security key that Campsite can use for integration of web services and
      other advanced features
      Session Lifetime: Enables you to specify the maximum duration of Campsite
      administration sessions without re-authentication, which is a security feature
      Keyword separator: Specify the separator for Keywords in the Edit Article page (comma
      or hyphen)
      Number of failed login attempts before showing CAPTCHA: A security measure
      designed to foil password-guessing robots
      Maximum upload file size: The maximum size of attachments that users of your website
      can upload
      SMTP Host: The server that Campsite will use for sending out email notifications
      SMTP Port: The port number that Campsite will use on the specified email server

EDITOR SETTINGS
The second section of the page is for Editor Settings, which refer to image handling.




The fields in this section enable you to specify the default resize ratio, or default width and
height, for images in articles. If the Zoom enabled for images in article content? radio button
is set to Yes, readers can enlarge article images in your publication's pages by clicking on them.

EXTERNAL SUBSCRIPTION MANAGEMENT
The third section down is related to external subscription management software.




92
If you select the Yes radio button for the Reader subscriptions managed externally? option,
the subscription management features in the Campsite administration interface are hidden. The
subscription data is still held in the Campsite database, which your systems administrator will
have connected to your third-party subscription management software.

DATABASE REPLICATION SERVER
The fourth section enables you to set up Campsite to operate on two servers at once, which is a
safety feature in case of hardware or network problems.




Selecting the Yes radio button for the option Setting up a Campsite Replication Server?
displays four fields:

      Database Replication Host: The name or IP address of the remote database server
      Database Replication User: The user name to connect with on the remote server
      Database Replication Password: The password to submit on the remote server
      Database Replication Port: The port number to connect to on the remote server (the
      default port number is 3306)

USING A CAMPCASTER MEDIA LIBRARY
The fifth section enables you to attach media in a Campcaster storage server to articles in your
Campsite publication. Once you've installed and configured Campcaster according to the manual
at http://en.flossmanuals.net/Campcaster, create a user in the Campcaster administration
interface and add it to the Admins group.




Back in the Campsite System Preferences page, select the Yes radio button for the option
Enable Campcaster audioclip attachments? Below, you should enter the host name or IP
address of the Campcaster server. The values of the fields Port, XML RPC Path and XML RPC File
should already be filled in with the default values. You don't need to edit these default values,
unless you have a custom Campcaster configuration.

The last step is to give certain users the right to attach audio clips to articles. You can edit a
Staff User Type to enable this, so that all users of this type will receive the right automatically.
Alternatively, you can enable this right for individual staff user accounts.
                                                                                                       93
OTHER OPTIONS
At the end of the System Preferences page are two further options.




     Templates filter mask: Enter keywords for templates that you wish to hide on the
     Configure - Templates page. For example, templates that are no longer in use, but you do
     not wish to delete from the server
     Run cron tasks externally? This means to use the server's own scheduler for automated
     tasks, rather than the one included in Campsite.

Finally, the Save button updates your preferences.




94
31. TEMPLATES
Templates control the look and feel of your Campsite publication. Each publication has a unique
template created by your web developer, which should have already been installed by your
system administrator. The Campsite administration interface includes a template management
and editing tool, which you can find by clicking Configure on the main navigation menu, then
Templates.




Templates are organized into folders, shown in a box on the left hand side of the page.




Clicking on the name of a folder shows the files included in that template.




                                                                                                  95
In turn, clicking on a file name opens that file in the template editor. This feature enables web
developers to make quick changes to templates on a running Campsite system.




You should only make changes to the templates if you know what you are doing, because any
modifications will have an immediate impact on the appearance of your publication. However,
this feature is useful for editing templates on a development server before they are copied to
the publication's production server.



96
32. ARTICLE TYPES
Article Types specify the information that Campsite will require from the journalists adding a
particular kind of article to your publication. For example, a feature story is likely to require
more elements than a brief news item. By default, Campsite has one Article Type set up, which
is News Article, but you can create as many as you need. To create or manage your Article
Types, select Configure, then Article Types from the main navigation menu. This action opens
the Article Types page.




Article Types consist of a sequence of fields, with each field holding a certain kind of data.
Currently, there are six kinds of fields available:

      Single-line text: this type of field can contain a maximum of 265 characters, and does not
      support HTML tags. Its appearance and character set is entirely determined by the
      template in use
      Multi-line text with WYSIWYG: this type of field can be up to 16MB in size. The journalist
      can insert images, audio, video, links (external, internal or to attached files), and formatting
      tags. Subheads can be used for article pagination
      Date: this is a standard date field with a fixed syntax of YYYY-MM-DD (four year digits,
      two month digits, two day digits, separated by hyphens)
      Topic: this type of field can be used to categorize articles. Each topic field has a top level
      element, for example Entertainment / Review. When the journalist types the article into
      Campsite, this field will display a drop-down menu containing available subtopics of that top
      element, such as Movie Review or Theater Review
      Switch: allows you to add check boxes which activate particular features to the Edit
      Article page. For example, you might add a switch breaking_news, which would be used by
      your template to display the article in a special place on your site. (Campsite comes with
      two switches by default, Show article on front page and Show article on section page)
      Numeric: allows you to add numeric elements to your articles, such as longitude/latitude,
      temperature, or exchange rate

Campsite makes a distinction between the Template Name and Display Name for each Article
Type and field. The Template Name is limited to letters, numbers, and underscores (no spaces)
and is used internally by your Campsite template. The Display Name is the part that the
journalist will see, and can be translated into other languages.

ADDING A NEW ARTICLE TYPE
Click the Add new article type link at the top left of the Article Types page.


                                                                                                         97
The Add new article type page will appear. The first step is to enter the Template Name of
the Article Type you wish to create. In this example, we'll create an Article Type with the
template name review_article - note that it has an underscore, instead of a space, between the
words review and article.




After you click the Save button, you will be prompted to enter the Template Name of the first
field in the new Article Type. Select one of the six field types available from the drop-down
menu, for example Topic. For this particular field type, we'll also have to select a top level
element, such as Entertainment / Review.




After clicking the Save button, the Article type fields page is shown. The Article Type that you
are currently working on is shown in the breadcrumb trail beneath the main navigation menu.




98
Click on the Show display names link to add a Display Name for this new field. Select the
language you require from the Add translation drop-down menu, and enter the display name for
the new field in this language. Then click the blue Translate button.




The Article type fields page will now show the Display Name for the field, together with a
language code (in brackets) to indicate its translation. Note that the Display Name can contain
spaces, or be capitalized differently from the Template Name for the field.




Continue to add new fields to this Article Type, until you have all that you need. Then click the
link Back to Article Types List, next to the blue arrowhead icon. This action will return you to
the Article Types page.

EDITING ARTICLE TYPES
                                                                                                    99
You can add translated Display Names for your new Article Type after clicking on the Show
display names link in the Article Types List.




Article Types are not set in stone; they can evolve as your publication evolves. For example, you
can hide old Article Types that are no longer in use. Toggle whether a type is shown by clicking
on the colored light icon in the Show/Hide column - green for shown, red for hidden. A pop-up
dialog will ask you if you are sure about this action.




Hiding a type is less dangerous than deleting it; the latter action will remove the associated
content from the server. The delete button is a white cross in a red square icon, over on the
right side of the page. Use this button with caution!




As usual when carrying out an action that will have an impact on your publication, Campsite will
ask you if you are sure.


100
In the Article Types List there is also a Comments enabled? column, which toggles readers
comments on and off for a specific Article Type. For example, you might wish to disable reader
comments for all entertainment reviews, but leave them enabled for news articles.

Article types can be renamed, simply by clicking on the Template Name in the Article Types
page. Remember that if you change a Template Name, you cannot put spaces into it.




EDITING ARTICLE TYPE FIELDS
On the Article Type Fields page, fields can be renamed, given Display Names, hidden or
deleted, just like Article Types. When you have more than one Article Type field, you can re-
arrange the order in which the fields show up on the Edit article page by clicking the blue up and
down arrows.




To change a field type, for example, from Single-line Text to Multi-line Text with WYSIWYG,
click on the corresponding link for that row in the Type column. The Reassign a field type page
will open, on which you can select the new type from a drop-down menu. Then click the Save
button to return to the Article type fields page.




                                                                                                     101
After editing article type fields, you could create a new article to test that the updated fields are
displayed as expected.




MERGING ARTICLE TYPES
Campsite enables you to merge two different Article Types so that content in fields from one
type (the Source Article Type) is migrated to another (the Destination Article Type). This is a
useful process to go through after adding or editing an Article Type, so that all previously written
copy matches the new Article Type fields.

On the Article Types page, click the Merge types link. This opens the Merge article type page.
Select the source and destination Article Types you wish to merge from the drop-down menus.




102
Next, choose the fields of the source which you'd like to merge into fields of the destination.




The next screen displays the result of the potential merge. Any source fields which have not
been mapped to destination fields are shown in a red font. You may need to create additional
fields in the destination Article Type before attempting a merge.

You can cycle through all the articles which will be merged, and preview the changes. Optionally,
check the box to Delete the source article type. When you're ready, click the Merge button.




                                                                                                    103
If there are no articles left belonging to the Source Article Type, Campsite will display a warning
message at the first step of the proposed merge.




104
33. TOPICS
In Campsite, topics are the subject matters assigned by editors and journalists to articles, so
that related articles can be identified and displayed together. A topic can have many subtopics;
for example: the sports topic could have the subtopics football, basketball, and water polo. An
individual article may have several topics or subtopics assigned to it.

To review or create topics, click Configure on the main navigation menu, then click Topics from
the sub-menu.




To add a new top-level topic, select a language from the drop-down menu and enter a word in
the Add root topic field. Then click the Add button.




                                                                                                   105
To rename a topic, click the Edit link to the right of the topic or subtopic name. The name row
will expand to show the Change topic name field. Update the name, and then click the Save
button.




You can translate topic names so that they appear in the correct language when an author is
editing an article. To translate a topic, click the Edit link to display the Add Translation field for
that topic name. Select the language you are translating into from the drop-down menu, enter
the translation of the topic name, and then click the Translate button.


106
If you translate a subtopic and its parent has not yet been translated, the parent topic will
appear in its original language until you translate it.

To add a subtopic, click the Edit link next to the topic you want to put the subtopic under. Enter
a word or two into the Add Subtopic field, then click the Add button.




The new subtopic will appear underneath its parent topic.




                                                                                                     107
You can delete a specific topic or subtopic using the blue cross in a white square icon, on the
right hand side of its row. However, you cannot delete a topic currently in use by articles, or a
topic that has any subtopics remaining. Campsite will remind you if this is the case.




108
34. LANGUAGES
While Campsite's default language is English, you are by no means limited to publishing in that
language only. Click Configure on the main navigation menu, then Languages from the submenu,
to see the languages currently available on the system.




The Language page enables you to configure support for languages that you wish to publish in.
The Code column refers to the two-letter ISO 639-1 code name for each language. English, for
example, is en, German is de, Spanish is es, Chinese is zh and so on.




                                                                                                  109
Click on a name in the Language column to open a page for that language, which enables you to
adjust month, day and time name translations. This feature ensures that automatically
generated publication dates and times for an article in a particular language are displayed
correctly to your international readers.




110
To add another language, click on the Add new language link, next to the green cross icon. You
should enter the language name (both in English and in the language itself), and its code (e.g. cy
for Welsh).




After entering translations in all the fields, click the Save button at the end of the page. The new
language will now be shown on the Languages page.




                                                                                                       111
You may wish to limit the number of languages configured on your server, in order to spare your
editors and journalists from having to navigate long drop-down language menus. To remove a
language, click the white cross in a red square icon at the end of each row in the list. You will be
asked if you are sure about this action.




112
35. COUNTRIES
This page determines how country lists will appear in forms that readers fill in, for example when
signing up for an email newsletter. It also enables you to create country lists in different
languages. To see the list of country names in the default language, click Configure on the main
navigation menu, then Countries on the submenu.




The Countries page shows an alphabetical list of countries, with the language they are displayed
in, and a two-letter ISO 3166-1 country code for each name. Note that the alphabetical sorting is
by the country code, rather than by the country name.




                                                                                                     113
Click on the name of a country to rename it, then click the Save button to return to the country
list.




To translate a specific country name into a particular language, click the Translate link in that
country's row in the list. In the Translate country name page, select the target language from
the drop-down menu, and enter the translation into the Name field. Then click the Save button.

114
To find your translated country names later, use the drop-down Language menu at the top of
the Country page to select the language you are interested in, and then click the Search button.
The search results, if any, will be listed below the Search box.




Campsite's list includes almost all known countries by default, but if you have deleted a country
and need to put it back, you can do this by clicking on the Add new country link next to the
green cross icon. You will be prompted to enter the country's two-letter ISO code, name and
language. The drop-down menu will contain as many languages as you have defined in Campsite's
Configure - Languages page.




Note that the language you are asked to specify is the language in which you are entering a
country's name, not the language spoken in the country.


                                                                                                    115
36. THE LOCALIZER
The default language for the Campsite administration interface is English, but you can either use
one of the many translations supplied with Campsite, or create your own translation using the
built-in Localizer tool. You can also use the Localizer to improve an existing translation, or adapt
it for a regional dialect.

The first step is to check that the language you wish to translate into is in the Configure -
Languages list. If your target language does not exist yet, you will have to add it to Campsite
first. Then, you can open the Localizer by clicking Configure - Localizer on the main navigation
menu.




The Localizer works by enabling you to translate individual 'strings' of text that appear in the
Campsite administration interface. There are around 1893 strings in the whole of Campsite,
divided into 36 Screens representing the various different pages in the interface. You can
complete a localization with a team of translators working together, by tackling one screen each
at a time.




116
Select your source (Translate from) and target (Translate to) languages from the drop-down
menus, and then select a Screen, such as Universal List or Article Types. Strings that have not
yet been translated are shown in a red font. You can save your work at any time by clicking the
disk icon next to one of the input fields. When you have completed your translation, there is a
Save button at the end of the page.




You will encounter strings with a dollar sign in them, e.g. "$1". This means that one or more
words will be substituted in place of these characters. For example, the phrase "Signed in: $1",
when printed out on the interface, might be: "Signed in: Administrator". In this example,
"Administrator" was substituted for "$1".

TinyMCE, the WYSIWYG article editor incorporated into Campsite, can also be localized. The
strings in TinyMCE have to be edited manually by your system administrator, which is a task
done separately from the Localizer.

SENDING A LOCALIZATION BACK TO THE CAMPSITE TEAM
                                                                                                   117
We actively encourage Campsite users to send us their language localizations. This makes
Campsite more useful for people around the world. Even if a similar language localization exists,
it may not address your particular needs or regional differences. For example, there may be
differences in Spanish between that used in Spain and that used in Guatemala. In that case, you
can localize Campsite to your needs and share the localization with other users that speak your
language or dialect.

For more information on how to contribute a localization to Campsite, please email
contact@sourcefabric.org




118
37. LOGS
The Campsite administration interface includes a feature which enables you to keep track of who
has done what, and when, on your publication's server. You can examine Campsite's log files by
clicking Configure on the main navigation menu, then Logs.




The default log view displays all recent events on the Campsite server, with 15 listings per page,
and the most recent events first. Click the Next link or page number just above the search
results box to see previous pages. Like most features in Campsite, the Logs page is multilingual,
so you may see log entries in languages other than your own.




                                                                                                     119
To examine the logs selectively, use the Event drop-down menu above the search results box to
select a particular action; for example, Add Article. Then click the Search button, and the Logs
page will be refreshed to list events corresponding to that action exclusively.




120
38. USER MANAGEMENT
Campsite's user management allows you to control access to the backend and the frontend of
your publication(s). Backend users are called Staff users and frontend users are called
Subscribers. You can define roles for your staff members, such as Journalist and Editor. The
interface will change for each user depending on which permissions they have enabled. For
example, a journalist will have a more simple interface than an editor.

Your subscribers are most likely paying for access to your content. When you edit an article,
you have to option to make the article only viewable to subscribers.

IMPORTANT: Initially, the Campsite demo packages have only one user: admin with admn00
password. Make sure to change the password as soon as possible. Also, do not delete this user
as it is needed by the email script which informs Staff users of events in the system. You should
set the email address of "admin" after installation because it is used as "Reply-To" address in
the notification emails.




CREATING USER TYPES
A user type is generally defined by the list of the tasks a user is allowed to do in a system. In
Campsite, this list of tasks ranges from creating, managing, and editing publications, sections, and
articles, to template management and definition of the publishing environment.

To simplify user management, Campsite allows you to create generic user types, which can then
be assigned to multiple users, instead of taking care of every single access right for every single
user.

Campsite comes "out of the box" with three default user types:

      Administrator - user with full authorization, i.e. all rights (normally reserved to
      webmasters)

      Chief Editor - user with higher editorial rights (e.g. has a right to create and delete issues)

      Editor - standard back end user with rights limited to basic article management and editing
      (normally assigned to journalists and editors)

To create your custom user profiles, select 'Users'->'Staff User Types' from the main menu:




                                                                                                        121
and then select 'Add new user type'. Proceed to select the rights that you want included for this
type of user.




CREATING STAFF USERS
To add a user, select Users->Staff from the main menu:




122
and then choose 'Add new user account'. You will see this screen:




You should specify the full name of the user, user name, password, and choose a predefined
user type (i.e. one of the default types or your custom user types).

If you would like to further fine tune the rights assigned to a particular user, go to Users->Staff
and click on the user name you wish to edit.




SETTING UP SUBSCRIPTIONS
In this section:

      Username/Password Access
      IP Address Subscriptions
      Customizing the Subscription Form

Campsite allows you to control public access to your publication(s) through its built-in subscription
module.

[TIP: If you want to have all your content freely accessible, you can bypass this feature by
structuring your templates in a special way. For more information see "Creating Templates for
your Publication" chapter.]

For now, you should know that all articles you create in your publication(s) are by default
available to subscribers only. Publication editors or administrators have the right to make an
article accessible to non-subscribers.

The way it works from readers' side is as follows: If a reader tries to access a non-public article,
she is informed that she is not allowed to read the article but is provided with an option to
subscribe immediately to that article or other articles or the whole publication. A temporary
subscription is activated immediately (the duration of that temporary subscription is determined
by the value you set for the 'Pay Time', For more information, see "Creating a Publication"
chapter). During this period, the reader has a chance to effect the payment and consequently
have her subscription extended by the administrator.

The publication's administrator is automatically notified of all new subscriptions by e-mail.
Subscribers also receive automatically generated e-mail reminders that their subscription is
expiring 14 days before the event.



                                                                                                        123
[NOTE: The text of the subscription-expiry message is hard coded in the current version of
Campsite and it reads as follows:

"Dear <reader>,

This is an automatically generated e-mail message. Your <subs_type> subscription (started on
<start_date>) to publication <publication> will expire on <date> (in <number> days).

Please enter the site http://<pub_site&gt; to update subscription."

Future versions of Campsite will allow for customization of the message and for its translation
into multiple languages.]

Campsite allows you to control access to your site in two ways:

      Standard UserName:Password pairs, which is suitable for individual users
      IP Address access, which most institutional subscribers (libraries, universities, NGOs,
      companies, etc.) tend to prefer

As Campsite handles subscriptions at the publication level, all subscription-related variables are
customizable from the Publication Configure screen:




First you have to select a time unit for your subscriptions; the time unit can be: days, months,
weeks and years.

You can set two types of subscriptions: paid and trial. Paid subscriptions have the following
properties:

      Currency: the publication's currency. Even if the subscription request is sent and the
      currency is changed meanwhile, the information about the user's debt is correctly
      recorded.
      Time unit cost per one section:
            for one language: the price for access to a section in a single language
            for all languages: the price for access to a section in all available languages
      Default time period: the default duration of the paid subscription. This value is used whe
      a reader subscribes through the frontend (site). The period for a certain subscription can
      be modified however from the administration interface.

You can specify different default time periods for individual countries if you like. To do so, click
on "Countries defaults". You will then have the option to "Add new country", i.e. create
subscription preferences for a given country.




124
Username/Password Access

Campsite allows readers to subscribe to one publication at a time. Within a publication itself, the
level of subscription is the section. The reader is able to select any section from the list of the
publication's sections, and for each of them specify the period of time he would like to have a
subscription for.

Before submitting his request, the user (reader) can evaluate the cost of the subscription and
change it. At any time later, he can subscribe to additional sections. Once the user has
subscribed to a section, he can't increase the period of time for the subscription until payment is
done for that section.

Immediately after the completion of the subscription form, the reader has the right to view the
site. By default, the reader has seven days to make a payment and have his subscription
confirmed by the administrator or else the account is locked.

The authorized person can confirm the payment, so that the subscription remains active after
the first 7 days. There are two options in the administration module for that: change the value
of the amount that the subscriber has to pay, or change the number of days the subscriber is
allowed to surf the publication's site. By default, if this sum is set to 0 (zero), the number of paid
days is automatically set to the number of requested days.

The administrator (or any other user who has the rights to manage publications) has 7 days to
confirm the payment. The confirmation is made from the main menu, by selecting User and then
Subscriptions. The confirmation consists in changing the payment status (from 'no' to 'yes').



IP Address Subscriptions

The IP based access can be used to automatically log in users that have known IP addresses that
never change. Examples of this are libraries, colleges, schools etc. The IP address-based access
works by recognizing a computer as owned by a certain subscriber based on the computer's IP
address. Subscribers with IP address-based access will be allowed to accesss the site without
being prompted for user names and passwords.


To create an IP-Address subscription, go to the Subscribers screen:




You will get to a screen that looks something like this:




First create a regular user by clicking on "Add new user account", edit it by clicking on the "Full
Name" link in the subscriber list and click on "Add new" link in "User IP access list management"
table (see image number 3). The form allows the input of a group of consecutive IP addresses. If
necessary, more groups can be added. The start IP address is the smallest address in the group,
while the number of addresses sets the size of the group.

                                                                                                         125
For example, if a university library had a group of IP addresses: 120.120.120.0 to 120.120.120.63
then you would fill in:

      start IP address: 120.120.120.0
      number of addresses: 64 = 63 - 0 + 1

It is not necessary to add anything to the templates or to inform the users who will be accessing
the site through IP address authentication of the existence of this User Name/Password pair.

It is possible to search for users based their IP addresses. In the subscribers list fill in at least
one box in the field named "IP address" from left to right. The administration screen will display
all readers that have IP addresses matching the input. For example, if we had two clients, one
with IP access group: 120.120.120.0:64 (start IP address 120.120.120.0, 64 addresses), the other
one with IP access group: 120.120.140.0:64 then we will have the following results:

      filling in 120.120 in the IP address field will return both clients
      filling in 120.120.120 will return only the first client: the second client's IP access group
      120.120.140 doesn't match our input
      filling in 120.120.120.10 will return the first client
      filling in 120.120.120.80 will return an empty list: the IP access group of the first client stops
      at 120.120.120.63



Customizing the Subscription Form

The subscription interface for the user is customizable. Depending on the user's status, several
steps must be taken by a user in order to be able to read the publication. There are three
possible scenarios:

      The user has never subscribed. In this case, the user is served a subscription form (name,
      login, password, email etc). After the completion of this form, the user can start
      subscribing to any section

      The user has already subscribed (i.e. is a known user to the system) but only to a few
      sections. In this case, he or she wants to add more sections to the subscriptions they
      have already made - some of which might have expired. The user should be served a
      different subscription form (reflecting his status as a known user).

      The user is not known to the system even though his subscriptions are active (e.g. the
      subscriber hasn't logged for a long time). A login form must be supplied for such a user.

The template designer can customize all those forms by means of Campsite's template language.




126
39. PLUGINS
Plugins enable your system administrator to add functionality to your Campsite installation
without having to write a large amount of code. They can also enable you to make better use of
the content and templates already in your Campsite publication. Currently, there are three
plugins installed by default with Campsite:

      Polls: A mechanism for site visitors to vote on a question; the question can be set
      dynamically and can be multilingual
      Interviews: Enables on-line interviews for your Campsite publication; users have to refresh
      the page regularly to get the latest questions and answers
      Blogs: Enables users to create and post to their own blogs, including comments

INSTALLING NEW PLUGINS
Plugins can be found on the Campsite SourceForge page. Once they are downloaded to a local
hard disk, they can be uploaded to your Campsite instance. Log in to your admin interface and
go to Plugins -> Manage Plugins. From there you can select the plugin to be uploaded. Plugins
must be uploaded to the Campsite instance as a .tar archive.

Selecting 'Manage Plugins' pulldown menu also provides you with a list of installed plugins; there is
a check box to disable the plugin and a red X to delete the plugin from your system. Once a
plugin is correctly installed, you will be able to administer it separately from the Plugins pulldown
menu.

Plugins require changes to your site's templates, but each plugin also includes sample templates
to either copy and paste or to use as a guide to your own templating.



CREATING TEMPLATES FOR YOUR PUBLICATION
40. Creating Templates For Your Publication
41. Template Quickstart Guide: "How do I..."
42. Templating tricks with Smarty
43. Templates In-depth
44. What's New In the Template Language In Version 3.0
45. Template Language Reference
46. Language Elements; Conventions
47. Basic Syntax
48. Template Objects
49. Environmental Control
50. Lists
51. Forms
52. Images
53. Template sample for comments
54. Somebody Should Set The Title For This Chapter!
55. How to do article pagination?
56. Miscellaneous
57. Campsite Modifiers
58. Creating an RSS feed for your site
59. Changing Templates
60. The Template Cache




                                                                                                        127
40. CREATING TEMPLATES FOR YOUR
PUBLICATION
In this chapter:

      Template Quickstart Guide: "How do I..."
      Templates In-depth
      What's New In the Template Language In Version 3.0
      Template Language Reference



When implementing Campsite, chances are you will already have a rather clear outline of the
structure of your publication online, or - even better - have a running web version already in
HTML. Either way, to migrate your publication to Campsite you will have to generate customized
templates for your content. Such templates will be incorporating the Campsite tags used to pull
information from the database into the HTML page.

The following sections will guide you step by step through the process of generating such
templates. Before proceeding, you should layout your site design. This can be done in many
ways, including sketching your design on paper, or using an HTML editor. However, the design of
web pages is outside the scope of this document.

One of the main goals of Campsite is to offer a fully customizable layout for online publications
and at the same time keep the content independent of the layout. This is done by means of
templates. Those templates are nothing more than HTML files containing embedded Campsite
description-language tags, which creates the link between the view and the content.

Templates are in-between your content database and your audience on the web. Therefore they
need to mediate between both. The database needs to understand what information is
requested, and the user's browser needs to retrieve a finished HTML page.

The template sets the stage, passing specific environmental information to the database query,
such as: "list only articles from current issue and section 'sports'." At the same time, it gives
detailed instructions on how content should be displayed in HTML format. This distinction
between environment and content is crucial for understanding and building templates. The
template language was designed to be usable on different levels of dynamic features: one can
make static templates for every issue, section, article or just a few customized templates that
generate different views depending on the given parameters.

The following will cover some examples on how to build templates. Further down you can find a
complete list of available commands used by Campsite templates.




128
41. TEMPLATE QUICKSTART GUIDE: "HOW
DO I..."
In this chapter:

  1.   How   to create a list of the most popular articles in a section
  2.   How   to create breadcrumbs
  3.   How   to do article pagination?
  4.   How   to display the most recently published articles?
  5.   How   to make a hard-coded link to an article?
  6.   How   to check if there are any articles in a section?
  7.   How   to display content based on the day of the weeek or date
  8.   How   to add an audio player, playing mp3-files attached to an article



Dive right in to the template language using the examples provided here. These examples are
meant to answer the most of the basic "getting started" questions laid out as questions in the
form of "How do I...<do something>".


If you are looking for more in-depth information on templates, see "Templates In-depth" chapter.



1. How to Create a List of the Most Popular Articles in a Section

The following code snippet works insiction or article page and will display links to the most
popular articles in this section.
<?
<ul>
{{ list_articles length=5 order="byPopularity desc"}}
<li><a href="{{ uri }}">{{ $campsite->article->name }}</a></li>
{{ /list_articles }}
</ul>
?>




2. How to Create Breadcrumbs

The easiest way to make breadcrumbs is following the two level structure of "Home" and
"Section" and create something like this:
<?
<a href="{{ uri options="publication" }}">Home</a>
&gt;
<a href="{{ uri options="section" }}">{{ $campsite->section->name }}</a>
?>

This will first display the link to the home page and then the link to the current section where
you are. Include this breadcrumb in your section page.

If you run an issue driven magazine, you might even add an additional level to your breadcrumbs:
the current issue:
<?
<a href="{{ uri options="publication" }}">Home</a>
&gt;
<a href="{{ uri options="issue" }}">{{ $campsite->issue->name }}</a>
&gt;
<a href="{{ uri options="section" }}">{{ $campsite->section->name }}</a>
?>



                                                                                                   129
3. How to do article pagination?

This example will show you how to split an article on multiple pages. We assume the article type
is fastnews and has three fields: date (date field type), intro (body field type) and Full_text (body
field type). You'll find this example implemented in the Campsite demo package here. The field
Full_text is the one that contains the pagination (subheads).

Here is the code:
{{ list_subtitles field_name="Full_text" }}
   <p>
  {{ if $campsite->article->full_text->subtitle_is_current }}
     <b>{{ $campsite->current_list->index }}. {{ $campsite->subtitle->name }}</b>
   {{ else }}
     <a href="{{ uri }}">{{ $campsite->current_list->index }}. {{ $campsite->subtitle->name
}}</a>
   {{ /if }}
   </p>
{{ /list_subtitles }}
<p>View subtitle:
{{ if $campsite->article->full_text->has_previous_subtitles }}
   <a href="{{ uri options="previous_subtitle full_text" }}">Previous</a>
{{ else }}
   Previous
{{ /if }}
|
{{ if $campsite->article->full_text->has_next_subtitles }}
   <a href="{{ uri options="next_subtitle full_text" }}">Next</a>
{{ else }}
   Next
{{ /if }}
|
{{ if $campsite->article->full_text->has_next_subtitles || $campsite->article->full_text-
>has_previous_subtitles }}
   <a href="{{ uri options="all_subtitles full_text" }}">All</a>
{{ else }}
   All
{{ /if }}
</p>
<p>{{ $campsite->article->full_text }}</p>




Lines 1-9 display the list of article subtitles (see "List of Subtitles" in "Template Language Reference"
chapter):

      display the subtitle name as simple text for the current subtitle - the one that's being
      viewed - (if $campsite->article->full_text->subtitle_is_current)
      display the subtitle name as link for other subtitles (else branch)

Lines 11-27 create links to navigate to the previous or next subtitle (uri options="previous_subtitle
full_text", uri options="previous_subtitle full_text"), or to display all subtitles (uri
options="all_subtitles full_text").

Line 29 displays the actual article content, in this case the current subtitle ($campsite->article-
>full_text).

The example given above will make your page look something like this:




130
4. How to display the most recently published articles?

This example will show you how to list the most recent news. It also demonstrates how to
display an image that is linked to an article, and how to make a hyperlink to an article.

The example given below will make your page look something like this:




Note: CSS styles have been removed from the example below to make it easier to read, so if
you use the code below, it will not look exactly as shown above; the colors will not be there, and
the spacing will be a bit different.



{{ local }}
{{ set_current_issue }}
{{ unset_section }}

<!-- Display all news articles on the front page, most recent first -->
{{ list_articles length="10" constraints="type is news OnFrontPage is on" order="bydate desc" }}

                                                                                                     131
     {{ if $campsite->current_list->at_beginning }}
       <table width="100%">
     {{ /if }}

     <tr>
     <td valign="top" align="left">
          <!-- Article date -->
           {{ $campsite->article->publish_date | camp_date_format:"%M %d, %Y" }}
          <br />


<!-- Article Headline -->


<a href="{{ uri }}">{{ $campsite->article->name }}</a>
      <br />


<!-- Article Intro -->

         {{ $campsite->article->intro }}
         <br />


<!-- Read more -->


<a href="{{ uri }}"><nobreak>Read
More...</nobreak></a>
    </td>


<td valign="top" align="right">

<!-- Optional image -->


         {{ if $campsite->article->has_image(1) }}

<img src="../{{ uri options="image 1" }}"
border="0">

         {{ /if }}

    </td>
  </tr>
  {{ if $campsite->current_list->at_end }}
    </table>
  {{ /if }}
<!-- END Article -->
{{ /list_articles }}
{{ /local }}


5. How to make a hard-coded link to an article?

To make a hard-coded link to an article, do the following (replacing the values with the values for
your particular article). This will make a link to an "About Us" page:
{{    local }}
{{    set_issue number="1" }}
{{    set_section number="5" }}
{{    set_article name="About Us" }}
<a    href="{{ uri }}">About Us</a>
{{    /local }}


6. How to check if there are any articles in a section?

This example shows you how to do something only if there is at least one article in a section. In
the example below, substitute the name of your article type for "news". This also assumes that
publication, issue, and section variables have been set already.
{{ list_articles constraints="type is news OnSection is On }}
    {{ if $campsite->current_list->at_beginning }}
        {{ $campsite->section->name }}
    {{ /if }}
{{ /list_articles }}




7. How to display content based on the day of the weeek or date

To invoke a certain action within templates (e.g. display a particular article headline) you can use
the following smarty code:
{{ if $smarty.now|date_format:'%l' == 'Monday' }}
{{ $campsite->article->name }}
{{ /if }}

 or in the case of lower case comparison:
{{ if $smarty.now|date_format:'%l'|lower == 'monday'                           }}
{{ $campsite->article->name }}


132
{{ /if }}

Furthermore, you can use all smarty date_format conversion specifiers for this or similar
purpose:




                                                                                            133
      %a - abbreviated weekday name according to the current locale

      %A - full weekday name according to the current locale

      %b - abbreviated month name according to the current locale

      %B - full month name according to the current locale

      %c - preferred date and time representation for the current locale

      %C - century number (the year divided by 100 and truncated to an integer, range 00 to
      99)

      %d - day of the month as a decimal number (range 01 to 31)

      %D - same as %m/%d/%y

      %e - day of the month as a decimal number, a single digit is preceded by a space (range 1
      to 31)

      %g - Week-based year within century [00,99]

      %G - Week-based year, including the century [0000,9999]

      %h - same as %b

      %H - hour as a decimal number using a 24-hour clock (range 00 to 23)

      %I - hour as a decimal number using a 12-hour clock (range 01 to 12)

      %j - day of the year as a decimal number (range 001 to 366)

      %k - Hour (24-hour clock) single digits are preceded by a blank. (range 0 to 23)

      %l - hour as a decimal number using a 12-hour clock, single digits preceeded by a space
      (range 1 to 12)

      %m - month as a decimal number (range 01 to 12)

      %M - minute as a decimal number

      %n - newline character

      %p - either `am' or `pm' according to the given time value, or the corresponding strings for
      the current locale

      %r - time in a.m. and p.m. notation

      %R - time in 24 hour notation

      %S - second as a decimal number

      %t - tab character

      %T - current time, equal to %H:%M:%S

      %u - weekday as a decimal number [1,7], with 1 representing Monday

      %U - week number of the current year as a decimal number, starting with the first
      Sunday as the first day of the first week

      %V - The ISO 8601:1988 week number of the current year as a decimal number, range 01
      to 53, where week 1 is the first week that has at least 4 days in the current year, and
      with Monday as the first day of the week.

      %w - day of the week as a decimal, Sunday being 0


134
      %W - week number of the current year as a decimal number, starting with the first
      Monday as the first day of the first week

      %x - preferred date representation for the current locale without the time

      %X - preferred time representation for the current locale without the date

      %y - year as a decimal number without a century (range 00 to 99)

      %Y - year as a decimal number including the century

      %Z - time zone or name or abbreviation

      %% - a literal `%' character



8. How to add an audio player, playing mp3-files attached to an article

By using a combination of the list of articles and the uri options, you can create a playlist of files
which are attached to an article. This is the code I used:
<?smarty
{{ list_article_attachments }}
 {{ if $campsite->current_list->at_beginning }}
 {{ /if }}
 {{ if $campsite->attachment->extension == "mp3" }}
<div <param name="movie" value="/templates/radioactive/apps/player_mp3_maxi.swf" />
 <param name="bgcolor" value="#444444"/>
 <param name="FlashVars" value="mp3={{ uri options="articleattachment" }}" />
<!-- player home: http://flash-mp3-player.net/ -->
</object>
 {{ /if }}
{{ /list_article_attachments }}
?>

Note that there is a special if condition: checking if the attached file is actually an mp3 file. If you
want to play with this, you could extend this and e.g. also embed flv video players or other
embedded objects according to the mime-type (i.e. ending) of the attached file.




                                                                                                           135
42. TEMPLATING TRICKS WITH SMARTY
Here are some tricks, using Smarty in the Campsite templates:


Check if the field is totally empty, i.e. no tags or whitespaces either:
{{ if trim(strip_tags($campsite->article->insert)) !== '' }}
                <ul class="articleList sidebar extLinks">
                     <li class="level-4 extLinks">
{{ $campsite->article->insert }}
                     </li>
               </ul>
{{ /if }}




136
43. TEMPLATES IN-DEPTH
In this chapter:

      Modular Structure of Templates
      Building a Navigation Template
      Linking to Issues, Sections and Articles
      Building an Article Template
      Building a Section Template
      Building a Home Page Template
      Advanced Search
      Creating reader subscriptions through the template language
      Powerful Lists and Ordering
      Adding PHP Scripts to Your Campsite Templates



This section is an in-depth guide to the templates.




MODULAR STRUCTURE OF TEMPLATES
A glance at all articles of an online publication reveals that generally there are many layout
similarities even across different sections of the publication. Taking advantage of such similarities
is what the template structure of Campsite was meant to do. In other words: design features
that remain the same for all articles only need to be specified once, e.g. the navigation from an
article back to section and home, font type and size, background color and the like.

On the other hand, there are article components that vary between articles. For example, the
top of the article might contain some specific logo to indicate which section it belongs to. In such
a case, the templates are designed to work in a modular fashion, allowing you to call up
templates within templates.

The modular structure of the templates can be illustrated well by the following example: If
background color, font size and type are the same for all articles, they will be specified as plain
HTML in the template. But differences between sections will be indicated within the structure of
the template (see below) indicating "if this article belongs to the politics section, insert such-and-
such template here, if it is sports, insert such-and-such, else: just use the following."

Templates can be stacked within each other. A template can be made to call another template
and include the layout information at the position where it was called in the main template. The
easiest way to illustrate this modular structure is by looking at a usual tree structure of folders
on a computer. Starting from general categories, the deeper the structure, the more precise and
specific the folder names and information.

The modular structure was introduced to keep redundancy to zero and therefore the layout
work minimal. Any design changes need to be made only once in the templates, never even
twice, if you make full use of this modularity potential.




BUILDING A NAVIGATION TEMPLATE
As described above, the template structure can be nested, meaning one template can call
another template. This, for example, makes a lot of sense for the navigation. To jump between
sections, you might only need one navigation template that can be used by all other templates
(article, section, home page).

To nest another template within another, use the following Campsite tag:
                                                                                                         137
{{ include file="navigationtemplate.tpl" }}

The 'include' command is Campsite lingo; the name of the template needs to be adjusted to
whatever you called it. Let's assume we add this tag in the article template we created earlier,
and we can now go on and build the template.

First thing to do when you are building something like the navigation is to take control over the
environmental variables. Our navigation needs to follow some standard rules and should not be
affected too much by the environmental setting of the current position of the user.

In terms of Campsite lingo, we need to introduce a 'local' tag, which allows us to specify some
environmental variables for a local section inside the template. In other words, we can switch off
the environmental variables, set our own and then switch them on again. In that way we can use
the same template for the navigation for all articles, sections, even issues (not publications,
obviously).

In order to make sure you enter the current issue in the navigation bar, set the environment
variables to:
{{ local }}{{ set_current_issue }}

Here, 'local' allows you to set the parameters inside a template to the values you want to be
specified. Once the parser finds the '/local' tag, it will switch back to the environment variables it
arrived with (for example a back issue).

Then the issue parameter is set to 'current'. This is done in order to make sure that the
navigation will always jump to the 'section' (or whatever you want) of the current (latest
published) issue.

Then you would need to specify which section you would want to link to. This is done with the
'section number' tag.
{{ set_section number="1" }}

The above tag would set the local section parameter to 1, which will be looked up in the
Campsite database under section entries (each section is assigned a number when it is created,
see chapter "Creating a section" of this manual).

Now we have set all necessary values for the link: we will link to section 1 in the current issue.
All we need to do now is create the link to the section, or - to be more precise - the template
that is used to build section pages.
<a href="{{ uri options="section" }}">NEWS</a>

This will create an ordinary link, using the anchor tag of HTML. This link will generate the URI for
the section 1.

Finally, we need to end the local parameters with the tag:
{{ /local }}

A complete navigation template could look like this:
{{ local }}

{{ set_current_issue }}
{{ set_section number="1" }}
<a href="{{ uri options="section" }}">News</a><br>
{{ set_section number="2" }}
<a href="{{ uri options="section" }}">Politics</a><br>
{{ set_section number="3" }}
<a href="{{ uri options="section" }}">Sport</a><br>
{{ set_section number="4" }}
<a href="{{ uri options="section" }}">Weather</a><br>

{{ /local }}



138
Make sure that the section numbers assigned correlate with the names of the sections, as you
assigned them when building the publication in the first place.

Now we can advance into a more conditional environment, the section pages.

LINKING TO ISSUES, SECTIONS, AND ARTICLES
When building your navigation template, you will most likely want to link to internal content.
Two statements will help you do this: uri and uripath. You can find the full description at
"Displaying the URL" in "Template Language Reference" chapter. These statements help you build a
URL. In the admin interface, you will assign each issue, section, and article a "URL Name".
These names are used to contruct a link like so:
http://test.com/en/may30/news/summer_is_coming


where:

        test.com is the publication's site name
        en is the publication's language code
        may30 is the latest issue number
        news is the section short name
        summer_is_coming is the article short name

To produce such a link you only have to write the following:
<a href="{{ uri }}">text</a>


This is equivalent to:
<a href="{{ uripath }}?{{ urlparameters }}">text</a>


uripath displays the 'path' part of the URI: / e n / m a y 3 0 / n e w s / s u m m e r _ i s _ c o m i n g . urlparameters
displays the rest of the parameters if any. uri combines both these statements. All these
statements work for both old style URLs (named template path) and new type of URLs (named
short name).

Creating Links to Issues, Sections, etc.

Use language, publication, issue, section and article arguments in order to specify the scope of
the link. Suppose we are in the article template and we want to return to the last issue, current
issue, section or article page.
<a href="{{ uri options="language" }}">text</a>

will display:

<a href=/en>text</a>

this will redirect us to the last published issue page.

<a href="{{ uri options="publication" }}">text</a>

will display:

<a href=/en>text</a>

this will redirect us to the last published issue page.

Publication argument has the same effect as language because short name URLs do not have
the publication parameter in the URI. Instead, the publication is identified by the site name.
<a href="{{ uri options="issue" }}">text</a>


will display:

<a href=/en/may30>text</a>

this will take us to the current issue page.
                                                                                                                             139
<a href="{{ uri options="section" }}">text</a>


will display:
<a href=/en/may30/news>text</a>

this will take us to the current section page.

<a href="{{ uri options="article" }}">text</a>

will display:
<a href=/en/may30/summer_is_coming>text</a>


this will take us to the current article page.

Language, publication, issue, section and article arguments cannot be combined.

Creating a Link to a Template

Sometimes we may need to create a link to a template that is not an issue, section or article
template; with short name URLs this can be done the following way:
<a href="{{ uri options="template login.tpl" }}">text</a>

will display:

<a href=/en/may30/summer_is_coming?tpl=tpl_id>text</a>

this will display the login.tpl template in the current context of variables (publication, language,
issue etc.).




BUILDING AN ARTICLE TEMPLATE
Building an article template is the easiest option. All you need to do is generate your HTML
layout and substitute the dynamic sections (title, author, intro, text...) with the simple tag:
{{ $campsite->article->title }}

The command is 'print article'; the 'title' part varies. This is the name of the variable that you
assigned when building the Article Types. So it could also read:
{{ $campsite->article->sportsitemdeck }}

As the rest of the HTML layout remains as it is, a simple template might look like this:
<body>
<h1>{{ $campsite->article->title }}</h1>
<h3>{{ $campsite->article->subtitle }}</h3>
<p><i>Written by {{ $campsite->article->authorname }}
   on the {{ $campsite->article->date }}</i><p>
{{ $campsite->article->text }}
</body>
</html>

The reason we can reduce the templates to such a simple solution is, because Campsite will
remember where it comes from and where it is. So by the time the user arrives at one
particular article, Campsite knows the publication, the issue, the section, and even the article ID
and can simply generate the HTML page from the database by using the environmental variables
together with the layout information in the template.

Obviously, your design can be far more advanced than this page. And Campsite can also perform
far more advanced functions than this. In order to get a feel for this, let's jump into the next
example, building the navigation. (A full list of tag commands can be found at the end of this
chapter.)



140
BUILDING A SECTION TEMPLATE
In this article:

      The 'Feature' article of the section
      Displaying only the most recent feature article on a section page
      Including Images in the Section Listing

<h3




                                                                          141
44. WHAT'S NEW IN THE TEMPLATE
LANGUAGE IN VERSION 3.0
In this chapter:

      Template Engine Structure
      Syntax Changes




TEMPLATE ENGINE STRUCTURE
The Campsite extension to Smarty will initialize objects that are specific to Campsite: article,
section, issue, image etc. These objects are instantiated from meta classes (e.g. MetaArticle,
MetaSection etc.) and use method call overloading for allowing the web designer to access object
properties (see: http://www.php.net/manual/en/language.oop5.overloading.php). This way we
won't expose the core Article, Section etc. objects to the web designer so he/she won't be able
to play with the database. These meta classes will only implement the _ _get() method, _ _set()
will be empty or throw an error. Meta classes will use the existing classes (Publication, Issue,
Section etc.) to retrieve the data. Meta classes will also implement the method "defined()" that
returns true if the object instantiated from the class was actually initialized.

The template engine will initialize the $campsite object, which stores the whole Campsite
environment (meaning all template parameters, objects, properties etc.). The $campsite object
has the following read/write properties:

      language
      publication - holds data for the current publication
      issue
      section
      article
      topic
      url
      defaultLanguage
      defaultPublication - holds data for the publication defined at the beginning of the template
      defaultIssue
      defaultSection
      defaultArticle
      defaultTopic
      defaultUrl
      currentList
      user
      user->subscription
      search

and the following read-only properties:




142
          current_issues_list
          current_sections_list
          current_articles_list
          current_article_attachments_list
          current_article_comments_list
          current_article_images_list
          current_article_topics_list
          current_article_audio_attachments_list
          current_search_results_list
          current_subtopics_list
          current_subtitles_list
          current_list




SYNTAX CHANGES
Conventions

          #element# will be replaced by the corresponding language element based on the semanting
          of 'element' word (e.g. #statement#: List, Article etc., #value#: a certain string, integer or
          other type value)
          [element] means the element is optional
          <!** > are the old begin/end tags
          {{ }} are the new begin/end tags
          if #element# is a predefined identifier (e.g. #statement#, #attribute#) then in the new
          syntax it will converted always to the following style: all letters are lower case (e.g.
          ARTICLE -> article, article -> article, Article -> article); words are separated by underscore
          (e.g.: ArticleComment? -> article_comment) (see "Article comment" in "Template Objects"
          chapter)
          [#element#]+ means the element can occur 0 to multiple times
          \[#element#\] is replaced by [#element#], like accessing array elements by keys:
          $article\[#element#\] -> $article[#element#]

Environment Manipulating Statements

Set/Unset Statements

Old syntax:
1.   <!**   #statement#   #attribute# #value#>⁞
2.   <!**   #statement#   default>
3.   <!**   #statement#   current>
4.   <!**   #statement#   off>

New syntax:
1.   {{   set_#statement# #attribute#="#value#" }}
2.   {{   set_default_#statement# }}
3.   {{   set_current_#statement# }}
4.   {{   unset_#statement# }}


Local Statement

Old syntax:
<!** Local>
<!** EndLocal>

New syntax:
{{ local }}
{{ /local }}


Include Statement


                                                                                                           143
We will use the include statement implemented in Smarty.

Exceptions

Old syntax:
1. <!** HTMLEncoding on>
2. <!** HTMLEncoding off>

New syntax:
1. {{ enable_html_encoding }}
2. {{ disable_html_encoding }}


Examples

<!** Article number 125>

changes to:
{{ set_article number="125" }}

<!** Article off>

changes to:
{{ unset_article }}


List Statements

Old syntax:
<!** List [length #value#] [columns #value#] #statement# [#contraints#]
          [order #order_constraints#]>
<!** ForEmptyList>
<!** EndList>

New syntax:
{{ list_#statement#s [name="#value#"] [length="#value#"] [columns="#value#"]
                     [constraints="#constraints#"] [order="#order_constraints#"] }}
{{ if $currentList->empty }}
{{ /if }}
{{ /list_#statement#s }}

Constraints will require a 'Constraint Parser'. The Constraint Parser has the following
requirements:
 * constraints can contain variables
 * constraints can contain "&&"(AND) and "||" (OR)
 * constraints can contain parenthesis


Exceptions

Old syntax:
1. <!** List [length #value#] [columns #value#] ArticleAttachment ForCurrentLanguage>
2. <!** List [length #value#] [columns #value#] ArticleAttachment ForAllLanguages>
3. <!** List [length #value#] [columns #value#] Subtitle>

New syntax:
1. {{ list_article_attachments [name="#name#"] [length="#value#"]
                               [columns="#value#"] language="current" }}
2. {{ list_article_attachments [name="#name#"] [length="#value#"]
                               [columns="#value#"] language="all" }}
3. {{ list_subtitles [name="#name#"] [length="#value#"] [columns="#value#"]
                     [articleType="#value#"] field="#value#" }}

In the exception example 3 articleType and field attributes are read from "With" statement from
the old template language.

If Statements

144
General Syntax

Old syntax:
1.   <!**      If   [not]   #statement#   >
2.   <!**      If   [not]   #statement#   #attribute# >
3.   <!**      If   [not]   #statement#   #attribute# #value# >
4.   <!**      If   [not]   #statement#   #attribute# #value# [#value#]+ >
5.   <!**      If   [not]   #statement#   #attribute# #operator# #value# >
6.   <!**      If   [not]   #statement#   #article_type# #attribute# #operator# #value# >

New syntax:
1.   {{   if $#statement# }}
                [!]
2.   {{   if $#statement#->#attribute# }}
                [!]
3.   {{   if ($#statement#->#attribute# == "#value#") }}
                [!]
4.   {{   if ($#statement#->#attribute# == "#value#"
                [!]
              [and $#statement#->#attribute# == "#value#"]+ ) }}
5. {{ if [!] ($#statement#->#attribute# #smarty_corresponding_operator# "#value#") }}
6. {{ if [!] ($#statement#->type->#article_type#->#attribute#
              #smarty_corresponding_operator# "#value#") }}


Exceptions

Old syntax:
1. <!** If [not] Allowed>
2. <!** If [not] Article upload_date #operator# #value# >
3. <!** If [not] Article has_keyword #value# >
4. <!** If [not] Article translated_to #value# >
5. <!** If [not] CurrentSubtitle >
6. <!** If [not] Image #value# >
7. <!** If [not] Login #attribute# >
8. <!** If [not] NextItems >
9. <!** If [not] PreviousItems >
10. <!** If [not] NextSubtitles >
11. <!** If [not] PrevSubtitles >
12. <!** If [not] Search #attribute# >
13. <!** If [not] User #attribute# >
14. <!** If [not] Subtitle number #operator# #value# >

New syntax:
1. {{ if [!] $article->content_accessible }}
2. {{ if [!] $article->creation_date #smarty_corresponding_operator# "#value#" }}
3. {{ if [!] $article->keyword == "#value#" }}
4. {{ if [!] $article->translationLang == "#value#" }}
5. {{ if [!] $article->subtitle->is_current }}
6. {{ if [!] $article->image_number == "#value#" }}
7. {{ if [!] $user->login_#attribute# }}
8. {{ if [!] $current_list->length gt $current_list->last_element->index }}
9. {{ if [!] $current_list->first_element->index gt 1 }}
10. {{ if [!] $current_list->length gt $current_list->last_element->index }}
11. {{ if [!] $current_list->first_element->index gt 1 }}
12. {{ if [!] $article->search#attribute# }}
13. {{ if [!] $user->subscription_#attribute# }}
14. {{ if [!] $article->subtitle->number #smarty_corresponding_operator# "#value#" }}


With Statement

This statement is not used anymore, see example 3 from "List" exceptions.

URL Statements

Old syntax:
<!** #statement# [#option#]+ >

New syntax:
{{ #statement# [options="[#option#]+"] }}

Where #statement# can be one of the following: URIPath, URLParameters, URI, URL,
FormParameters?.

Date Statement

                                                                                            145
Old syntax:
1. <!** Date #attribute# >
2. <!** Date #date_format# >

New syntax:
1. {{ $smarty.now|camp_date_format:"#corresponding_smarty_date_part#" }}
2. {{ $smarty.now|camp_date_format:"#date_format#" }}


Print Statements

Old syntax:
1. <!** Print #statement# #attribute# >
2. <!** Print Article [#article_type#] #attribute# >
3. <!** Print #statement# #attribute# #date_format# >

New syntax:
1. {{ $#statement#->#attribute# }}
2. {{ $article->[type->#article_type#->]#attribute# }}
3. {{ $#statement#->#attribute#|camp_date_format:"#date_format#" }}


Exceptions

1. <!** Print ArticleAttachment #attribute# >
2. <!** Print ArticleComment #attribute# >
3. <!** Print ArticleComment readerEmailObfuscated >
4. <!** Print ArticleComment readerEmailPreviewObfuscated >
5. <!** Print Subtitle name >
6. <!** Print Image [#imageNumber#] #attribute# [#date_format#] >
7. <!** Print List #attribute# >
8. <!** Print Login error >
9. <!** Print Search #attribute# >
10. <!** Print Subscription #attribute# [#date_format#] >

1. {{ $article->attachment->#attribute# }}
2. {{ $article->comment->#attribute# }}
3. {{ $article->comment->reader_email|camp_obfuscate }}
4. {{ $article->comment->reader_email_preview|camp_obfuscate }}
5. {{ $article->subtitle->name }}
6. {{ $article->image[\[#imageNumber#\]]->#attribute#[|camp_date_format:"#date_format#"] }}
7. {{ $current_list->#attribute# }}
8. {{ $user->login->error_message }}
9. {{ $article->search->#attribute# }}
10. {{ $user->subscription->#attribute#[|camp_date_format:"#date_format#"] }}

{{ $article->title }}
{{ $article->type->data->intro }}


Form Statements

Old syntax:
1. <!** #statement# #template_name# #submit_button_name# >
2. <!** ArticleCommentForm #template_name# #submit_button_name# [#preview_button_name#] >
3. <!** Subscription #subscription_type# #template_name# #submit_button_name#
                     [#total_field_name# #evaluate_button_name#] >

New syntax:
1. {{ #statement#_form template="#template_name#" submit_button="#submit_button_name#" }}
2. {{ article_comment_form template="#template_name#" submit_button="#submit_button_name#"
                           [preview_button="#preview_button_name#"] }}
3. {{ subscription_form type="#subscription_type#" template="#template_name#"
                        submit_button="#submit_button_name#"
                        [total_field="#total_field_name#"]
                        [evaluate_field="#evaluate_button_name#"] }}

The statements that match rule 1 are: Login, Search and User.

Edit Statements

Old syntax:
1. <!** Edit #statement# #attribute# >

146
2. <!** Edit #statement# #attribute# #integer_value# >
3. <!** Edit #statement# #attribute# HTML #html_code# >

New syntax:
1. {{ camp_edit object="#statement#" attribute="#attribute#" }}
2. {{ camp_edit object="#statement#" attribute="#attribute#" }}
3. {{ camp_edit object="#statement#" attribute="#attribute#" html_code="#html_code#" }}


Select Statements⁞

Old syntax:
1. <!** Select #statement# #attribute# >
2. <!** Select User gender #male_name_string# #female_name_string# >

New syntax:
1. {{ camp_select object="#statement#" attribute="#attribute#" }}
2. {{ camp_select object="user" attribute="gender" male_name="#male_name_string#"
                  female_name="#female_name_string#" }}




                                                                                          147
45. TEMPLATE LANGUAGE REFERENCE
In this chapter:

      Language Elements; Conventions
      Basic Syntax
      Template Objects
      Environmental Control
      Lists
      Forms
      Miscellaneous
      Campsite Modifiers




148
46. LANGUAGE ELEMENTS;
CONVENTIONS
In the following sub chapters describing the template language we used the following conventions:

      identifiers in between '<' and '>' must be replaced in the template according to their
      description
      spaces must be used as in the language description
      identifiers that are not in between '<' and '>' are language keywords and must be written
      as in the language description
      identifiers enclosed by '[' and ']' characters are not mandatory in the statement
      sequences of identifiers separated by '|' character describe a situation where all the
      identifiers are valid but only one can be used at a time

The template language is composed out of:

      statements: they are keywords with a special meaning that define actions taken by
      template parser
      parameters: are keywords describing statement features; they are used to specify
      statement constraints
      parameter values: keywords that describe the parameter must take

Any value must be put in between double quotes (""). The double quote (") must be escaped any
time it is used in an identifier. E.g.: escaping a value that contains quote:
{{ if $campsite->article->name == "Lucas \"the beast\"" }}

In some statements (usually lists) there is a special parameter named "constraints". This
parameter describes conditions that can not be specified in the usual way:
parameter="value"

The constraints are specified in the following way:
constraints="<constraints_list>"

Constraints are built from the following expressions:

      comparison expressions: <attribute> <operator> <value>
      attributes without type: <attribute>

Attributes may have no type or one of the following types:

      integer: signed, 10 digits number
      string of characters: may contain any character except control characters - these will be
      removed automatically
      switch: has two values: "on" and "off"
      date: year, month, day; where date value is specified it must be written in "yyyy-mm-dd"
      format
      time: hour, minute, second; where time value is specified it must be written in "hh:mm:ss"
      format
      datetime: year, month, day, hour, minute, second; where datetime value is specified it
      must be written in "yyyy-mm-dd hh:mm:ss" format
      topic: list of names defined by the application user used for categorizing articles

Every type has a list of valid operators that can be used on attributes of that certain type. The
operators list corresponding to defined types:




                                                                                                    149
      integer: <integer_operator> = is | not | greater | greater_equal | smaller | smaller_equal
      string of characters: <string_operator> = is | not | greater | greater_equal | smaller |
      smaller_equal
      switch: <switch_operator> = is | not
      date: <date_operator> = is | not | greater | greater_equal | smaller | smaller_equal
      time: <time_operator> = is | not | greater | greater_equal | smaller | smaller_equal
      datetime: <datetime_operator> = is | not | greater | greater_equal | smaller | smaller_equal
      topic: <topic_operator> = is | not

Spaces in values must be escaped with backslash.

E.g.: constraints="topic is Global\ Warming:en"
In this case "Global Warming" is the topic name.




150
47. BASIC SYNTAX
In this article:

      Comments
      Variables
      Functions
      Attributes
      Embedding Vars in Double Quotes
      Math
      Escaping Smarty Parsing
      Modifiers

The Campsite template engine was built upon Smarty so the Campsite template language is
actually an extension of the Smarty template language. For details on the Smarty template
language please go to this link: http://smarty.net/manual/en/smarty.for.designers.php

All template tags are enclosed within delimiters. By default these are { and } , but they can be
changed. In Campsite we use {{ and }}.

For the examples in this manual, we will assume that you are using the default Campsite
delimiters. All content outside of delimiters is displayed as static content, or unchanged. When
the template engine encounters template tags, it attempts to interpret them, and displays the
appropriate output in their place.

The following sub-chapters, which were copied from the Smarty manual, will familiarize you with
the Smarty syntax.




COMMENTS
Template comments are surrounded by asterisks, and that is surrounded by the delimiter tags
like so:

 {{* this is a comment *}}


Comments are NOT displayed in the final output of the template, unlike <!-- HTML comments --> .
These are useful for making internal notes in the templates which no one will see ;-)

Example 3-1. Comments within a template
{{* I am a template comment, I don't exist in the compiled output      *}}
<html>
<head>
<title>{{$title}}</title>
</head>
<body>

{{* another single line comment *}}
<!-- HTML comment that is sent to the browser -->

{{* this multiline
    comment is
    not sent to browser
*}}

{{*********************************************************
Multi line comment block with credits block
  @ author:         bg@example.com
  @ maintainer:     support@example.com
  @ para:           var that sets block style
  @ css:            the style output
**********************************************************}}

{{* The header file with the main logo and stuff     *}}
{{include file='header.tpl'}}


                                                                                                   151
{{* Dev note: the $includeFile var is assigned in foo.php script        *}}
<!-- Displays main content block -->
{{include file=$includeFile}}

{{* this <select> block is redundant *}}
{{*
<select name="company">
  {{html_options options=$vals selected=$selected_id}}
</select>
*}}

<!-- Show header from affiliate is disabled -->
{{* $affiliate|upper *}}

{{* you cannot nest comments *}}
{{*
<select name="company">
  {{* <option value="0">-- none -- </option> *}}
  {{html_options options=$vals selected=$selected_id}}
</select>
*}}


{{* cvs tag for a template, below the 36 SHOULD be an american currency
. however its converted in cvs.. *}}
{{* &#36;Id: Exp &#36; *}}
{{* $Id: *}}
</body>
</html>




VARIABLES
Template variables start with the $dollar sign. They can contain numbers, letters and
underscores, much like a PHP variable. You can reference arrays by index numerically or non-
numerically. Also reference object properties and methods.

Config file variables are an exception to the $dollar syntax and are instead referenced with
surrounding #hashmarks#, or via the $smarty.config variable.

Example 3-2. Variables

 {{$foo}}        <-- displaying a simple variable (non array/object)
 {{$foo[4]}}     <-- display the 5th element of a zero-indexed array
 {{$foo.bar}}    <-- display the "bar" key value of an array, similar to PHP $foo['bar']
 {{$foo.$bar}}   <-- display variable key value of an array, similar to PHP $foo[$bar]
 {{$foo->bar}}   <-- display the object property "bar"
 {{$foo->bar()}} <-- display the return value of object method "bar"
 {{#foo#}}       <-- display the config file variable "foo"
 {{$smarty.config.foo}} <-- synonym for {{#foo#}}
 {{$foo[bar]}}   <-- syntax only valid in a section loop, see {{section}}
 {{assign var=foo value='baa'}}{{$foo}} <-- displays "baa", see {{assign}}

 Many other combinations are allowed

 {{$foo.bar.baz}}
 {{$foo.$bar.$baz}}
 {{$foo[4].baz}}
 {{$foo[4].$baz}}
 {{$foo.bar.baz[4]}}
 {{$foo->bar($baz,2,$bar)}} <-- passing parameters
 {{"foo"}}        <-- static values are allowed

 {{* display the server variable "SERVER_NAME" ($_SERVER['SERVER_NAME'])*}}
 {{$smarty.server.SERVER_NAME}}


Request variables such as $_GET , $_SESSION , etc are available via the reserved $smarty variable.

See also $smarty , config variables {{assign}} and assign() .




FUNCTIONS

152
Every Smarty tag either prints a variable or invokes some sort of function. These are processed
and displayed by enclosing the function and its attributes within delimiters like so: {{funcname
attr1='val1' attr2='val2'}} .

Example 3-3. function syntax

 {{config_load file='colors.conf'}}

 {{include file='header.tpl'}}
 {{insert file='banner_ads.tpl' title='Smarty is cool'}}

 {{if $logged_in}}
     Welcome, <font color="{{#fontColor#}}">{{$name}}!</font>
 {{else}}
     hi, {{$name}}
 {{/if}}

 {{include file='footer.tpl' ad=$random_id}}


      Both built-in functions and custom functions have the same syntax within templates.

      Built-in functions are the inner workings of Smarty, such as {{if} }, {{section}} and
      {{strip}} . There should be no need to change or modify them.

      Custom functions are additional functions implemented via plugins. They can be modified
      to your liking, or you can create new ones. {{html_options}} and {{popup}} are examples
      of custom functions.

See also register_function()




ATTRIBUTES
Most of the functions take attributes that specify or modify their behavior. Attributes to Smarty
functions are much like HTML attributes. Static values don't have to be enclosed in quotes, but it
is recommended for literal strings. Variables may also be used, and should not be in quotes.

Some attributes require boolean values (TRUE or FALSE ). These can be specified as either
unquoted true , on , and yes , or false , off , and no .

Example 3-4. function attribute syntax
{{include file='header.tpl'}}

{{include file='header.tpl' attrib_name='attrib value'}}

{{include file=$includeFile}}

{{include file=#includeFile# title='Smarty is cool'}}

{{html_select_date display_days=yes}}

{{mailto address='smarty@example.com'}}

<select name='company_id'>
  {{html_options options=$companies selected=$company_id}}
</select>




EMBEDDING VARS IN DOUBLE QUOTES
      Smarty will recognize assigned variables embedded in "double quotes" so long as the
      variable name contains only numbers, letters, under_scores and brackets[]. See naming for
      more detail.

      With any other characters, for example a .period or $object>reference , then the variable
      must be surrounded by `backticks` .

      You cannot embed modifiers, they must always be applied outside of quotes.
                                                                                                     153
Example 3-5. Syntax examples

 {{func   var="test   $foo test"}}       <-- sees $foo
 {{func   var="test   $foo_bar test"}}   <-- sees $foo_bar
 {{func   var="test   $foo[0] test"}}    <-- sees $foo[0]
 {{func   var="test   $foo[bar] test"}} <-- sees $foo[bar]
 {{func   var="test   $foo.bar test"}}   <-- sees $foo (not $foo.bar)
 {{func   var="test   `$foo.bar` test"}} <-- sees $foo.bar
 {{func   var="test   `$foo.bar` test"|escape}} <-- modifiers outside quotes!

Example 3-6. Practical examples



 {{* will replace $tpl_name with value *}}
 {{include file="subdir/$tpl_name.tpl"}}

 {{* doesn't replace $tpl_name *}}
 {{include file='subdir/$tpl_name.tpl'}} <--

 {{* must have backticks as it contains a . *}}
 {{cycle values="one,two,`$smarty.config.myval`"}}

 {{* same as $module['contact'].'.tpl' in a php script *}}
 {{include file="`$module.contact`.tpl"}}

 {{* same as $module[$view].'.tpl' in a php script *}}
 {{include file="$module.$view.tpl"}}



See also escape




MATH
Math can be applied directly to variable values.

Example 3-7. math examples

 {{$foo+1}}

 {{$foo*$bar}}

 {{* some more complicated examples *}}

 {{$foo->bar-$bar[1]*$baz->foo->bar()-3*7}}

 {{if ($foo+$bar.test%$baz*134232+10+$b+10)}}

 {{$foo|truncate:"`$fooTruncCount/$barTruncFactor-1`"}}

 {{assign var="foo" value="`$foo+$bar`"}}


See also the {{math}} function for complex equations and {{eval}} .




ESCAPING SMARTY PARSING
It is sometimes desirable or even necessary to have Smarty ignore sections it would otherwise
parse. A classic example is embedding Javascript or CSS code in a template. The problem arises
as those languages use the { and } characters which are also the default delimiters for Smarty.

The simplest thing is to avoid the situation altogether by separating your Javascript and CSS code
into their own files and then using standard HTML methods to access them.

Including literal content is possible using {{literal}}..{{/literal}} blocks. Similar to HTML entity
usage, you can use {{ldelim}} ,{{rdelim}} or {{$smarty.ldelim}} to display the current delimiters.




154
MODIFIERS
Modifiers can be applied to variables, custom functions or strings. To apply a modifier, specify
the value followed by a | (pipe) and the modifier name. A modifier may accept additional
parameters that affect its behavior. These parameters follow the modifer name and are
separated by a : (colon). Also, all php-functions can be used as modifiers implicitly (more below)
and modifiers can be combined.

Example 5-1. Modifier examples

 {* apply modifier to a variable *}
 {$title|upper}

 {* modifier with parameters *}
 {$title|truncate:40:'...'}

 {* apply modifier to a function parameter *}
 {html_table loop=$myvar|upper}

 {* with parameters *}
 {html_table loop=$myvar|truncate:40:'...'}

 {* apply modifier to literal string *}
 {'foobar'|upper}

 {* using date_format to format the current date *}
 {$smarty.now|date_format:"%Y/%m/%d"}

 {* apply modifier to a custom function *}
 {mailto|upper address='smarty@example.com'}

 {* using php's str_repeat *}
 {'='|str_repeat:80}

 {* php's count *}
 {$myArray|@count}

 {* php's shuffle on servers's ip *}
 {$smarty.server.SERVER_ADDR|shuffle}

 (* this will uppercase and truncate the whole array *}
 <select name="name_id">
 {html_options output=$myArray|upper|truncate:20}
 </select>


      If you apply a modifier to an array variable instead of a single value variable, the modifier
      will be applied to every value in that array. If you really want the modifier to work on an
      entire array as a value, you must prepend the modifier name with a @ symbol.

            Example:{$articleTitle|@count} - will print out the number of elements in the
            $articleTitle array using the php count() function as a modifier.

      Modifiers are autoloaded from the $plugins_dir or can be registered explicitly with the
      register_modifier() function. The later is useful for sharing a function between php scripts
      and smarty templates.

      All php-functions can be used as modifiers implicitly, as demonstrated in the example
      above. However, using php-functions as modifiers has two little pitfalls:

            First - sometimes the order of the function-parameters is not the desirable one.
            Formatting $foo with {"%2.f"|sprintf:$foo} actually works, but asks for the more
            intuitive, like {$foo|string_format:"%2.f"} that is provided by the Smarty
            distribution.

            Secondly - if $security is enabled, all php-functions that are to be used as modifiers
            have to be declared trusted in the MODIFIER_FUNCS element of the $security_settings
            array

You can apply any number of modifiers to a variable. They will be applied in the order they are
combined, from left to right. They must be separated with a | (pipe) character:
 {$articleTitle}
 {$articleTitle|upper|spacify}
 {$articleTitle|lower|spacify|truncate}

                                                                                                      155
{$articleTitle|lower|truncate:30|spacify}
{$articleTitle|lower|spacify|truncate:30:". . ."}




156
48. TEMPLATE OBJECTS
In this article:

      Language
      Default Language
      Publication
      Default Publication
      Issue
      Default Issue
      Section
      Default Section
      Article
      Default Article
      Article Attachment
      Audio Attachment
      Article Comment
      Subtitle
      Image
      Topic
      Default Topic
      User
      Subscription
      Template
      Default Template
      URL
      Default URL
      Current List
      Login Action
      Search Articles Action
      Submit Comment Action
      Preview Comment Action
      Edit User Action
      Edit Subscription Action

The Campsite template engine stores the template environment in an object named 'campsite'.
All Campsite properties and objects are attributes of $campsite object.

The $campsite object has the following attributes which are not objects:

      version: the Campsite version
      preview: true if the page was displayed in the preview window (by a Campsite staff user)
      prev_list_empty: true if a list was displayed before querying this attribute and this list was
      empty

Any Campsite object (e.g.: $campsite->language, $campsite->article) has the following functions:

      has_property("property_name")

Returns true when the object has the given property. This function can be used for dynamic
article properties too.

E.g.: $campsite->article->has_property("name") will return true.

      same_as($campsite->other_object)

Returns true if the object variable given as a parameter points to the same data as the current
object.



                                                                                                       157
E.g.: {{ if $campsite->article->same_as($campsite->default_article) }} will return true if the
current article was the same as the article defined at the beginning of the template. If both were
undefined this function returns true.

LANGUAGE
The "language" object is set at the beginning of the main template based on the request URL.
This object can be changed using the set_language function. The language object has the following
properties:

      name: language name
      number: language identifier in the Campsite database (integer value)
      english_name: language name in English
      code: language international code
      defined: boolean value (true/false) - true if the language was set in the current
      environment; false otherwise

If you want to verify whether the current environment language was the same as the initial
language compare it to the default_language object:
{{ if $campsite->language == $campsite->default_language }}
...
{{ /if }}

If you want to display parts of your templates in a different language according to the language
selected by the user, you can use something similar to the following code. This snippet was used
for a bilingual publication.
{{ if $campsite->language->code == "en" }}archive{{ else }}[trans]archive{{ /if }}


DEFAULT LANGUAGE
The "default_language" object is set at the beginning of the main template based on the request
URL and can not be modified. It has the same attributes as the language object (see "Language"
in this chapter).

PUBLICATION
The "publication" object is set at the beginning of the main template based on the request URL.
This object can be changed using the set_publication (see "Set publication" in this chapter) function.
The publication object has the following properties:




158
      name: publication name
      identifier: publication identifier in the Campsite database (integer value)
      default_language: the publication default language - object of type language (see "Language"
      in this chapter))
      site: publication site
      defined: boolean value (true/false) - true if the publication was set in the current
      environment; false otherwise
      public_comments: true if the public (anonymous readers) was allowed to post comments
      moderated_comments: true if the comments posted by the current reader will be
      moderated
      captcha_enabled: true if CAPTCHA will be used to detect spam
      subscription_currency: returns the currency used for subscription payments
      subscription_time_unit: returns the time unit (day, week, month, year) used to set the
      subscription length
      subscription_trial_time: returns the default time of the trial subscription in time units
      subscription_paid_time: returns the default time of the paid subscription in time units
      subscription_time: returns the default time of the subscription in time units; the
      subscription type should be defined through request parameters in the user form (see
      "Form: User" in this chapter)
      subscription_unit_cost: returns the cost of the time unit for the paid subscription for a
      single translation of the publication
      subscription_unit_cost_all_lang: returns the cost of the time unit for the paid subscription
      for all translations of the publication

For more details on these attributes see also "Creating a Publication" chapter.

DEFAULT PUBLICATION
The "default_publication" object is set at the beginning of the main template based on the
request URL and can not be modified. It has the same attributes as the publication object (see
"Publication" in this chapter).

ISSUE
The "issue" object is set at the beginning of the main template based on the request URL. This
object can be changed using the set_issue function (see "Set Issue" in this chapter). The issue
object has the following properties:


      name: issue name
      number: issue identifier in the Campsite database (integer value)
      <date_attribute>: issue publish date field (year, month, day etc.)
      date: the issue publish date; you can customize the date display format by using the filter
      camp_date_format (see "Date Formatting" in this chapter)
      publish_date: alias of date
      template: the full path of the issue template file
      publication: the publication to which this issue belongs to - object of type publication (see
      "Publication" in this chapter)
      language: the issue language - object of type language (see "Language" in this chapter)
      url_name: the issue name used in URL display (see "Creating New Issue" chapter)
      defined: boolean value (true/false) - true if the issue was set in the current environment;
      false otherwise
      is_current: true if the issue set in the environment was the latest published issue

<date_attribute> may be one of the following:




                                                                                                      159
      year: year (four digits)
      mon: month as a number (1..12)
      mday: day of the month as a number (1..31)
      yday: day of the year (1..366)
      wday: day of the week as a number (0=Sunday..6=Saturday)
      hour: hour (0..23)
      min: minute (two digits)
      sec: seconds (two digits)
      mon_name: name of the month
      wday_name: day of the week

DEFAULT ISSUE
The "default_issue" object is set at the beginning of the main template based on the request URL
and can not be modified. It has the same attributes as the issue object (see "Issue" in this
chapter).

SECTION
The "section" object is set at the beginning of the main template based on the request URL. This
object can be changed using the set_section function (see "Set Section" in this chapter). The
section object has the following properties:


      name: section name
      number: section identifier in the Campsite database
      description: section description text
      url_name: the section name used in URL display (see Creating a section at "Creating a
      Publication" chapter)
      template: the full path of the issue template file
      publication: the publication to which this section belongs to - object of type publication (see
      "Publication" in this chapter)
      issue: the issue to which this section belongs to - object of type issue (see "Issue" in this
      chapter)
      language: the section language - object of type language (see "Language" in this chapter)
      defined: boolean value (true/false) - true if the section was set in the current environment;
      false otherwise

DEFAULT SECTION
The "default_section" object is set at the beginning of the main template based on the request
URL and can not be modified. It has the same attributes as the section object (see "Section" in
this chapter).

ARTICLE
The "article" object is set at the beginning of the main template based on the request URL. This
object can be changed using the set_article function (see "Set Article" in this chapter). The article
object has the following properties:

Base properties/functions:




160
      name: article name
      number: article identifier in the Campsite database
      author: returns an object with the following properties:
           name
           first_name
           last_name
           email (will be enabled in version 3.4)
           defined
      keywords: text containing the article keywords separated by the Campsite defined
      separator (default is comma [,])
      has_keyword(<keyword>): returns true if the given keyword existed in the article
      keywords list
      Example:
      {{ if $campsite->article->has_keyword (mp3podcast) }}<span class="audio"></span>{{ /if
      }}

      Important: the command matches parts of the keyword. In the above example keywords
      "mp3podcast10" and "mp3podcasttalk" both return true.
      type_name: article type name (see "Article Types" chapter)
      type_translated: article type name translated to the environment language
      <date_attribute>: article creation date field (year, month, day etc.) - see below
      creation_date: article creation date; you can customize the date display format by using
      the filter camp_date_format (see "Date Formatting" in this chapter)
      publish_date: article publish date; you can customize the date display format by using the
      filter camp_date_format (see "Date Formatting" in this chapter)
      last_update: time of the last article edit
      template: the full path of the article template file
      type->[<article_type>]-><article_type_attribute>: returns the content of an article field
      specific to a certain article type (see "Article Types" chapter); read Date Formatting for
      formatting the content of type date/time; see also the notes below
      url_name: the article name used in URL display (see "Creating Articles" chapter)
      translated_to(<language_code>): true if an article translation for the language with the
      given code existed
      subtitles_count(<field_name>): returns the number of the subtitles in the given content
      field; the article name is counted as the first subtitle so this function returns a number
      greater or equal to 1. If the specified field was not a content field it returns null.
      subtitle_url_id(<field_name>): returns the URL parameter which sets the number of the
      subtitle to be displayed from the field <field_name>
      current_subtitle_no(<field_name>): returns the number of the subtitle which will be
      displayed through the statement {{ $campsite->article-><field_name> }}; 0 for the default
      subtitle, 1 for the first subtitle defined in the article content field etc.
      publication: the publication to which this article belongs to - object of type publication (see
      "Publication")
      issue: the issue to which this article belongs to - object of type issue (see "Issue")
      section: the section to which this article belongs to - object of type section (see "Section")
      language: the article language - object of type language (see "Language")
      owner: the user who created the article - object of type user (see "User")
      defined: boolean value (true/false) - true if the article was set in the current environment;
      false otherwise

Comments related properties/functions:

      comments_enabled: true if comments were enabled for the article publication, article type
      and the current article
      comments_locked: true if comments were locked (meaning they can be listed but no new
      comments can be posted)
      comment_count: returns the number of the comments posted to the article and approved

Accessibility properties/functions:




                                                                                                        161
      on_front_page: true if article front page flag was set
      on_section_page: true if article section page flag was set
      is_published: true if the article was published
      is_public: true if the article was accessible to the public
      is_indexed: true if the article was indexed by the search engine
      content_accessible: returns true if the content of the article is accessible for reading:
      either is public or the reader subscribed to the publication (see also "Editing Articles" and
      "Setting up Subscriptions")

Attachment related properties/functions:

      has_attachments: true if the article had attached files
      image: returns the image object that was defined in the template environment; if the
      image was not defined in the environment, returns the first image of the article; if the
      article didn't have any image attached returns an unset image object
      image_index: returns the index of the current image inside the article; if the image wasn't
      defined in the environment or it doesn't belong to the article returns null.
      has_image(<image_index>): true if the article had an attached image and it's index was
      equal to the given index
      image(<image_index>): returns the attached image having the given index; if no such image
      existed, returns an unset image object. This is a function so the image index is given in
      between brackets. E.g.: $campsite->article->image(3)
      image<image_index>: returns the attached image having the given index; if no such image
      existed, returns an unset image object. This is a property, not a function. E.g.: $campsite-
      >article->image3
      topics_count: returns the number of topics attached to this article
      has_topics: true if the article had attached topics
      has_topic(<topic_identifier>): true if the article had the specified topic attached to it

Statistics properties/functions:

      reads: returns the number of readers that viewed this article since it was published
      request_object_id: the identifier used in statistics gathering

<date_attribute> may be one of the following:

      year: year (four digits)
      mon: month as a number (1..12)
      mday: day of the month as a number (1..31)
      yday: day of the year (1..366)
      wday: day of the week as a number (0=Sunday..6=Saturday)
      hour: hour (0..23)
      min: minute (two digits)
      sec: seconds (two digits)
      mon_name: name of the month
      wday_name: day of the week

Note regarding the attribute type->[<article_type>->]<article_type_attribute>:

Attributes which are body fields (content) have the following properties:

      all_subtitles: returns the whole content of the body field, not just the current subtitle
      first_paragraph: returns the first paragraph of the current subtitle
      subtitles_count: returns the number of the subtitles in the body field
      subtitle_number: returns the number of the current subtitle: 0 for the default subtitle, 1
      for the first subtitle defined in the article content field etc.
      subtitle_is_current: true if the subtitle that would be displayed through the statement {{
      $campsite->article-><article_type_attribute> }} is the same as the subtitle defined in the
      template environment (see also "Subtitle" and current_subtitle_no(<field_name>) above)
      has_previous_subtitles: true if the current subtitle from this field was not the first subtitle
      has_next_subtitles: true if the current subtitle from this field was not the last subtitle

E.g.: displaying the first paragraph of the dynamic field "content":

162
$campsite->article->content->first_paragraph

Note regarding the attribute type->[<article_type>->]<article_type_attribute>: Starting
with Campsite 2.3.0 the table cell containing the image link in article body fields has the class
cs_img and the cell containing the caption text has the class "caption"; this allows the web
designer to change the layout of the article images by using a CSS file. The new image link has
the following structure:
<table border="0" cellspacing="0" cellpadding="0" class="cs_img" align=left>
  <tr>
    <td align="center">
       <img src="/get_img?NrArticle=143&NrImage=1" border="0"
            hspace="5" vspace="5">
    </td>
  </tr>
  <tr><td align="center" class="caption">Campsite team</td></tr>
</table>

Note regarding the attribute type->[<article_type>->]<article_type_attribute>: Starting
with Campsite 2.3.3 the subtitle in the article body fields has the class articlesubhead; this allows
the web designer to change the layout of the subtitles by using a CSS file. The subtitle anchor
has the following structure:
<span class="articlesubhead">
    <a name="a1.250_s1">Version 2.3.0 - 2.3.1</a>
</span>

The structure of the anchor name is:

a<language_identifier>.<article_number>_s<subtitle_number>

See also:

      Displaying Article Info
            Articles List
            URI
            Setting the Context Article
      Breaking an article into multiple parts
            Subtitle
            Subtitles List
            Current List
      Displaying Image Info
            Image
            Article Images List
      Displaying Topics
            Topic
            Article Topics List
      Displaying Attachments
            Article Attachment
            Article Attachments List
      Comments
            ArticleComment
            Article Comments List




DEFAULT ARTICLE
The "default_article" object is set at the beginning of the main template based on the request
URL and can not be modified. It has the same attributes as the article object.




ARTICLE ATTACHMENT


                                                                                                        163
The "article_attachment" object is usually initialized inside a list of article attachments. It is not
initialized at the beginning of the template and can not be initialized by other campsite function.
The article attachment object has the following properties:

      identifier: the attachment identifier in the Campsite database (integer value)
      file_name: the name of the attached document
      mime_type: the mime type of the attached document
      extension: the file extension of the attached document
      description: the user filled description field of the attached document in the current
      language
      size_b: the size of the attached document in bytes
      size_kb: the size of the attached document in kilobytes
      size_mb: the size of the attached document in megabytes
      defined: boolean value (true/false) - true if the attachment was set in the current
      environment; false otherwise




AUDIO ATTACHMENT
The "audio_attachment" object is usually initialized inside a list of audio attachments. It is not
initialized at the beginning of the template and can not be initialized by other campsite function.
The audio attachment object has the following properties:

      title
      creator
      genre
      length
      year
      bitrate
      samplerate
      album
      description
      format
      label
      composer
      channels
      rating
      track_no
      disk_no
      lyrics
      copyright
      defined




ARTICLE COMMENT
The "article_comment" object is usually initialized inside a list of article comments. It can be
initialized at the beginning of the template from the URL request but can not be initialized by
other campsite function. The article comment object has the following properties:

      identifier: the numerical identifier of the article comment from the database
      real_name: the real name of the reader who posted the comment; the reader must be a
      registered campsite user; for anonymous readers this attribute will return an empty string
      nickname: the nickname of the reader who posted the comment
      reader_email: the email of the reader who posted the comment
      submit_date: the date and time the comment was submitted
      subject: the subject of the article comment
      content: the content of the article comment
      level: the level of the current comment in the tree structure of the comments
      defined: true if the comment object had a valid value
164
SUBTITLE
The "subtitle" object is usually initialized inside a list of subtitles. It can be initialized at the
beginning of the template from the URL request but can not be initialized by other campsite
function. The subtitle object has the following properties:

      number: the order number of the subtitle (starts from 0)
      name: subtitle name without the HTML formatting
      field_name: the article field name to which the subtitle belongs
      formatted_name: the subtitle name with HTML formatting
      content: the subtitle content
      count: the number of subtitles in the field content
      has_previous_subtitles: true if previous subtitles exist
      has_next_subtitles: true if subtitles exist after the current subtitle

See also Editing body-type fields: Working with the body field editor ("Using the WYSIWYG Article
Editor" chapter).




IMAGE
The "image" object is usually initialized inside a list of article images. It is not initialized at the
beginning of the template and can not be initialized by other campsite function. The image object
has the following properties:

      number: the image identifier in the images archive
      photographer: the name of the photographer that took the picture
      place: a short text containing the place where the picture was taken
      description: short description of the picture
      <date_attribute>: image creation date field (year, month, day etc.)
      date: image creation date; you can customize the date display format by using the filter
      camp_date_format (see "Date Formatting" in this chapter)
      article_index: returns the index of the current image inside the article defined in the
      environment; if the image wasn't defined in the environment, the article was not defined or
      the image didn't belong to the article returns null.
      imageurl: returns the URL of the current image
      thumbnailurl: returns the URL of the current image' thumbnail
      defined: boolean value (true/false) - true if the image was set in the current environment;
      false otherwise

<date_attribute> may be one of the following:

      year: year (four digits)
      mon: month as a number (1..12)
      mday: day of the month as a number (1..31)
      yday: day of the year (1..366)
      wday: day of the week as a number (0=Sunday..6=Saturday)
      hour: hour (0..23)
      min: minute (two digits)
      sec: seconds (two digits)
      mon_name: name of the month
      wday_name: day of the week




TOPIC


                                                                                                          165
The "topic" object is usually initialized inside a "List of article topics" or a "List of subtopics". It can
be initialized at the beginning of the template from the URL request or by using the "Set topic"
campsite function. The topic object has the following properties:

      name: return the topic name in the current language defined in the template environment
      value: returns the topic value in the following format:
      <topic_name_lang_code> = <topic_name>:<language_code>

      identifier: the topic identifier in the campsite database
      defined: true if the topic object had a valid value




DEFAULT TOPIC
The "default_topic" object is set at the beginning of the main template based on the request URL
and can not be modified. It has the same attributes as the "Topic" object.




USER
The "user" object is set at the beginning of the main template based on the session cookies or if
one of the following actions took place: "Login action", "Edit user action". It can not be initialized
by other campsite function. The user object has the following properties:




166
      identifier: the user identifier in the campsite database
      name: the user full name
      uname: the user login name
      gender: "M" or "F"
      email
      city
      str_address: street address
      state
      phone
      fax
      country: the country name
      country_code: the country code
      contact
      second_phone
      postal_code
      employer
      position
      interests
      how
      languages
      improvements
      field1
      field2
      field3
      field4
      field5
      text1
      text2
      text3
      pref1
      pref2
      pref3
      pref4
      title
      age
      defined: true if the user object had a valid value
      logged_in: true if the user was defined and authenticated
      blocked_from_comments: true if the user was blocked from posting comments
      subscription: returns the first subscription assigned to this user; unset if the user was not
      a reader
      is_admin: true if the user was not a reader
      has_permission(<permission_name>): true if the user was not a reader and had the given
      permission




SUBSCRIPTION
The "user->subscription" object is set at the beginning of the main template based on the
session cookies or if the "Login action" took place. It can not be initialized by other campsite
function.The subscription object has the following properties:




                                                                                                      167
      identifier: the subscription identifier in the Campsite database
      currency: the currency identifier
      type: one of the following values: "trial", "paid"
      start_date: returns the start date of the subscription
      expiration_date: the expiration date in the format "yyyy-mm-dd hh:mm:ss"
      is_active: true if the subscription was active
      is_valid: true if the subscription was active and did not expire
      publication: returns the publication to which the subscription was made
      has_section(<section_number>): returns true if the subscription included the given section
      defined: true if the subscription object had a valid value




TEMPLATE
The "template" object is set at the beginning of the main template based on the request URL.
This object can not be changed using campsite functions. The template object has the following
properties:

      name: the template file name
      identifier: the template identifier in the Campsite database
      type: returns one of the following values: issue, section, article, default, nontpl
      defined: true if the template object had a valid value




DEFAULT TEMPLATE
The "default_template" object is set at the beginning of the main template based on the request
URL and can not be modified. It has the same attributes as the template object (see "Default
Template" in this chapter).




URL
The URL object follows the changes in the template environment, meaning that every time an
object in the environment changed the URL object is updated. It has the following properties:

      is_valid: returns true if the URL was valid, false otherwise. On invalid URLs Campsite
      returns "404 not found" HTTP response. This option only works in 3.4.0 and newer
      versions.
      {{ if !$campsite->url->is_valid }}
          <h3>The requested page was not found.</h3>
          {{ set_language name=`$campsite->publication->default_language->english_name`
      }}
          {{ set_current_issue }}
      {{ else }}
          <!-- display content -->
      {{ /if }}

      uri: returns the complete link URI and it is equivalent to:
      {{ $campsite->url->uri_path }}?{{ $campsite->url->url_parameters }}

      uri_path: returns only the path part of the URI, the part before the parameters list. E.g.: if
      /en/1/2/3?param1=text was the full URI, uri_path is /en/1/2/3.
      url: returns the complete URL in the form:
      url_parameters: returns a string containing the runtime environment parameters in URL
      format
      form_parameters: the runtime environment parameters in HTML form format:
      <input type="hidden" name="<param_name>" value="<param_value>">



168
      base: returns the URL base in the form: http[s]://<server_name>[:<port>]; the port is not
      displayed if it's value was the default value (80 for HTTP, 443 for HTTPS)
      path: equivalent to uri_path
      query: equivalent to url_parameters
      type: returns the identifier of the URL type set in the publication (see also "Creating a
      Publication" chapter)
      request_uri: equivalent to uri
      scheme: one of the following values: http, https
      host: the host name from the URL
      port: the port to which the request was made
      language: returns the language object corresponding to the language set in the URL; this
      value is always the same as the language in the environment (see "Language" in this
      chapter)
      publication: returns an object corresponding to the publication identified by the
      <server_name>; this value is always the same as the publication in the environment (see
      "Publication" in this chapter)
      issue: returns an object corresponding to the issue specified in the URL (unset if the issue
      was not specified); this value is always the same as the issue in the environment (see
      "Issue" in this chapter)
      section: returns an object corresponding to the section specified in the URL (unset if the
      section was not specified); this value is always the same as the section in the environment
      (see "Section" in this chapter)
      article: returns an object corresponding to the article specified in the URL (unset if the
      article was not specified); this value is always the same as the article in the environment
      (see "Article" in this chapter)

The URL object has the following functions:

      get_parameter(<parameter_name>): returns the value of the given parameter, null if not
      set
      set_parameter(<parameter_name>, <parameter_value>): set the given parameter to the
      given value
      reset_parameter(<parameter_name>): unset the given parameter




DEFAULT URL
The "default_url" object is set at the beginning of the main template based on the request URL
and can not be modified. It has the same attributes as the url object (see "URL" in this chapter).




CURRENT LIST
The "current_list" is defined inside a list statement only. If multiple lists are embedded then the
current_list object refers to the most internal list in which the current_list object was used. E.g.:
{{ list_sections }}
    {{ $campsite->current_list->index }} {{* refers to the sections list *}}
    {{ list_articles }}
        {{ $campsite->current_list->index }} {{* refers to the articles list *}}
    {{ /list_articles }}
    {{ $campsite->current_list->index }} {{* refers to the sections list *}}
{{ /list_sections }}

The object has the following properties:




                                                                                                        169
      column: if the "columns" parameter was set the column is incremented from 1 to
      "columns" and then reset to 1
      columns: the number of columns set in the list
      current: returns the current element in the list
      end: returns the index of the last element of the list
      index: the index of the current element in the list; starts from 1 and is computed from the
      list "start" plus the number of the element in the interval of the list that was displayed
      length: the number of the objects in the interval of elements to be displayed from the list
      limit: the maximum length of the list to be displayed (0 for unlimited)
      name
      row: starts from 1 and is incremented each time the column was reset
      start: the index of the first element to be displayed from the list
      count: the actual number of objects in the list (regardless of the limit set by the user)
      at_beginning: true if the current element was the first in the interval of elements to be
      displayed
      at_end: true if the current element was the last in the list
      has_next_elements: true if the list was limited and there are other elements after the last
      element of the interval to be displayed
      has_previous_elements: true if the list was limited and there are other elements before
      the first element of the interval to be displayed
      previous_start: the index of the first element from the previous interval of elements
      next_start: the index of the next element from the next interval of elements
      id: internal id of the list set by the template engine




LOGIN ACTION
The "login_action" object is defined when a login action took place. It has the following properties:

      defined: true if a login action took place
      is_error: true if a login action took place and the result was an error
      error_code: error code of the login action; null if no login action took place
      error_message: error message of the login action; null if no login action took place
      ok: true if a login action took place and the result was success
      user_name: the login name of the user that attempted to log in
      remember_user: true if the remember user flag was set in the login form




SEARCH ARTICLES ACTION
The "search_articles_action" object is initialized when a search action took place. It has the
following properties:

      defined: true if a search action took place
      is_error: true if a search action took place and the result was an error
      error_code: error code of the search action; null if no search action took place
      error_message: error message of the search action; null if no search action took place
      ok: true if a search action took place and the result was success
      search_phrase: the phrase for which the search was performed
      search_keywords: an array of keywords for which the search was performed
      match_all: true if the match all flag was set
      search_level: 0 for multiple publication search, 1 for current publication search, 2 for
      current issue search, 3 for current section search
      submit_button: the submit button text
      template: the template used on search form submit




SUBMIT COMMENT ACTION
170
The "submit_comment_action" object is initialized when a comment form was submitted. It has
the following properties:

      defined: true if a comment submit action took place
      is_error: true if a comment submit action took place and the result was an error
      error_code: error code of the comment submit action; null if no comment submit action
      took place
      error_message: error message of the comment submit action; null if no comment submit
      action took place
      ok: true if a comment submit action took place and the result was success
      subject: the comment subject as filled in the form
      content: the comment content as filled in the form
      reader_email: the comment reader email as filled in the form




PREVIEW COMMENT ACTION
The "preview_comment_action" object is initialized when the preview button was clicked on a
comment form. It has the following properties:

      defined: true if a comment preview action took place
      is_error: true if a comment preview action took place and the result was an error
      error_code: error code of the comment preview action; null if no comment preview action
      took place
      error_message: error message of the comment preview action; null if no comment preview
      action took place
      ok: true if a comment preview action took place and the result was success
      subject: the comment subject as filled in the form
      content: the comment content as filled in the form
      reader_email: the comment reader email as filled in the form




EDIT USER ACTION
The "edit_user_action" object is initialized when a user add/edit form was submitted. It has the
following properties:




                                                                                                   171
      defined: true if a user data submit action took place
      is_error: true if a user data submit action took place and the result was an error
      error_code: error code of the user data submit action; null if no user data submit action
      took place
      error_message: error message of the user data submit action; null if no user data submit
      action took place
      ok: true if a user data submit action took place and the result was success
      type: can take one of the following two values: "add" for user add submit, "edit" for an
      existing user data edit submit
      name: the user full name as filled in the form
      uname: the user login name as filled in the form
      password: the account password as filled in the form
      passwordagain: the password confirmation
      email: the user email as filled in the form
      city
      str_address
      state
      phone
      fax
      contact
      second_phone
      postal_code
      employer
      position
      interests
      how
      languages
      improvements
      field1
      field2
      field3
      field4
      field5
      text1
      text2
      text3
      country
      title
      gender
      age
      employertype
      pref1
      pref2
      pref3
      pref4




EDIT SUBSCRIPTION ACTION
The "edit_subscription_action" object is initialized when a subscription form was submitted. It has
the following properties:




172
defined: true if a subscription submit action took place
is_error: true if a subscription submit action took place and the result was an error
error_code: error code of the subscription submit action; null if no subscription submit
action took place
error_message: error message of the subscription submit action; null if no subscription
submit action took place
ok: true if a subscription submit action took place and the result was success
is_trial: true if the submitted subscription type was trial
is_paid: true if the submitted subscription type was paid subscription




                                                                                           173
49. ENVIRONMENTAL CONTROL
In this article:

      Set Language
      Set Default Language
      Unset Language
      Set Publication
      Set Default Publication
      Unset Publication
      Set Issue
      Set Current Issue
      Set Default Issue
      Unset Issue
      Set Section
      Set Default Section
      Unset Section
      Set Article
      Set Default Article
      Unset Article
      Set Topic
      Set Default Topic
      Unset Topic
      Unset Comment




SET LANGUAGE
Purpose:

Sets the runtime environment language to the one selected by English name. From this
statement on the language is the new chosen one. If the name supplied was not valid this
variable is not modified.

Syntax:
{{ set_language name="<language_name>" }}

where <language_name> is the English name of selected language.

Constraints:

Can not be used inside any list statement.

See also "set_default_language", "unset_language".




SET DEFAULT LANGUAGE
Purpose:

Sets the runtime environment language to the "default_language".

Syntax:
{{ set_default_language }}

Constraints:


174
Cannot be used inside any list statement.

See also "set_language", and "unset_language".




UNSET LANGUAGE
Purpose:

Unset the runtime environment language. After this statement the language object will not be
defined anymore.

Syntax:
{{ unset_language }}

Constraints:

Cannot be used inside "list_articles", "list_article_attachments", "list_article_comments",
"list_article_comments", "list_article_topics", "list_article_audio_attachments",
"list_search_results" and "list_subtitles" statements.

See also "set_language", and "set_default_language".




SET PUBLICATION
Purpose:

Sets the runtime environment publication to the one selected by the statement constraint. If the
statement constraint was not valid the publication is not changed.

Syntax:
{{ set_publication name="<publication_name>" }}

Select the publication having the specified name. If the name supplied was not valid, this
parameter is not modified.
{{ set_publication identifier="<publication_identifier>" }}

Select the publication having the specified identifier. The publication identifier is a unique number
associated to the publication and is supplied by the administration interface.

Constraints:

Cannot be used inside any list statement.

See also "set_default_publication", "unset_publication".




SET DEFAULT PUBLICATION
Purpose:

Sets the runtime environment publication to the "default_publication".

Syntax:
{{ set_default_publication }}

Constraints:


                                                                                                        175
Cannot be used inside any list statement.

See also "set_publication", "unset_publication".




UNSET PUBLICATION
Purpose:

Unset the runtime environment publication. After this statement the publication object will not
be defined anymore.

Syntax:
{{ unset_publication }}

Constraints:

Cannot be used inside any list statement.

See also "set_publication", "set_default_publication".




SET ISSUE
Purpose:

Sets the runtime environment issue to the one selected by the statement constraint. If the
statement constraint was not valid the issue is not changed.

Syntax:
{{ set_issue number="<issue_number>" }}

Select the issue having the specified number. If number supplied was not valid this parameter is
not changed.

Constraints:

Cannot be used inside any list statement.

See also "set_default_issue", "set_current_issue", "unset_issue".




SET CURRENT ISSUE
Purpose:

Sets the runtime environment issue to the last published issue.

Syntax:
{{ set_current_issue }}

Constraints:

Cannot be used inside any list statement.

See also "set_issue", "set_default_issue", "unset_issue".




SET DEFAULT ISSUE
176
Purpose:

Sets the runtime environment issue to the "default_issue".

Syntax:
{{ set_default_issue }}

Constraints:

Cannot be used inside any list statement.

See also "set_issue", "set_current_issue", "unset_issue".




UNSET ISSUE
Purpose:

Unset the runtime environment issue. After this statement the issue object will not be defined
anymore.

Syntax:
{{ unset_issue }}

Constraints:

Cannot be used inside any list statements.

See also "set_issue", "set_current_issue", "set_default_issue".




SET SECTION
Purpose:

Sets the runtime environment section to the one selected by the statement constraint. If the
statement constraint was not valid the section is not changed.

Syntax:
{{ set_section name="<section_name>" }}

Select the section having the specified name; this has to be written in the language of the
context. If the name supplied was not valid this parameter is not modified.
{{ set_section number="<section_number>" }}

Select the section having the specified number; this is not dependent on context language. If the
number supplied was not valid this parameter is not modified.

Constraints:

Cannot be used inside "list_sections", "list_articles", "list_article_attachments",
"list_article_comments", "list_article_comments", "list_article_topics",
"list_article_audio_attachments", "list_search_results" and "list_subtitles" statements.

See also "set_default_section", "unset_section".




SET DEFAULT SECTION

                                                                                                    177
Purpose:

Sets the runtime environment section to the "default_section".

Syntax:
{{ set_default_section }}

Constraints:

Cannot be used inside "list_sections", "list_articles", "list_article_attachments",
"list_article_comments", "list_article_comments", "list_article_topics",
"list_article_audio_attachments", "list_search_results" and "list_subtitles" statements.

See also "set_section", "unset_section".




UNSET SECTION
Purpose:

Unset the runtime environment section. After this statement the section object will not be
defined anymore.

Syntax:
{{ unset_section }}

Constraints:

Cannot be used inside "list_sections", "list_articles", "list_article_attachments",
"list_article_comments", "list_article_comments", "list_article_topics",
"list_article_audio_attachments", "list_search_results" and "list_subtitles" statements.

See also "set_section", "set_default_section".




SET ARTICLE
Purpose:

Sets the runtime environment article to the one selected by the statement constraint. If the
statement constraint was not valid the section is not changed.

Syntax:
{{ set_article name="<article_name>" }}

Select the article having the specified name. If the supplied name was not valid this parameter is
not be modified.
{{ set_article number="<article_number>" }}

Select the article having the specified number. If the supplied value was not valid this parameter
is not be modified.

Constraints:

Cannot be used inside "list_articles", "list_article_attachments", "list_article_comments",
"list_article_comments", "list_article_topics", "list_article_audio_attachments",
"list_search_results" and "list_subtitles" statements.

See also "set_default_article", "unset_article".



178
SET DEFAULT ARTICLE
Purpose:

Sets the runtime environment article to the "default_article".

Syntax:
{{ set_default_article }}

Constraints:

Cannot be used inside "list_articles", "list_article_attachments", "list_article_comments",
"list_article_comments", "list_article_topics", "list_article_audio_attachments",
"list_search_results" and "list_subtitles" statements.

See also "set_article", "unset_article".




UNSET ARTICLE
Purpose:

Unset the runtime environment article. After this statement the article object will not be defined
anymore.

Syntax:
{{ unset_article }}

Constraints:

Cannot be used inside "list_articles", "list_article_attachments", "list_article_comments",
"list_article_comments", "list_article_topics", "list_article_audio_attachments",
"list_search_results" and "list_subtitles" statements.

See also "set_default_article", "unset_article".




SET TOPIC
Purpose:

Sets the runtime environment topic to the one selected by the statement constraint. If the
statement constraint was not valid the topic is not changed. Setting the environment topic will
change the behavior of articles list: only articles having that topic will be listed.

E.g.:
{{ set_topic name="test:en" }}
{{ list_articles }}
...
{{ /list_articles }}

This will list only articles having the topic 'test'. The topic is automatically appended to the URL
parameters so you don't have to set the topic in the current page.

E.g.:
{{ set_topic name"test:en" }}
<a href="{{ uri }}">text</a>

Syntax:
{{ set_topic name="<topic_name_lang_code>" }}

                                                                                                       179
{{ set_topic identifier="<integer_value>" }}

Select the topic having the specified name-language code or identifier. If the supplied value was
not valid this variable is not modified. The name must be written in the following format:
<topic_name_lang_code> = <topic_name>:<language_code>

Examples: sport:en, music:en etc. where 'sport' is the topic name and 'en' is the English language
code.

Constraints:

Cannot be used inside "list_articles" and "list_article_topics" statements.

See also "set_default_topic", "unset_topic".




SET DEFAULT TOPIC
Purpose:

Sets the runtime environment topic to the "default_topic".

Syntax:
{{ set_default_topic }}

Constraints:

Constraints:

Cannot be used inside "list_articles" and "list_article_topics" statements.

See also "set_topic", "unset_topic".




UNSET TOPIC
Purpose:

Unset the runtime environment topic. After this statement the topic object will not be defined
anymore.

Syntax:
{{ unset_topic }}

Constraints:

Cannot be used inside "list_articles" and "list_article_topics" statements.

See also "set_default_topic", "unset_topic".




UNSET COMMENT
Purpose:

Unset the runtime environment comment. After this statement the comment object will not be
defined anymore.

Syntax:
{{ unset_comment }}

180
Constraints:

Cannot be used inside "list_article_comments" statement.




                                                           181
50. LISTS
In this chapter:

        List   of   Languages
        List   of   Issues
        List   of   Sections
        List   of   Articles
        List   of   Article Attachments
        List   of   Article Comments
        List   of   Article Images
        List   of   Article Topics
        List   of   Article Audio Attachments
        List   of   Search Results
        List   of   Subtitles
        List   of   Subtopics

LIST OF LANGUAGES
Note: this works only in 3.2.1 and newer versions.

Purpose:

Select the list of languages according to the given constraints and current environmental
variables. The language variable may not be defined outside list_languages statement; inside the
statement however, this variable is defined. The code between "{{list_languages}}" statement
and "{{/list_languages}}" is repeated for every language in the list.

Syntax:
{{ list_languages [length="<integer_value>"]
        [columns="<integer_value>"]
        [of_publication="true|false"]
        [of_issue="true|false"]
        [of_article="true|false"]
        [exclude_current="true|false"]
        [order="<order_condition>"] }}
    <list_of_instructions>
{{ /list_languages }}


where:

        length="<integer_value>": <integer_value> specifies the list length and forces the list to
        have at most list_length items. If the list contains more items than list_length items the
        intervals of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>":<integer_value> specifies the list columns number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.
        of_publication: if true, will list languages in which publication issues were translated
        of_issue: if true, will list languages in which the current issue was translated
        of_article: if true, will list languages in which the current article was translated
        exclude_current: if true, will not include the current language in the list

When none of the three attributes (of_publication, of_issue, of_section) was specified it will list all
available languages in Campsite.

<list_of_instructions> may contain any statement except those listed at the end of the page.

<order_condition>= byNumber desc|asc
                   |byName desc|asc
                   |byEnglish_Name desc|asc

182
                           |byCode desc|asc

Order conditions are self-explanatory.

Inside the List the following environment variable is modified:

        language: if not defined before list start

The environment is restored after the list ends.

Constraints:

Inside list_issues the following statements are forbidden:

        set_language
        set_default_language
        unset_language
        list_languages

LIST OF ISSUES
Purpose:

Select the list of issues according to the given constraints and current environmental variables.
The publication, language and issue variables may not be defined outside list_issues statement;
inside the statement however, all these variables are defined. The code between "{{ list_issues
}}" statement and "{{ /list_issues }}" is repeated for every issue in the list.

Syntax:
{{ list_issues [length="<integer_value>"]
        [columns="<integer_value>"]
        [constraints="<list_of_issue_constraints>"]
        [order="<order_condition>"] }}
    <list_of_instructions>
{{ /list_issues }}


where:

        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

<list_of_instructions> may contain any statement except: "set_language", "set_publication",
"list_issues", "set_issue".

<list_of_issue_constraints>=                [<issue_constraint>] <list_of_issue_constraints>
                                            | <issue_constraint>
<issue_constraint>=            number<integer_operator> <integer_value>
                               |name <string_operator> <string_value>
                               |publish_date <date_operator> <date_value>
                               |publish_year <integer_operator> <integer_value>
                               |publish_month <integer_operator> <integer_value>
                               |publish_mday <integer_operator> <integer_value>
                               |<date_constraint>
<date_constraint>=             year <integer_operator> <integer_value>
                               |mon_nr <integer_operator> <integer_value>
                               |mday <integer_operator> <integer_value>
                               |yday <integer_operator> <integer_value>
                               |wday <integer_operator> <integer_value>

                                                                                                          183
                               |hour <integer_operator> <integer_value>
                               |min <integer_operator> <integer_value>
                               |sec <integer_operator> <integer_value>

where year stands for year, mon_nr for month number (1..12), mday for month day (1..31), yday
for year day (1..365), wday for week day (1..7), hour for hour, min for minute and sec for second.

Any parameter used in <list_of_issue_constraints> can only be used once.

<order_condition>=             byNumber desc|asc
                               |byName desc|asc
                               |byDate desc|asc
                               |byCreationDate desc|asc
                               |byPublishDate desc|asc

Order conditions are self-explanatory; byDate and byCreationDate are aliases of byPublishDate.

Inside the List the following environment variables are modified:

        language: if not defined before list start
        publication: if not defined before list start
        issue

The environment is restored after the list ends.

Constraints:

Inside list_issues the following statements are forbidden:

        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        unset_issue

list_issues statement can not be used inside any other list statements.

LIST OF SECTIONS
Purpose:

Select the list of sections according to the given constraints and current environmental variables.
The publication, language, issue and section variables may not be defined outside list_sections
statement; inside the statement however, all these variables are defined. The code between "{{
list_sections }}" statement and "{{ /list_sections }}" is repeated for every section in the list.

Syntax:
{{ list_sections [length="<integer_value>"]
        [columns="<integer_value>"]
        [constraints="<list_of_section_constraints>"] }}
    <list_of_instructions>
{{ /list_sections }}


where:




184
        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

<list_of_instructions> may contain any statement except: "set_language", "set_publication",
"list_issues", "set_issue", "list_section", "set_section".

<list_of_section_constraints>=    [<section_constraint>] <list_of_section_constraints>
                                  | <section_constraint>
<section_constraint>= name <string_operator> <string_value>
                      | number <integer_operator> <integer_value>

Any parameter used in <list_of_section_constraints> can only be used once.

Inside list_sections, the data context is defined by the constraints applied to the current section
for every processed line. The data context is restored after the list processing.

Constraints:

Inside list_sections the following statements are forbidden:

        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        unset_issue
        list_section
        set_section
        set_default_section
        unset_section

list_sections statement cannot be used inside list_articles, list_subtitles, list_search_results
statements.

LIST OF ARTICLES
Purpose:

Select the list of articles according to the given constraints and current environmental variables.
The publication, language, issue, section and article variables may not be defined outside
list_articles statement; inside the statement however, all these variables are defined. The code
between "{{ list_articles }}" statement "{{ /list_articles }}" is repeated for every article in the list.

Syntax:
{{ list_articles [length="<integer_value>"]
        [columns="<integer_value>"]
        [constraints="<list_of_article_constraints>"]
        [ignore_issue="true"] [ignore_section="true"]
        [ignore_language="true"]
        [order="<order_condition>"] }}
    <list_of_instructions>
{{ /list_articles }}


where


                                                                                                            185
      length="<integer_value>": <integer_value> specifies list_length and forces the list to have
      at most list_length items. If the list contains more items than list_length items the intervals
      of elements to be displayed can be switched using
      has_previous_elements/has_next_elements from the current_list object.
      columns="<integer_value>": <integer_value> specifies columns_number and sets an
      environment variable. This is incremented as if the items would be placed in a table cell.
      The counting starts from one and the variable is incremented for every new element.
      When it reaches the maximum value it is reset to one. This is very useful in building tables
      of data. For details see current_list.
{{ list_articles length="10" columns="2" order="byPublishDate desc"}}
{{ if $campsite->current_list->column == "1" }}
left column
{{ /if }}
{{ /list_articles }}

      ignore_issue: list articles from all issues, not only from the environment issue; if the section
      was defined it will list only articles from the environment section
      ignore_section: list articles from all sections, not only from the environment section
      ignore_language: list articles in all languages; if the issue and section were defined in the
      environment it lists only articles belonging to the environment issue/section

<list_of_instructions> may contain any statement except those listed at the end of the page.

<list_of_article_constraints>=       [<article_constraint>] <list_of_article_constraints>
                                     | <article_constraint>
<article_constraint>= name <string_operator> <string_value>
                      |number <integer_operator> <integer_value>
                      |keyword <string_value>
                      |OnFrontPage [<switch_operator> <switch_value>]
                      |OnSection [<switch_operator> <switch_value>]
                      |upload_date <date_operator> <date_value>
                      |publish_date <date_operator> <date_value>
                      |public <switch_operator> <switch_value>
                      |type <switch_operator> <article_type>
                      |[<article_type>] <article_type_attribute> <attribute_type_operator>
                      <attribute_type_value>
                      |matchAllTopics
                      |matchAnyTopic
                      |topic is|not <string_value>
                      |reads <integer_operator> <integer_value>
                      |author <string_operator> <string_value>
                      |issue <integer_operator> <integer_value>
                      |section <integer_operator> <integer_value>
Examples of constraints:
constraints="issue greater 10 issue smaller 20"
constraints="section greater_equal 40 section smaller 60"




186
        name, number, upload_date, publish_date are self explaining article attributes
        keyword: all articles containing the specified keyword (and respecting all the other
        constraints) will be in the list
        OnFrontPage: articles having "Show article on front page" flag in <⁞switch_operator>
        relation with <switch_value> will be selected; for details see Creating articles within a
        section
        OnSection: articles having "Show article on section page" flag in <switch_operator> relation
        with <switch_value> will be selected; for details see Creating articles within a section
        public: articles having "Allow users without subscription..." flag in <switch_operator>
        relation with <switch_value> will be selected
        type: only articles having the given time will be selected
        ... <article_type_attribute> ...: articles being of <article_type> and having
        <article_type_attribute> in <attribute_type_operator> relation with <attribute_type_value>
        will be selected; for details see "Article Types"
        matchAllTopics/matchAnyTopic: defines the behavior of the list when matching articles
        topics against the list of topics given as parameters:
               matchAllTopics will force the selection of articles that have all the given topics
               matchAnyTopic (default) will select articles that have at least one topic from the
               given topic list
        topic: if "is" operator is used, articles having specified topic in their list of topics will be
        selected; if "not" operator is uses articles not having specified topic in their list of topics
        will be selected
        reads: you can set constraints based on the number of readers that viewed this article
        since it was published
        author: you can list articles that have or don't have a certain author; e.g.: "author is John\
        Doe" (the backslash is needed to escape the space character - see Language Elements;
        Conventions at the bottom of the page). The author attribute has a predefined value
        "__current"; when using this value the author will be filled in from the currently defined
        article. E.g.: "author is __current".

Note on author attribute: this works only in 3.2.1 and newer versions.

Note on topics: the topic name must be written in the following format:
<topic_name>:<language_code>

Examples of valid topic names: sports:en, health:en etc.

Note on topics: If a certain topic was defined in the template environment by use of "set_topic"
statement or URL parameter the list will change the behavior of articles list: only articles having
that topic will be listed.

E.g.:
{{ set_topic name="test:en" }}
{{ list_articles }}
...
{{ /list_articles }}


This will list only articles having the topic 'test'. The topic is automatically appended to the URL
parameters so you don't have to set the topic in the current page.




                                                                                                           187
<order_condition>=         byNumber desc|asc
                           |byName desc|asc
                           |byDate desc|asc
                           |byCreationDate desc|asc
                           |byPublishDate desc|asc
                           |byLastUpdate desc|asc
                           |byPopularity desc|asc
                           |byPublication desc|asc
                           |byIssue desc|asc
                           |bySection desc|asc
                           |byLanguage desc|asc
                           |bySectionOrder desc|asc
                           |byComments desc|asc
                           |byLastComment desc|asc

      byComments instructs the Campsite to list articles by the number of comments filed to
      each article.
      byLastComment will list articles ordered by the last article comment time.
      byDate is an alias of byCreationDate.
      The other order conditions are self-explanatory.
      The default order of articles in the list (if no order condition was set) is: first they are
      ordered by the issue number descending, then by the section number ascending and by the
      article order in the section ascending.

Note: ByComments and byLastComment only work in Campsite 3.2.2 and newer.

Note: byLastUpdate is implemented in Campsite 3.5 and newer

Inside the list the data context is defined by the constraints applied to the current article for
every processed line. The data context is restored after the list processing.

Constraints:

Inside list_articles the following statements are forbidden:

      list_languages
      set_language
      set_default_language
      unset_language
      set_publication
      set_default_publication
      unset_publication
      list_issues
      set_issue
      set_default_issue
      set_current_issue
      unset_issue
      list_sections
      set_section
      set_default_section
      unset_section
      list_articles
      set_article
      set_default_article
      unset_article

list_articles statement cannot be used inside list_subtitles, list_search_results statements.

LIST OF ARTICLE ATTACHMENTS
Purpose:



188
Create a list of documents attached to the article currently defined in the template
environment. If the article was not set the list is empty. The code between "{{
list_article_attachments }}" statement and "{{ /list_article_attachments }} is repeated for every
attachment in the list.

Syntax:
{{ list_article_attachments [length="<integer_value>"]
        [columns="<integer_value>"]
        [language="current"] }}
    <list_of_instructions>
{{ /list_article_attachments }}


where

        all_languages: if true (default) the list will contain all article attachments independent of
        their language; if false, the list will contain only article attachments that have the language
        currently defined by the template environment.
        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.
        language="current": list only attachments that were set as available for all translations
        and available for the language currently set in the template environment

Inside list_articles the following statements are forbidden:

        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        set_current_issue
        unset_issue
        list_sections
        set_section
        set_default_section
        unset_section
        list_articles
        set_article
        set_default_article
        unset_article
        list_article_attachments

Inside the list, the current article attachment is set to the current element of the list. The
environment context is restored after the list processing.

Example:
{{ list_article_attachments }}
    {{ if $campsite->current_list->at_beginning }}
        <h4>Downloads:</h4>
{{ /if }}
<a href="/attachment/{{ $campsite->attachment->identifier }}">{{ $campsite->attachment->file_name }}</a> ({{ $campsite-
>attachment->size_kb }}kb)<br/>
{{ /list_article_attachments }}


Here is an example on how to use the attachment list to play a number of MP3-files:
{{ list_article_attachments }}
    {{ if $campsite->attachment->extension == "mp3" }}


                                                                                                                          189
        <object type="application/x-shockwave-flash" data="/templates/radioactive/apps/player_mp3_maxi.swf" width="200"
height="20">
             <param name="movie" value="/templates/radioactive/apps/player_mp3_maxi.swf" />
             <param name="bgcolor" value="#444444"/>
             <param name="FlashVars" value="mp3={{ uri options="articleattachment" }}" />
             <!-- player home: http://flash-mp3-player.net/ -->
        </object>
    {{ /if }}
{{ /list_article_attachments }}



LIST OF ARTICLE COMMENTS
Purpose:

Create a list of comments attached to the article currently defined in the template environment.
If the article was not defined the comments list is empty. The code between "{{
list_article_comments }}" statement and "{{ /list_article_commnets }}" is repeated for every
comment in the list.

Syntax:
{{ list_article_comments [ignore_language="true|false"]
        [ignore_article="true|false"]
        [length="<integer_value>"]
        [columns="<integer_value>"]
        [order="<order_condition>"] }}
    <list_of_instructions>
{{ /list_article_comments }}


where:

        ignore_language: list comments regardless of the comment language
        ignore_article: list comments for all articles, not only for the current article
        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

Note on ignore_article: this option will force the list order to date ordering.

Note: ignore_language and ignore_article only work in Campsite 3.2.2 and newer.

 <order_condition>=            byDate desc|asc
                               |default desc|asc

The default order of the comments in the list (if no order condition was specified) is based on the
tree structure of the comments as in the following example:

        root comment 1
              reply 1 (parent is root comment 1)
                    reply 1_1 (parent is reply 1)
        root comment 2
        ...

The first element in the list is the first comment that was submitted, second is it's first reply (if
exists), first reply of the first reply .. and so on down the tree structure until it finds no other
reply, second reply to the root element etc.

If the order by date condition was specified the comments are displayed strictly by their
submission date, regardless of the relation they had to the other comments.

Example:
{{ list_article_comments order="byDate desc" }}
    Subject: {{ $campsite->comment->subject }}<br/>
    Posted {{ $campsite->comment->submit_date }}
    by <b>{{ $campsite->comment->reader_email }}</b>
    <br/>
    {{ $campsite->comment->content }}


190
    <br/>
{{ /list_article_comments }}

Inside list_articles the following statements are forbidden:

        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        set_current_issue
        unset_issue
        list_sections
        set_section
        set_default_section
        unset_section
        list_articles
        set_article
        set_default_article
        unset_article
        list_article_comments

LIST OF ARTICLE IMAGES
Purpose:

Create a list of images attached to the article currently defined in the template environment. If
the article was not defined the list is empty. The code between "{{ list_article_images }}"
statement and "{{ /list_article_images }} is repeated for every image in the list.

Syntax:
{{ list_article_images [length="<integer_value>"]
        [columns="<integer_value>"] }}
    <list_of_instructions>
{{ /list_article_images }}


where:

        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

Example:
{{ set_language name="Deutsch" }}
{{ set_publication name="fluter" }}
{{ unset_issue }}
{{ set_section number="67" }}
{{* show image with index number 1 (when attached to article) *}}
{{ list_articles length="3" constraints="type is themaprint" }}
  {{ list_article_images }}
    {{ if $campsite->article->image->article_index == 1 }}
      <img src="../{{ $campsite->article->image->imageurl }}"
      title="{{$campsite->article->name }}">
    {{ /if }}
  {{ /list_article_images }}
{{ /list_articles }}


Inside list_articles the following statements are forbidden:
                                                                                                          191
        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        set_current_issue
        unset_issue
        list_sections
        set_section
        set_default_section
        unset_section
        list_articles
        set_article
        set_default_article
        unset_article
        list_article_images

Inside the list, the current image is set to the current element of the list. The environment
context is restored after the list processing.

LIST OF ARTICLE TOPICS
Purpose:

Create a list of topics attached to the article currently defined in the template environment. If
the article was not set the list is empty. The topic parameter may not be defined outside
list_article_topics statement; inside the statement however, this parameter is defined. The code
between "{{ list_article_topics }}" statement and "{{ /list_article_topics }}" is repeated for every
topic in the list.

Syntax:
{{ list_article_topics [length="<integer_value>"]
        [columns="<integer_value>"] }}
    <list_of_instructions>
{{ /list_article_topics }}


where:

        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

Inside list_articles the following statements are forbidden:




192
        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        set_current_issue
        unset_issue
        list_sections
        set_section
        set_default_section
        unset_section
        list_articles
        set_article
        set_default_article
        unset_article
        list_article_topics

Inside the list, the current topic is set to the current element of the list. The environment
context is restored after the list processing.

LIST OF ARTICLE AUDIO ATTACHMENTS
Purpose:

Create a list of audio files attached to the article currently defined in the template environment.
If the article was not set the list is empty. The code between "{{ list_article_audio_attachments
}}" statement and "{{ /list_article_audio_attachments }}" is repeated for every audio attachment
in the list. The order of the audio attachments is the same as in the administration interface.

Syntax:
{{ list_article_audio_attachments
        [length="<integer_value>"]
        [columns="<integer_value>"] }}
    <list_of_instructions>
{{ /list_article_audio_attachments }}


where:

        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

Inside list_articles the following statements are forbidden:




                                                                                                          193
        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        set_current_issue
        unset_issue
        list_sections
        set_section
        set_default_section
        unset_section
        list_articles
        set_article
        set_default_article
        unset_article
        list_article_audio_attachments

Inside the list, the current audio attachment is set to the current element of the list. The
environment context is restored after the list processing.

LIST OF SEARCH RESULTS
Purpose:

Create a list of articles that match the search keywords inputted by the reader. The publication,
language, issue, section, article variables may not be defined outside list_search_results
statement; inside the statement however, all these variables are defined. The code between "{{
list_search_result }}" statement and "{{ /list_search_result }}" is repeated for every article in the
list.

Syntax:
{{ list_search_results [length="<integer_value>"]
        [columns="<integer_value>"]
        [order="<order_condition>"] }}
    <list_of_instructions>
{{ /list_search_result }}


where:

        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

<list_of_instructions> may contain any statement except: "set_language", "set_publication".

<order_condition>=                 byDate desc|asc
                                   |byCreationDate
                                   |byPublishDate
                                   |byNumber desc|asc
                                   |byName desc|asc




194
Order conditions are self-explanatory; byDate is an alias of byCreationDate. The default order
of articles in the list (if no order condition was set) is: first they are ordered by the publication
identifier ascending, then by the issue number descending, then by the section number ascending
and by the article order in the section ascending.

Inside the list, the data context is defined by the constraints applied to the current article for
every processed line. The data context is restored after the list processing.

Constraints:

Inside list_articles the following statements are forbidden:

        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        set_current_issue
        unset_issue
        list_sections
        set_section
        set_default_section
        unset_section
        list_articles
        set_article
        set_default_article
        unset_article

LIST OF SUBTITLES
Purpose:

Create a list of subtitles for the content of the article currently defined in the template
environment. The article, if not specified somewhere else, is treated as group of paragraphs. The
markup for a new paragraph is the subtitle. The code between "{{ list_subtitles }}" statement
and "{{ /list_subtitles }}" is repeated for every subtitle in the list.

Syntax:
{{ list_subtitles [length="<integer_value>"]
        [columns="<integer_value>"] }}
    <list_of_instructions>
{{ /list_subtitles }}


where:

        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

<list_of_instructions> may contain any statement except: "set_language", "set_publication",
"list_issues", "set_issue", "list_sections", "set_section", "list_articles", "set_article".

Inside the list, the data context is defined by the constraints applied to the current article for
every processed line. The data context is restored after the list processing.

                                                                                                          195
Constraints:

Inside list_articles the following statements are forbidden:

        set_language
        set_default_language
        unset_language
        set_publication
        set_default_publication
        unset_publication
        list_issues
        set_issue
        set_default_issue
        set_current_issue
        unset_issue
        list_sections
        set_section
        set_default_section
        unset_section
        list_articles
        set_article
        set_default_article
        unset_article

LIST OF SUBTOPICS
Purpose:

Create a list of subtopics of the topic currently set in the template environment. If the topic was
not set it will generate the list of root topics. The topic parameter may not be defined outside
the list statement; inside the statement however, this parameter is defined. The code between
"{{ list_subtopics }}" statement and "{{ /list_subtopics }}" is repeated for every topic in the list.

Syntax:
{{ list_subtopics [length="<integer_value>"]
        [columns="<integer_value>"]
        [order="<order_condition>"] }}
    <list_of_instructions>
{{ /list_subtopics }}


where:

        length="<integer_value>": <integer_value> specifies list_length and forces the list to have
        at most list_length items. If the list contains more items than list_length items the intervals
        of elements to be displayed can be switched using
        has_previous_elements/has_next_elements from the current_list object.
        columns="<integer_value>": <integer_value> specifies columns_number and sets an
        environment variable. This is incremented as if the items would be placed in a table cell.
        The counting starts from one and the variable is incremented for every new element.
        When it reaches the maximum value it is reset to one. This is very useful in building tables
        of data. For details see current_list.

<list_of_instructions> may contain any statement except those listed at the end of the page.

<order_condition>=              byNumber desc|asc
                               |byName desc|asc

Inside the list, the data context is defined by the constraints applied to the current topic for
every processed line. The data context is restored after the list processing.

Constraints:

Inside list_subtopics the following statements are forbidden:


196
list_subtopics
set_topic
set_default_topic
unset_topic




                    197
51. FORMS
In this chapter:

      Form: Login
      Form: Search
      Form: Comment
      Form: User
      Form: Subscription
      Form Parameters
      Text Input Fields
      Edit Login
      Edit Search
      Edit Comment
      Edit CAPTCHA
      Edit User
      Edit Subscription
      Option Input Fields
      Select Login
      Select Search
      Select User
      Select Subscription
      CAPTCHA ImageLink




FORM: LOGIN
Purpose:

Generate the form and data fields for logging in a user.

Syntax:
{{ login_form [template="<template_name>"] submit_button="<button_name>"
              [html_code="<html_code>"]
              [button_html_code="<html_code>"] }}
<list_of_instructions>
{{ /login_form }}

      <template_name> is the name of the next template to be requested from login form.
      <button_name> is the name of the button for submitting the form.
      html_code: you can insert whatever HTML code you want in the <form> statement; e.g.: {{
      user_form .. html_code="id=\"my_id\"" }}
      button_html_code: you can insert whatever HTML code you want in the button input field
      statement; e.g.: {{ user_form .. button_html_code="id=\"my_submit_id\"" }}

Constraints:

Can not be used inside subscription and user forms. Cannot be used within itself (e.g. login in
login).

A simple example of implementing a login form on the front end of your publication:
{{ if ! $campsite->user->logged_in }}
    <p>Login</p>
    {{ if $campsite->login_action->is_error }}
        <p>There was an error logging in: {{ $campsite->login_action->error_message }}</p>
    {{ /if }}
    {{ login_form submit_button="Login" button_html_code="class=\"submitbutton\"" }}
        <p>User ID: {{ camp_edit object="login" attribute="uname" }}</p>
        <p>Password: {{camp_edit object="login" attribute="password" }}</p>
    {{ /login_form }}
{{ else }}
    <p>Welcome {{ $campsite->user->name }}</p>

198
    <p><a href="?logout=true">Logout</a></p>
{{ /if }}

Attention: the logout requires this code in the head of every page:
{{ if $campsite->url->get_parameter('logout') == 'true' }}
<META HTTP-EQUIV="Set-Cookie" CONTENT="LoginUserId=; path=/">
<META HTTP-EQUIV="Set-Cookie" CONTENT="LoginUserKey=; path=/">
{{ $campsite->url->reset_parameter('logout') }}
<META HTTP-EQUIV="Refresh" content="0;url={{ uri }}">
{{ /if }}




FORM: SEARCH
Purpose:

Generate the search form and data fields for searching keywords in published articles. By default
the search action is performed in the current publication only.

Syntax:
{{ search_form [template="<template_name>"] submit_button="<button_name>"
               [html_code="<html_code>"]
               [button_html_code="<html_code>"] }}
<list_of_instructions>
{{ /search_form }}

      <template_name> is the name of the next template to be requested from search form.
      <button_name> is the name of the button for submitting the form.
      html_code: you can insert whatever HTML code you want in the <form> statement; e.g.: {{
      user_form .. html_code="id=\"my_id\"" }}
      button_html_code: you can insert whatever HTML code you want in the button input field
      statement; e.g.: {{ user_form .. button_html_code="id=\"my_submit_id\"" }}

The list of instructions may contain any instruction allowed in the current context.

Setting the search scope: whether to search in all publications, in the current publication, in
the current issue or in the current section. Insert the following field in the search form:
{{ camp_select object="search" attribute="level" }}

Constraints:

Can not be used within itself (e.g. search in search).




FORM: COMMENT
Purpose:

Generate the form and default data fields for article comment submit. Inside the form camp_edit
statements can be used to generate article comment input fields.

Syntax:
{{ comment_form [template="<template_name>"]
                submit_button="<submit_button_name>"
                [preview_button="<preview_button_name>"]
                [html_code="<html_code>"]
                [button_html_code="<html_code>"] }}
<list_of_instructions>
{{ /comment_form }}




                                                                                                    199
      <template_name>: the name of the next template to be requested when submitting the
      comment
      <submit_button_name>: the name of the button for submitting the comment
      <preview_button_name>: the name of the button for previewing the comment
      html_code: you can insert whatever HTML code you want in the <form> statement; e.g.: {{
      user_form .. html_code="id=\"my_id\"" }}
      button_html_code: you can insert whatever HTML code you want in the button input field
      statement; e.g.: {{ user_form .. button_html_code="id=\"my_submit_id\"" }}




FORM: USER
Purpose:

Generate the form and data fields for adding a new user or editing an existing user data.

Syntax:
{{ user_form submit_button="<button_name>" [template="<template_name>"]
             [html_code="<html_code>"]
             [button_html_code="<html_code>"] }}
<list_of_instructions>
{{ /user_form }}

      <template_name> is the name of the next template to be requested from user form.
      <button_name> is the name of the button for submitting the form.
      html_code: you can insert whatever HTML code you want in the <form> statement; e.g.: {{
      user_form .. html_code="id=\"my_id\"" }}
      button_html_code: you can insert whatever HTML code you want in the button input field
      statement; e.g.: {{ user_form .. button_html_code="id=\"my_submit_id\"" }}

Constraints:

Can not be used inside subscription and login forms. Can not be used within itself (ex.: user in
user).




FORM: SUBSCRIPTION
Purpose:

Generate the form and default data fields for subscription. Inside this can be used Edit and Select
statements to generate fields for every section on issue.

Syntax:
{{ subscription_form type="<subscription_type>" [template="<template_name>"]
                     submit_button="<button_name>"
                     [total="<total_field_name>"]
                     [html_code="<html_code>"]
                     [button_html_code="<html_code>"] }}
<list_of_instructions>
{{ /subscription_form }}




200
       <subscription_type> has two values: by_publication and by_section
       <template_name> is the name of the next template to be requested from subscription
       form.
       <button_name> is the name of the button for submitting the form.
       <total_field_name> is the name of the field where the total payment is written.
       <evaluate_button_name> is the name of the evaluate button (when pressing this button
       the total payment is updated in the total field.
       html_code: you can insert whatever HTML code you want in the <form> statement; e.g.: {{
       user_form .. html_code="id=\"my_id\"" }}
       button_html_code: you can insert whatever HTML code you want in the button input field
       statement; e.g.: {{ user_form .. button_html_code="id=\"my_submit_id\"" }}

Constraints:

Cannot be used inside user and login forms. Can not be used within itself (ex.: subscription in
subscription).




FORM: PARAMETERS
"formparameters" prints the runtime environment parameters in HTML form format. It prints
only data context parameters and can be used to create links.

Syntax:
{{ formparameters [options="<options_list>"] }}
<options_list> = <option>
               | <option> <options_list>
option = fromStart
       | articleComment

where:

       fromstart: prints the parameters received at the start of template, not the current ones
       (useful when building site maps)
       articleComment: inserts the article comment identifier in the parameters list; if no article
       comment was defined in the template environment no parameter is inserted. This
       attribute is needed if you want to pass on the current comment id to another page for
       display purposes.




TEXT INPUT FIELDS
Purpose:

Generate an input text field; these fields are used in forms to allow the reader to enter data.
These must be used in conjunction with the form statements.

Syntax:
{{ camp_edit object="<object_name>"
             attribute="<attribute_name>"
             [html_code="<HTML_code>"]
             [size ="<field_length>"]
             [columns="<max_columns>"]
             [rows="<max_rows>"] }}

For text input fields, if the size parameter was set the input field size will be set to that value.
For text box fields, if the columns/rows parameter was set the box will have the given number
of columns/rows.

Note

       columns and rows parameters were implemented starting with version 3.2.2.


                                                                                                       201
      If the html_code parameter was set the HTML code will be inserted inside the input field.

      Example:
      {{ camp_edit object="user" attribute="name"
                   html_code="id=\"userNameInput\"" }}

      will output:
      <input type="text" name="f_user_name" size ="50" maxlength="255" id="userNameInput">




      EDIT LOGIN
      Purpose:
      Generates a text input field for entering a subscriber's login user name or password. Use
      this to allow a subscriber to login to your site. These statements should be used inside the
      login form.

      Syntax:
      {{ camp_edit object="login" attribute="<attribute>"
                   [html_code="<HTML_code>"] [size ="<field_length>"] }}

      where <attribute> being one of the following:

            uname: allows login name input
            password: allows password input

      Constraints:

      The login edit fields can be used only inside the login form.




      EDIT SEARCH
      Purpose:
      Generates a text input field so that a user can search for articles on your site. This
      statement should be used inside the search form.

      Syntax:
      {{ camp_edit object="search" attribute="<attribute>"
                   [html_code="<HTML_code>"] [size ="<field_length>"] }}

      with <attribute> being one of the following:

            keywords: allows search keywords input
            start_date: select only articles published starting on the selected date
            end_date: select only articles published up to the selected date

      Constraints:
      The search edit field can be used only inside the search form.




      EDIT COMMENT
      Purpose:
      Generates text fields so that a user can enter a comment. This statement should be used
      inside the comment form.

      Syntax:


202
       {{ camp_edit object="comment" attribute="<attribute>"
                    [html_code="<HTML_code>"]
                    [size ="<field_length>"]
                    [columns="<max_columns>"]
                    [rows="<max_rows>"] }}

       with <attribute> being one of the following:

             nickname: a place for the user to type in a nickname
             reader_email: a place for the user to type in their email address; this field is optional
             for logged in readers because the email can be read from the subscribers database
             subject: a place for the user to type in a subject line for their comment
             content: a place for the user to type in their comment.

       The attributes reader_email, subject and content are mandatory in each Edit Comment
       form.

Note

       columns and rows parameters were implemented starting with version 3.2.2. Constraints:
       The comment edit field can be used only inside the comment form.




       EDIT CAPTCHA
       Purpose:
       Generates a text field allowing the user to input the CAPTCHA code for spam control. This
       statement should be used inside the comment form.

       Syntax:
       {{ camp_edit object="captcha" attribute="code"
                    [html_code="<HTML_code>"] [size ="<field_length>"] }}




       EDIT USER
       Purpose:
       Generates a text input field for editing the selected user attribute. This statement should
       be used inside the user form.

       Syntax:
       {{ camp_edit object="search" attribute="<attribute>"
                    [html_code="<HTML_code>"]
                    [size ="<field_length>"]
                    [columns="<max_columns>"]
                    [rows="<max_rows>"] }}

       with <attribute> being one of the following:




                                                                                                         203
             name
             uname
             email
             city
             str_address
             state
             phone
             fax
             contact
             second_phone
             postal_code
             employer
             position
             how
             languages
             field1
             field2
             field3
             field5
             interests
             improvements
             text1
             text2
             text3
             password
             passwordagain

       The parameters (name, uname, email, city...) are fields describing the user's data; field1-
       field5, text1-text3 are extra fields for storing extra information of your choosing.

Note

       columns and rows parameters were implemented starting with version 3.2.2. Constraints:
       The user edit field can be used only inside the user form.




       EDIT SUBSCRIPTION
       Purpose:
       Generates an input field for editing the subscription time for a certain section. The section
       must be defined in the template environment. This statement should be used inside the
       subscription form.

       Syntax:
       {{ camp_edit object="search" attribute="time"
                    [html_code="<HTML_code>"] [size ="<field_length>"] }}

       Constraints:
       The subscription edit field can be used only inside the subscription form.




       OPTION INPUT FIELDS
       Purpose:

       Generate an option input field; these fields are used in forms to allow the reader to enter
       data. These must be used in conjunction with the form statements.

       Syntax:


204
{{ camp_select object="<object_name>"
               attribute="<attribute_name>"
               [html_code="<HTML_code>"] }}

If the html_code parameter was set the HTML code will be inserted inside the input field.

Example:
{{ camp_select object="user" attribute="country" html_code="id=\"countryId\"" }}

will output a popup list of available countries:
<select name="f_user_country" id="countryId">
...
</select>




SELECT LOGIN
Purpose:
Generates a check box; if checked the user session will be remembered for a period of two
weeks so the user will not have to login again. This statement should be used inside the
login form.

Syntax:
{{ camp_select object="login" attribute="rememberuser"
               [html_code="<HTML_code>"] }}

Constraints:
The select login field can be used only inside the login form.




SELECT SEARCH
Purpose:

Generates a check box or a popup list for selecting the search mode or the search level
respectively. This statement should be used inside the search form.

Syntax:
{{ camp_select object="search" attribute="<attribute>"
               [html_code="<HTML_code>"] }}

with <attribute> being one of the following:

      mode: if checked the search will return articles that contain all entered keywords; if
      not checked it will return articles that contain at least one keyword
      level: allows the reader to select the scope of the search: multiple publications,
      publication, issue, section.
      section: select only articles that are in the given section
      issue: select only articles that are in the given issue

Contraints:

The select search field can be used only inside the search form.




SELECT USER


                                                                                               205
      Purpose:
      Generates a dropdown list or radio-buttons for selecting values for the given fields. This
      statement should be used inside the user form.

      Syntax:
      {{ camp_select object="user" attribute="<attribute>"
                     [html_code="<HTML_code>"] }}

      with <attribute> being one of the following:

            gender
            title
            country
            age
            employertype
            pref1
            pref2
            pref3
            pref4

      The parameters (country, title, gender...) are fields describing the user information; pref1-
      pref4 are extra fields for storing extra information - the publication administrator sets
      their meaning.

      Constraints:
      The select user field can be used only inside the user form.




      SELECT SUBSCRIPTION
      Purpose:
      Special-purpose input for subscription data.

      Syntax:
      {{ camp_select object="subscription" attribute="<attribute>"
                     [html_code="<HTML_code>"] }}

      with <attribute> being one of the following:

            section: generates a checkbox for selecting the current section in subscription form;
            use together with "List of Sections" (see also "Creating reader subscriptions through
            the template language")
            allLanguages: generates a checkbox allowing the user to choose a subscription to all
            available languages
            languages: generates a multiple selection list allowing the user to select individual
            languages; this selection list is automaticaly deactivated if the user chose to
            subscribe to all available languages.


      Constraints:
      The select subscription field can be used only inside the subscription form.




      CAPTCHA IMAGELINK
      Purpose:

      "captcha_image_link" will insert the link for the CAPTCHA image. Use inside an "img" HTML
      tag as follows:
      <img src="../{{ captcha_image_link }}">

206
Syntax:
{{ captcha_image_link }




                          207
52. IMAGES
TEMPLATE BLOCK STATEMENT: {{ LIST_IMAGES }}
Parameters that can be used in {{ list_images }} statement:

      length="<integer_value>": <integer_value> specifies the list length and forces the list to
      have at mostlist_length items. If the list contains more items than list_length items the
      intervals of elements to be displayed can be switched using
      has_previous_elements/has_next_elements from the current_list object.
      columns="<integer_value>":<integer_value> specifies the list columns number and sets an
      environment variable. This is incremented as if the items would be placed in a table cell.
      The counting starts from one and the variable is incremented for every new element.
      When it reaches the maximum value it is reset to one. This is very useful in building tables
      of data. For details see current_list.
      order="<order_field> <direction>" where <direction> may be "asc" (ascending) or "desc"
      (descending) and the <order_field> can be one of:
            default: order by image identifier
            byDescription: order by the description field
            byPhotographer: order by the photographer field
            byDate: order by image date field
            byLastUpdate: order by the time the image was updated
      description="<value>": select images whose description matches exactly the given value

      photographer="<value>": select images whose photographer matches exactly the given
      value

      place="<value>": select images whose place matches exactly the given value

      caption="<value>": select images whose caption matches exactly the given value

      date="<value>": select images whose date matches exactly the given value

      type="<value>": select images whose type matches exactly the given value; valid type
      values are: png, jpeg, gif etc.

      description_like="<value>": select images whose description matches partially the given
      value

      photographer_like="<value>": select images whose photographer matches partially the
      given value

      place_like="<value>": select images whose place matches partially the given value

      caption_like="<value>": select images whose caption matches partially the given value

      start_date="<value>": select images whose date matches or is greater than the given
      value

      end_date="<value>": select images whose date matches or is smaller than the given value
      search="<value>": select images whose description, photographer, place and caption
      matches partially the given value
      local="true" | "false": select only local images if true, remote images if false

ATTRIBUTES FOR THE IMAGE OBJECT
The image template object (see http://en.flossmanuals.net/Campsite/TemplateObjects - Image)
has the following new attributes:



208
last_update: displays the time the image was updated
caption: displays the image caption field
is_local: 1 if the image was stored locally, 0 if external
type: the subtype from the mimetype field; e.g.: png, jpeg, gif etc.




                                                                       209
53. TEMPLATE SAMPLE FOR COMMENTS
The following template sample will display the comment form, using CAPTCHA. The comment
settings need to be enabled for article and article type, as explained further up in this manual.
{{ if $campsite->article->comments_enabled }}

<div id="comments">
<a name="comments">
  <h3>Comments</h3>
</a>
{{ list_article_comments }}
{{ if $campsite->current_list->at_beginning }}
<a name="commentlist">
  <h4>Previous comments</h4>
</a>
{{ /if }}
  <div class="comment" {{ if $campsite->current_list->at_end }}id="everlast"{{ /if }}>
     <p><strong>{{ $campsite->comment->subject }}</strong></p>
     <p>{{ $campsite->comment->content }}</p>
     <p><em>{{ $campsite->comment->nickname }} | <span>{{ $campsite->comment-
>submit_date|camp_date_format:"%M %e, %Y" }}</span></em></p>
  </div><!-- /.comment -->
{{ /list_article_comments }}

<a name="commentform">
     <h4>Post a comment</h4>
</a>
{{ if $campsite->submit_comment_action->rejected }}
     <div class="posterror">Your comment has not been accepted.</div>
{{ /if }}

{{ if $campsite->submit_comment_action->is_error }}
    <div class="posterror">{{ $campsite->submit_comment_action->error_message }}
        <span class="posterrorcode">{{ $campsite->submit_comment_action->error_code }}</span>
   </div>
{{ else }}
    {{ if $campsite->submit_comment_action->defined }}
        {{ if $campsite->publication->moderated_comments }}
            <div class="postinformation">Your comments has been passed on to the editors for
approval.</div>
        {{ /if }}
    {{ /if }}
{{ /if }}

{{* if $campsite->comment->defined }}
    <p><strong>{{ $campsite->comment->subject }}
        ({{ $campsite->comment->reader_email|obfuscate_email }}) -
        {{ $campsite->comment->level }}</strong></p>
    <p>{{ $campsite->comment->content }}</p>
{{ /if *}}

{{ if $campsite->user->blocked_from_comments }}
    <div class="posterror">The user you are logged in as, has been blocked from writing
comments.</div>
{{ else }}

{{ comment_form submit_button="Send comment" }}
    <div class="form-element">
      <label for="CommentSubject">Name:</label>{{ camp_edit object="comment"
attribute="nickname" }}
    </div>

    <div class="form-element">
      <label for="CommentEmail">Email (required):</label>{{ camp_edit object="comment"
attribute="reader_email" }}
    </div>

    <div class="form-element">
      <label for="CommentNickname">Subject (required):</label>{{ camp_edit object="comment"
attribute="subject" }}
    </div>

    <div class="form-element">
      <label for="CommentContent">Comment:</label>{{ camp_edit object="comment"
attribute="content" }}
    </div>
    {{ if $campsite->publication->captcha_enabled }}
    <div class="form-element clearfix">
      <label for="submitComment">SPAM-protection:</label>
      <img src="../{{ captcha_image_link }}"><br clear="all" />
      <label for="f_captcha_code">Type letters here: </label>{{ camp_edit object="captcha"

210
attribute="code" }}
    </div>
    {{ /if }}
    <div class="form-element">
      <label for="submitComment"></label>
    </div>
{{ /comment_form }}
{{ /if }}

{{ unset_comment }}
{{ if $campsite->comment->defined }}
    <div class="posterror">Error: Your recent comment is still being processed.<div>
{{ /if }}

</div><!-- /#comments -->

{{ /if }}




                                                                                       211
54. SOMEBODY SHOULD SET THE TITLE
FOR THIS CHAPTER!
Here is a sample template for Search:

Anywhere you want the search form to appear, leading to the search result page, include this:
 {{ search_form template="path/to/search.tpl" submit_button="Search"
html_code="class='FORM_suche'" button_html_code=" value='Suche' class='SUBMIT_black'" }}
    {{ camp_edit object="search" attribute="keywords" html_code="id=\"keywords\"" }}
{{ /search_form }}

The "path/to/search.tpl" refers to the relative path of the below template. If it lives in the top
folder of your templates, just use "search.tpl" if you have subfolders (e.g. searchfiles), use
"searchfiles/search.tpl". Attention: no leading slash!
<h2>Search</h2>
</div>
{{ search_form template="path/to/search.tpl" submit_button="Search"
html_code="class='FORM_suchseite'" button_html_code="class='SUBMIT_search'" }}
  <ul class="searchform">
    <li class="searchform">
    <label for="keywords">Search words:</label>
    {{ camp_edit object="search" attribute="keywords" html_code="id=\"keywords\"" }}
    </li>
    <li class="option">
    {{ camp_select object="search" attribute="mode" html_code="id=\"match_all\"" }}
    <label for="match_all">Nur Artikel mit allen W&ouml;rtern anzeigen</label>
    </li>
    <li class="option checkbox"><input type="radio" name="f_search_scope" value="content"
id="content" checked>
    <label for="content">Entire article</label></li>
    <li class="option checkbox"><input type="radio" name="f_search_scope" value="title"
id="title">
    <label for="title">Only in title</label></li>
    <li class="option"><input type="radio" name="f_search_scope" value="author" id="author">
    <label for="author">Author</li>
  </ul>
 {{ camp_select object="search" attribute="level" }}
  <p>Search in the
    <input type="radio" name="f_search_scope" value="content" id="content" checked>
    <label for="content"><strong>whole content</strong></label>,
    <input type="radio" name="f_search_scope" value="title" id="title">
    <label for="title"><strong>title</strong></label> or
    <input type="radio" name="f_search_scope" value="author" id="author">
    <label for="author"><strong>author</strong></label>
  </p>
  <p>Issue: {{ camp_select object="search" attribute="issue" }}</p>
  <p>Section: {{ camp_select object="search" attribute="section" }}</p>
  <p>Start date: {{ camp_edit object="search" attribute="start_date" }}</p>
  <p>End date: {{ camp_edit object="search" attribute="end_date" }}</p>
  <p>Topic:
    <select name="f_search_topic">
       {{ unset_topic }}
       {{ list_subtopics }}
         <option value="{{ $campsite->topic->identifier }}>">
           {{ $campsite->topic->name }}
         </option>
       {{ /list_subtopics }}
    </select>
  </p>
{{ /search_form }}
<div class="searchresults">
<h2>Search results</h2>
    {{ list_search_results length="24" order="byDate desc" }}
    {{ if $campsite->current_list->at_beginning }}
             <ul class="filmsList">
    {{ /if }}
                 <li>
                      <h5><a href="{{ url options="article" }}">{{ $campsite->article->name
}}</a></h5>
                      <div><a href="{{ url options="article" }}">{{ $campsite->article-
>untertitel }}</a></div>
                      <span>(Issue: {{ $campsite->issue->name }}&nbsp;|&nbsp;Section: {{
$campsite->section->name }}
                 </li>
        {{ if $campsite->current_list->at_end }}
    </ul>

212
          <ul class="pagination">
                <li>{{ $campsite->current_list->count }} Artikel</li>
{{ set_current_issue }}
{{ set_default_section }}
{{ unset_article }}
        {{ if $campsite->current_list->has_previous_elements }}
          <li class="previous"><a href="{{ uri options="previous_items template
path/to/search.tpl" }}">&laquo;</a></li>
        {{ /if }}
{{ set_current_issue }}
{{ set_default_section }}
{{ unset_article }}
        {{ if $campsite->current_list->has_next_elements }}
          <li class="next"><a href="{{ uri options="next_items template path/to/search.tpl"
}}">&raquo;</a></li>
        {{ /if }}
          </ul>
        {{ /if }}
     {{ /list_search_results }}
{{ if $campsite->prev_list_empty }}
                {{ if $campsite->search_articles_action->defined }}
                  <div class="warning">No matches found.</div>
              {{ /if }}
    {{ /if }}




                                                                                              213
55. HOW TO DO ARTICLE PAGINATION?
This example will show you how to split an article on multiple pages. We assume the article type
is fastnews and has three fields: date (date field type), intro (body field type) and Full_text (body
field type). You'll find this example implemented in the Campsite demo package here. The field
Full_text is the one that contains the pagination (subheads).

Here is the code:

   1. {{ list_subtitles field_name="Full_text" }}
  2.      <p>

  3.      {{ if $campsite->article->full_text->subtitle_is_current }}

  4.        <b>{{ $campsite->current_list->index }}. {{ $campsite->subtitle->name }}</b>

  5.      {{ else }}

  6.        <a href="{{ uri }}">{{ $campsite->current_list->index }}. {{ $campsite->subtitle-
        >name }}</a>

   7.     {{ /if }}

  8.      </p>

  9. {{ /list_subtitles }}
 10. <p>View subtitle:

  11. {{ if $campsite->article->full_text->has_previous_subtitles }}
  12.     <a href="{{ uri options="previous_subtitle full_text" }}">Previous</a>

  13. {{ else }}
  14.     Previous

  15. {{ /if }}
 16. |
  17. {{ if $campsite->article->full_text->has_next_subtitles }}
 18.      <a href="{{ uri options="next_subtitle full_text" }}">Next</a>

 19. {{ else }}
 20.      Next

  21. {{ /if }}
 22. |

 23. {{ if $campsite->article->full_text->has_next_subtitles || $campsite->article-
        >full_text->has_previous_subtitles }}

 24.      <a href="{{ uri options="all_subtitles full_text" }}">All</a>

 25. {{ else }}
 26.      All

 27. {{ /if }}
 28. </p>

 29. <p>{{ $campsite->article->full_text }}</p>

Lines 1-9 display the list of article subtitles (see "List of Subtitles" in "Template Language
Reference" chapter):
214
      display the subtitle name as simple text for the current subtitle - the one that's being
      viewed - (if $campsite->article->full_text->subtitle_is_current)
      display the subtitle name as link for other subtitles (else branch)

Lines 11-27 create links to navigate to the previous or next subtitle (uri options="previous_subtitle
full_text", uri options="previous_subtitle full_text"), or to display all subtitles (uri
options="all_subtitles full_text").

Line 29 displays the actual article content, in this case the current subtitle ($campsite->article-
>full_text).

The example given above will make your page look something like this:




Note: CSS styles have been removed from the example to make it easier to read, so if you use
the code above it will not look exactly as shown; the colors will not be there, and the spacing will
be a bit different.

Another way would be to only show the numbers and not display anything if there is no
pagination in the field, i.e. it is a normal article. Note: the count of subheads (sub titles) will be
one if there is no subheads in the article field.
{{ list_subtitles field_name="Body" }}
{{ if $campsite->current_list->count > 1 }}
    {{ if $campsite->current_list->at_beginning }}
    <div      <ul>
         {{ if $campsite->article->body->has_previous_subtitles }}
         <li><a href="{{ uri options="previous_subtitle body" }}">&laquo;</a></li>
         {{ else }}
         {{ /if }}
    {{ /if }}
    {{ if $campsite->article->body->subtitle_is_current }}
         <li><a     {{ else }}
         <li><a href="{{ uri }}">{{ $campsite->current_list->index }}<!--{{ $campsite-
>subtitle->name }}--></a></li>
    {{ /if }}
    {{ if $campsite->current_list->at_end }}
         {{ if $campsite->article->body->has_next_subtitles }}
         <li><a href="{{ uri options="next_subtitle body" }}">&raquo;</a></li>
         {{ else }}
         {{ /if }}
    </ul>
    </div>
    {{ /if }}
{{ /if }}
{{ /list_subtitles }}

There might be some fields in the article that you only want to display at the beginning of the
article. On the following pages of the pagination you don't want them to show. This is a way to
do this:
{{ * print lead only if article pagination is on page one *}}
{{ list_subtitles field_name="Body" }}


                                                                                                         215
    {{ if $campsite->current_list->at_beginning }}
        {{ if $campsite->article->body->has_previous_subtitles }}
        {{ else }}
        <span         {{ /if }}
    {{ /if }}
{{ /list_subtitles }}

As you can see, this is making use of the fact that even without actual pagination (subheads in
the text, set with the editor), the article has one subhead in the list: itself.




216
56. MISCELLANEOUS
In this chapter:

       Displaying the URL
       Local
       Logout




DISPLAYING THE URL
Purpose:

"uripath" prints only the path part of the URI, the part before the parameters list. If "/en/1/2/3?
param1=text" was the full URI, the URI path is "/en/1/2/3".

"urlparameters" prints the runtime environment parameters in URL format.

"uri" prints the complete link URI and it is equivalent to:
{{ uripath }}?{{ urlparameters }}

"url" prints the complete URL in the form: http://[site_alias][uri]. It is equivalent to:
http://{{ $campsite->publication->site }}{{ uri }}




Note

       All four statements work for both template path and short URL types. Depending on the
       URL type the statement displays the proper link.

       Note: For publications with short URL type the only way to create links is to use these
       three statements: either url, uri, uripath or urlparameters. It is not possible to build the URI
       manually.

       Syntax:
       {{   url [options="<options_list>"] }}
       {{   uri [options="<options_list>"] }}
       {{   uripath [options="<options_list>"] }}
       {{   urlparameters [options="<options_list>"] }}

       where:

       <options_list>= [<option>] <list_of_options>
                       | <option>
       <option>=              fromstart




                                                                                                          217
                         | reset_issue_list
                         | reset_section_list
                         | reset_article_list
                         | reset_searchresult_list
                         | reset_subtitle_list
                         | image [<image_number> [<image_options>]]
                         | root_level
                         | language
                         | publication
                         | issue
                         | section
                         | article
                         | template <template_name>
                         | articleAttachment
                         | articleComment
                         | audioAttachment
                         | previous_subtitle <field_name>
                         | next_subtitle <field_name>
                         | all_subtitles <field_name>
                         | previous_items
                         | next_items
      <image_number> is an <integer_value> representing a valid number of article image

      <template_name> is a <string value> representing the full path of a valid template

           fromstart: prints the url corresponding to the received request, before any changes
           were made to the template runtime environment (useful when building site maps)
           reset_issue_list: reset list counters for the issues list
           reset_section_list: reset list counters for the sections list
           reset_article_list: reset list counters for the articles list
           reset_searchresult_list: reset list counters for the search results list
           reset_subtitle_list: reset list counters for the subtitles list
           image: print image parameters in order to show an image in template; if you use this
           statement inside the "List of Article Images" statement the image number value is
           not mandatory. The image options are different depending on the Campsite version:
                  For versions 3.0-3.3:

            <image_options>=<image_ratio>.

            The "image_ratio" parameter is an integer between 1 and 100. The image will be
            scaled from 1% of it's size to 100% based on the image ratio parameter.
                   For versions 3.4 and newer:

            <image_options>=<image_ratio>|width <width>|height <height>.

            The "image_ratio" parameter is the same as above. You can specify image to be
            resized to the given width or height.

            E.g.: {{ uri options="image 1 width 100 height 100 }}




218
        root_level: this link will have all parameters reset: language, publication, issue,
        section, article, subtitle, lists indexes etc.
        language: this link will have all parameters above language reset: publication, issue,
        section, article, subtitle, lists indexes etc.; language parameter remains unchanged
        publication: this link will have all parameters above publication reset: issue, section,
        article, subtitle, lists indexes etc.; language and publication parameters remain
        unchanged
        issue: this link will have all parameters above issue reset: section, article, subtitle,
        lists indexes etc.; language, publication and issue parameters remain unchanged
        section: this link will have all parameters above section reset: article, subtitle, lists
        indexes etc.; language, publication, issue and section parameters remain unchanged
        article: this link will have all parameters above article reset: article, subtitle, lists
        indexes etc.; language, publication, issue, section and article parameters remain
        unchanged
        template <template_name>: this link will set the template in the link to
        <template_name>
        articleAttachment: displays the link for the current article attached document
        articleComment: inserts the article comment identifier in the parameters list; if no
        article comment was defined in the template environment no parameter is inserted.
        This attribute is needed if you want to pass on the current comment id to another
        page for display purposes.
        audioAttachment: displays the link for the current audio file attached to the article
        previous_subtitle <field_name>: add a parameter to the URI to select the previous
        subtitle of the given <field_name> for display
        next_subtitle <field_name>: add a parameter to the URI to select the next subtitle of
        the given <field_name> for display
        all_subtitles <field_name>: add a parameter to the URI to select all subtitles of the
        given <field_name> for display
        previous_items: add a parameter to the URI to select the previous interval of the
        current list items for display
        next_items: add a parameter to the URI to select the next interval of the current list
        items for display

Constraints:

None.




LOCAL
Purpose:

Creates a temporary environment; when leaving the local block the previous template
environment (before entering local) is restored.

Syntax:

{{ local }}
<list_of_instructions>
{{ /local }}

The list of instructions may contain any instruction allowed in the current context. If it is
used inside a list it must respect the constraints of the list.

Constraints:

None.




LOGOUT

                                                                                                    219
      There is no template keyword to logout a subscriber. Instead, just put these two lines in
      your logout.tpl file:

      <META HTTP-EQUIV="Set-Cookie" CONTENT="LoginUserId=; path=/">
      <META HTTP-EQUIV="Set-Cookie" CONTENT="LoginUserKey=; path=/">




220
57. CAMPSITE MODIFIERS
In this chapter:

      Truncating UTF8 strings
      Date Formatting
      File Size Formatting
      Email Obfuscation

TRUNCATING UTF8 STRINGS
The "truncate_utf8" modifier behaves exactly like the Smarty truncate modifier except that it
works properly on UTF8 strings. See more details on truncate here:

http://www.smarty.net/manual/en/language.modifier.truncate.php

DATE FORMATTING
The "camp_date_format" modifier formats a date string as specified:
{{ <string>|camp_date_format:"<date_attribute>" }}
{{ <string>|camp_date_format:"<date_format>" }}

where:
<date_attribute> may be one of the following:

      year: year (four digits)
      mon: month as a number (1..12)
      mday: day of the month as a number (1..31)
      yday: day of the year (1..366)
      wday: day of the week as a number (0=Sunday..6=Saturday)
      hour: hour (0..23)
      min: minute (two digits)
      sec: seconds (two digits)
      mon_name: name of the month
      wday_name: day of the week

<date_format> may contain any printable character; escape " (double quotes) in the date
formatting with \ (backslash). E.g.: "%M %e, %Y, \"%W\"" will display the the date like this: July 5,
2008, "Saturday".

The following groups of characters have special meaning:




                                                                                                        221
      %M - month name
      %W - weekday name
      %Y - year (4 digits)
      %y - year (2 digits)
      %m - month (01..12)
      %c - month (1..12)
      %w - day of the week (0=Sunday..6=Saturday)
      %d - day of the month (00..31)
      %e - day of the month (0..31)
      %j - day of the year (001..366)
      %D - day of the month with English suffix (1st, 2nd, 3rd etc.)
      %H - hour in format 00..23
      %h - hour in format 01..12
      %l - hour in format 1..12
      %i - minutes in format 00..59
      %S - seconds in format 00..59
      %s - is an alias of %S
      %p - AM or PM

Constraints:
None




FILE SIZE FORMATTING
The "camp_filesize_format" modifier formats an integer in Byte specific multiples:
{{ <integer>|camp_filesize_format:"<filesize_format>" }}

<filesize_format> may take one of the following values:

      TB: for displaying the size in terabytes
      GB: for displaying the size in gigabytes
      MB: for displaying the size in megabytes
      KB: for displaying the size in kilobytes
      B: for displaying the size in bytes




EMAIL OBFUSCATION
The "obfuscate_email" modifier obfuscates a string; the email string is obfuscated not to allow
spambot web crawlers to find it.
{{ <email_string>|obfuscate_email }}




222
58. CREATING AN RSS FEED FOR YOUR
SITE
  Step 1) Create your RSS feed.
Create a template named "rss.tpl" and copy and paste the template written below. You will have
to adjust the template tags to fit your site. For example, you should change the channel
information such as the title and link, and the tags inside the "<description>" element ("{{
$campsite->article->intro }} {{ $campsite->article->full_text }}").

The PHP code at the beginning and end of the sample below is so that the HTTP header is set to
"text/xml" instead of "text/html".

Step 2) Create the link to your RSS feed.
You can do this by using the "URI" keyword:
{{   local }}
{{   unset_issue }}
{{   unset_section }}
<a   href="{{ url options="template rss.tpl" }}">RSS Feed</a>
{{   /local }}

If your template is not in the root directory but in a sub folder (in this case the folder named
"feeds") you have to specify the URL options as a relative link, e.g.:
{{   local }}
{{   unset_issue }}
{{   unset_section }}
<a   href="{{ url options="template feeds/rss.tpl" }}">RSS Feed</a>
{{   /local }}

The following template contains the necessary commands for a valid RSS feed. However, you can
alter the list command any way you like to make more than one RSS feed. The following
example lists the latest 20 items listed on the front page.

rss.tpl template:
{{ php }}
ob_start();⁞
{{ /php }}
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://purl.org/rss/1.0/"
xmlns:dc="http://purl.org/dc/elements/1.1/">

     <channel rdf:about="http://www.sourcefabric.org">
         <title>Sourcefabric News</title>
         <link>http://www.sourcefabric.org</link>
         <description>Free Software for a Free Press</description>
         <dc:language>en-us</dc:language>
         <items>
           <rdf:Seq>
             {{ local }}
             {{ set_language name="English" }}
             {{ set_current_issue }}
             {{ unset_section }}
             {{ list_articles length="20" constraints="OnFrontPage is on" order="bydate desc"
}}
             <rdf:li rdf:resource="{{ url options="article" }}"/>
             {{ /list_articles }}
             {{ /local }}
           </rdf:Seq>
         </items>
     </channel>

   {{ local }}
   {{ set_language name="English" }}
   {{ set_current_issue }}
   {{ unset_section }}
   {{ list_articles length="20" constraints="OnFrontPage is on" order="bydate desc" }}
   <item rdf:about="{{ url options="article" }}">
       <title>{{ $campsite->article->name }}</title>
       <link>{{ url options="article" }}</link>
       <description><![CDATA[{{ $campsite->article->intro }} {{ $campsite->article->full_text
}}]]></description>

                                                                                                   223
       <dc:date>{{ $campsite->article->publish_date|camp_date_format:"%Y-%m-
%dT%H:%i:%S+01:00" }}</dc:date>
   </item>
   {{ /list_articles }}
   {{ /local }}
</rdf:RDF>

{{ php }}
header("Content-type: text/xml");
$content = ob_get_clean();
echo '<?xml version="1.0" encoding="utf-8"?>';
echo $content;
{{ /php }}

Tips & tricks

If you use XSL, the CDATA sections do not work with Firefox.
If you dont want to use CDATA sections in your RSS, you can strip the HTML from your article
this way:
$allowedTags="<rdf:RDF><rdf:Seq><rdf:li><channel><title><link><description><dc:language><dc:date><item><items>";

$content = strip_tags($content, $allowedTags);


Another way to create a link to your RSS feed
Assign the template to a section: create a new section (doesnt matter where), and call it "rss".
Configure the section so that its templates are "rss.tpl", and give the section the URL name of
"rss". The URL for this section will be the URL to your RSS feed.




224
59. CHANGING TEMPLATES
It is possible to keep the look for the old issues and at the same time to have a different look
for newer issues. There are a few steps you have to take:

   1. Create the new templates in a separate directory

  2. Go to the Issue Configure screen and select the new issue, section and article templates
     for the issue (e.g. /new/issue.tpl, /new/section.tpl and /new/article.tpl).

  3. Within your templates, make sure to create links to issue, section and article templates by
     using "uri" (see "Displaying the URL" in "Template Language Reference" chapter) instead of
     manually writing the link content. In other words, do this:
      <a href="{{ uri }}">link</a>




                                                                                                   225
60. THE TEMPLATE CACHE
To exclude dynamic stuff I've added {{ dynamic }} block. Any code inside dynamic block will be
excluded form cache and rendered on each request.

It was first version of template cache handler. It had been working fine but without so many
dynamic excluded parts. For given example the cache accelerates just about 2x times than
uncached.

That's not fine for me. I'd like more    and I've implemented the second template cache handler
version with multirendering support. It allows to render included sub-templates by separate
rendering process with personal cache settings. The next version contains new function {{ render
}}

Full specification:
{{ render file="template_name" [issue=off|issueid] [section=off|sectionid] [article=off|articleid]
[params=paremeters] [cache=secs] }}

where

file: template filename
issue: to cache for any issue or for an issue with issueid
section: to cache for any section or for a section with sectionid
article: to cache for any article or for a article with articleid
params: specify additional parameters
cache: overwrite the cache settings in template manager

Let's see on example.
Here is the layout of standard section page.




226
We need to exclude from caching some dynamic stuff:
1. Most popular list
2. Most commented list
3. External informers
4. Template contains article list pagination.

Let's define some parameters for dynamic stuff:
Most popular article list is defined for issue only.
Most commented article list is defined for all articles in any issue
Informers should be included on each request
Pagination generates links like http://site/en/pub/issue/section/?page=n

Most popular and commented lists should be cached for 600 sec
The main template section.tpl should be cached for 30 days

The cache lifetime for main template can be defined in Template manager:




                                                                           227
                                                                                             Most
popular list:
{{ render file="most_popular.tpl" section=off cache=600 }}

Most commented list:
{{ render file="most_commented.tpl" issue=off section=off cache=600 }}

Informers:
{{ dynamic }}
{{ php }} inclide 'informer1.php'; {{ php }}
{{ /dynamic }}

Section article list with pagination:
{{ render file="section_list.tpl" params=$campsite->url->get_parameter(page) }}

On article changing or issue publishing/unpublishing the cache manager cleans outdated cached
template. Cleaning algorithm based on campsite specific parameters: language, publication, issue,
section, article, template, additional params.



PLUGINS
61. Using plugins with your templates
62. Polls Plugin
63. Online Interview Plugin




228
61. USING PLUGINS WITH YOUR
TEMPLATES
Simply installing a plugin is not all you must do. You must still make changes in your site's
templates to take advantage of the new features.

Every plugin will be somewhat unique in the features and functionality it provides. Some plugins
may be quite complex, and others will be relatively simple. But the vast majority of plugins work
with templates in some form or another. Most add new properties that can be used with the
templates.

When a new plugin is released, the changes the plugin makes to the template language will also
be made available in this section. As an example, we will use the polls plugin as an example of
how this all works.




                                                                                                    229
62. POLLS PLUGIN
In this chapter:

        Frontend/Template Engine

Poll plugin
Plugin Author: Sebastian Goebel
Date: September, 2008

Description: The poll plugin allows users to vote on a topic and then to display the results. From
the administrative interface, authorized users can create and delete new polls, change the
questions , and add and edit new possible answers.

The polls plugin modifies the templating language in four parts:

        poll (17 properties)
        poll answer (8 properties)
        list of polls
        list of poll answers

Each of these is discussed in the next few pages.

The general poll object properties are used in your templates for managing such things such as
the language the poll will use, the overall number of votes, and the title of the poll.

FRONTEND/TEMPLATE ENGINE
In this article:

        Examples of templates using Polls plugin objects
        Poll object properties
        Poll Answer - object properties
        List of Polls - object properties
        List of Poll Answers - object properties

Examples of templates using Polls plugin objects

It's usually best to see an example of what it is we're talking about, so here is a sample
template that makes use of the polls plugin. This template is called section-polls.tpl. Feel free to
copy this and use it as a base for your own polls implementation:


{{ if $included }}
<style>

    .poll_bar {
       border:1px solid #000;

       background-color: #dfdfdf;

       height: 20px;
       vertical-align: center;

       float: left;

}
</style>

<script>

function play(url)
{


230
    var tag;


    if (navigator.appName=="Microsoft Internet Explorer") {

           tag = '<bgsound src="../'+url+'" loop="false">';
    } else {

        tag = '<embed src="../'+url+'" hidden="true" border="0" width="0" height="0"
autostart="true" loop="false">';
    }

    $('player_div').innerHTML = tag;
}

function stop()

{
    $('player_div').innerHTML = '';

}

</script>
<div {{ /if }}

{{ poll_form template='poll-form.tpl' submit_button=false ajax=true }}




    {{ $campsite->poll->title }}<br>

    {{*
    Question: {{ $campsite->poll->question }}<br>

    Voting Begin: {{ $campsite->poll->date_begin|date_format }}<br>

    Voting End: {{ $campsite->poll->date_end|date_format }}<br>
    *}}

    Votes: {{ $campsite->poll->votes }}<br>


    <div

    {{ list_poll_answers order="byvalue desc" }}


            {{ pollanswer_ajax }}


                    <div                  <div                   {{ $campsite->pollanswer->answer }}

                           ({{ $campsite->pollanswer->percentage|string_format:"%d" }})%

                   </div>


           {{ /pollanswer_ajax }}


           <div              {{ list_pollanswer_attachments }}

                  {{ if $campsite->attachment->mime_type|substr:0:5 == 'audio' }}
                <a href="javascript: void(0);" onClick="play('{{ uri
options="articleattachment" }}')">

                             <img src="..//css/is_shown.png" border="0">
                      </a>

                      <a href="javascript: void(0);" onClick="stop()">
                             <img src="..//css/unlink.png" border="0">

                      </a>

                  {{ /if }}



                                                                                                       231
          {{ /list_pollanswer_attachments }}



          <div            Give a note:
          {{ section name=foo start=1 loop=6 }}

            {{ pollanswer_ajax value=$smarty.section.foo.index }}{{ $smarty.section.foo.index
}}{{ /pollanswer_ajax }}

          {{ /section }}

          <br>


          {{ $campsite->pollanswer->votes }} votes |

          &#216;{{ $campsite->pollanswer->average_value|string_format:"%.1f" }} |
          sum: {{ $campsite->pollanswer->value }}



          <div       {{ /list_poll_answers }}


{{ /poll_form }}


{{ if $included }}

      </div>
      <div id="player_div"></div>

{{ /if }}

The next example of a template is the section page with the poll included. This template is called
poll-form.tpl:

{{ include file="html_header.tpl" }}

<table <tr>
  <td valign="top">

      <div id="breadcrumb">

      {{ breadcrumb }}
      </div>

      {{** main content area **}}

      <table       <tr>
        <td>

      {{ if $campsite->poll->defined }}


          <h3>Poll Details</h3>


          {{ include file='poll-form.tpl' included=true}}



          <br>
          <a href="{{ uri options="template section-polls.tpl" }}">All Polls</a>



      {{ else }}


          <p>


          <tr>

                 <th align="left">Name</th>


232
                 <th>Voting Begin</th>
                 <th>Voting End</th>

                 <th>Current</th>

                 <th>Allowed/Votes Cast</th>
                 <th>Votes</th>

          </tr>
          <tr><td colspan="6"><hr></td></tr>

          {{ local }}


          {{ list_polls name="polls_list" length="10" order='bylastmodified ASC' }}

             <tr align="center">

                 <td align="left">
                <a href="{{ uri options="template section-polls.tpl" }}&amp;f_poll_nr={{
$campsite->poll->number }}&amp;f_poll_language_id={{ $campsite->poll->language_id }}">
                            {{ $campsite->poll->name }}

                     </a>

                 </td>
                 <td>{{ $campsite->poll->date_begin|date_format }}</td>

                 <td>{{ $campsite->poll->date_end|date_format }}</td>

                 <td>{{ if $campsite->poll->is_current }} Y {{ else }} N {{ /if }}</td>
                 <td>{{ $campsite->poll->votes_per_user }}/{{ $campsite->poll->user_vote_count
}}</td>
                 <td>{{ $campsite->poll->votes }}

            </tr>


          {{ if     $campsite->current_list->at_end }}

          <tr><td colspan="6"><hr></td></tr>

          <tr>
                 <td>{{ $campsite->current_list->count }} Items</td>

                 <td colspan="5">
                     {{ if $campsite->current_list->has_previous }}

                    <a href="{{ uripath }}?p_polls_list_start={{ $campsite->current_list-
>previous }}">previous</a>
                     {{ else }}

                            previous

                     {{ /if }}
                     |

                     {{ if $campsite->current_list->has_next }}
                            <a href="{{ uripath }}?p_polls_list_start={{ $campsite->current_list-
>next }}">next</a>

                     {{ else }}
                            next

                     {{ /if }}
                 </td>

          </tr>

          {{ /if }}


          {{ /list_polls }}

          {{ /local }}



                                                                                                    233
      {{ /if }}




        </td>

      </tr>
      </table>

      {{** end main content area **}}
  </td>

  <td valign="top">

      {{ include file="html_rightbar.tpl" }}
  </td>

</tr>

</table>
{{ include file="html_footer.tpl" }}


Poll object properties

Poll object properties

The poll object has following properties:

        number: the internal number of the poll
        language_id: the language identifier
        defined: indicates if the poll (defined by number and language) exists in database
        title: the title for the poll
        name: synonym for title
        question: the question (or theme) of the poll
        date_begin: date when voting starts
        date_end: date when voting ends
        answers: number of different answers
        is_current: is the poll within the voting period
        votes_per_user: how often can a single user vote (mostly 1)
        user_vote_count: how often the current user voted already (stored in session and cookie,
        so it can be lost)
        votes: how many votes were made
        is_votable: can the poll voted by this user. must be within voting period, and votes made
        by current user do not excite number of allowed votes
        votes_overall: how many votes for all translations of this poll were made
        percentage_overall: percentage votes of this poll in relation to all translations of this poll
        last_modified: timestamp of last modification throught the admin

Poll Answer - object properties

The poll answer object has following properties:

        poll_nr: number of the correspondending poll
        language_id: language identifier for this answer and correspondending poll
        number: the number of this answer
        answer: the answer text to vote for
        votes: how many votes were given for this answer
        percentage: the percentage of votes for this answer, in relation to all answers of this poll
        percentage_overall: the percentage of votes for this answer, in relation to all answers of all
        translations of this poll
        last_modified: last modification throught the admin

List of Polls - object properties


234
Purpose:

Select the list of polls according to the given constraints and current environmental variables.
The code between "{{ list_polls }}" statement and "{{ /list_polls }}" is repeated for every poll in
the list.

Syntax:
{{ list_polls [length="<integer_value>"] [columns="<integer_value>"]
        [constraints="<list_of_poll_constraints>"]
        [item="<item_constraint>"]
        [order="<order_condition>"]>

}}

<list_of_instructions>
{{ /list_polls }}

where:

      length="<integer_value>": <integer_value> specifies list_length and forces the list to have
      at most list_length items. If the list contains more items than list_length items the ones not
      fitting in can be listed using If NextItems/PreviousItems statements.

      columns="<integer_value>": <integer_value> specifies columns_number and sets an
      environment variable. This is incremented as if the items would be placed in a table cell.
      The counting starts from one and the variable is incremented for every new element.
      When it reaches the maximum value it is reset to one. This is very useful in building tables
      of data. For details see If List.
      item="<item_constraint>": <item_constraint> sprecifies the item where the polls have to
      been assigned to. This can be publication, issue, section or article. The assignment can be
      done in admin interface on the proper item edit/properties page. The

<list_of_poll_constraints>= [<poll_constraint>] <list_of_poll_constraints>
                             | <poll_constraint>
<poll_constraint>= number <integer_operator> <integer_value>
                    | language_id <integer_operator> <integer_value>
                    | parent_poll_nr <integer_operator> <integer_value>
                    | is_extended <switch_operator> <switch_value>
                    | name <string_operator> <string_value>
                    | votes <integer_operator> <integer_value>
                    | votes_overall <integer_operator> <integer_value>
                    | is_current <boolean_operator> <boolean_value>
                    | <date_constraint>

<date_constraint>=
 begin <date_operator> <date_value>
 | begin_year <integer_operator> <integer_value>
 | begin_month <integer_operator> <integer_value>
 | begin_mday <integer_operator> <integer_value>
 | end <date_operator> <date_value>
 | end_year <integer_operator> <integer_value>
 | end_month <integer_operator> <integer_value>
 | end_wday <integer_operator> <integer_value>

<item_constraint>= publication
                   | issue
                   | section
                   | article

<order_condition>= bynumber desc|asc
                   | bylanguage
                   | bytitle
                   | byname

                                                                                                       235
                   | byquestion
                   | bybegin
                   | byend
                   | byanswers
                   | byvotes
                   | byvotes_overall
                   | bypercentage_overall
                   | bylastmodified




  LIST OF POLL ANSWERS - OBJECT PROPERTIES
  Purpose: Select the list of poll answers according to the current poll. The code between
  "{{ list_pollanswers }}" statement and "{{ /list_pollanswers }}" is repeated for every
  interview in the list.

  Syntax:
  {{ list_pollanswers [length="<integer_value>"] [columns="<integer_value>"]
          [constraints="<list_of_interview_constraints>"]
          [order="<order_condition>"]>

  }}

  <list_of_instructions>
  {{ /list_pollanswers }}

  where:

       length="<integer_value>": <integer_value> specifies list_length and forces the list to
       have at most list_length items. If the list contains more items than list_length items
       the ones not fitting in can be listed using If NextItems/PreviousItems statements.

       columns="<integer_value>": <integer_value> specifies columns_number and sets an
       environment variable. This is incremented as if the items would be placed in a table
       cell. The counting starts from one and the variable is incremented for every new
       element. When it reaches the maximum value it is reset to one. This is very useful in
       building tables of data. For details see If List.

  <list_of_instructions> may contain any statement except: "set_interview".

  <list_of_interview_constraints>= [<interview_constraint>] <list_of_interview_constraints>
                                    | <iinterview_constraint>
  <interview_constraint>= id <integer_operator> <integer_value>
                           | name <string_operator> <string_value>
                           | language_id <integer_operator> <integer_value>
                           | moderator_user_id <integer_operator> <integer_value>
                           | guest_user_id <integer_operator> <integer_value>
                           | status <string_operator> <string_value>
                           | <date_constraint>
  <date_constraint>=             interview_begin <date_operator> <date_value>
                                 | interview_begin_year <integer_operator> <integer_value>
                                 | interview_begin_month <integer_operator>
                                 <integer_value>
                                 | interview_begin_wday <integer_operator> <integer_value>
                                 | interview_end <date_operator> <date_value>
                                 | interview_end_year <integer_operator> <integer_value>
                                 | interview_end_month <integer_operator> <integer_value>
                                 | interview_end_wday <integer_operator> <integer_value>

236
                              | questions_begin <date_operator> <date_value>
                              | questions_begin_year <integer_operator> <integer_value>
                              | questions_begin_month <integer_operator>
                              <integer_value>
                              | questions_begin_wday <integer_operator>
                              <integer_value>
                              | questions_end <date_operator> <date_value>
                              | questions_end_year <integer_operator> <integer_value>
                              | questions_end_month <integer_operator> <integer_value>
                              | questions_end_wday <integer_operator> <integer_value>


<order_condition>= byIdentifier desc|asc
                   | byName desc|asc
                   | byTitle desc|asc
                   | byQuestions_begin desc|asc
                   | byQuestions_end desc|asc
                   | byInterview_begin desc|asc
                   | byInterview_end desc|asc
                   | byModerator desc|asc
                   | byGuest desc|asc
                   | byStatus desc|asc
                   | byOrder desc|asc




                                                                                          237
63. ONLINE INTERVIEW PLUGIN
In this chapter:

      Frontend/Template Engine
      Admin Interface



Description

The Interview-Module allows to plan, manage and publish an interview on your publication
website. The Interview can be announced and readers are invited to ask questions, which will be
answered by the interview partner. In practice, this module operates a little bit like a forum but
with one main protagonist who will reply to all questions posted. There is the possibility to
schedule a time frame for the interview, but this is NOT a chat module. It is closer to a FAQ-
tool.

Interview

An Interview is stored in the database in two tables. One keeps settings for the interview, and
the other records multiple pairs of questions and answers ("interview items") for each interview.

4 User Roles:

      Reader of your page can visit an interview. If subscribed to the page, he can submit own
      questions to an interview
      Guest is the person who answers the questions
      Moderator have to moderator incoming questions
      Admin can create new interviews and edit any property


4 Status:

      Draft: A new interview, which just occurs on the admin screen
      Pending: The interview is waiting for questions and answers
      Published: The interview is done, and the results are published on the website
      Rejected: Used to hide it from the website

Interview Items

Each pair of question and it answer is called interview item. They have similar 4 status stages:

      Draft: A new question send by an reader, and waiting for moderation (accept/reject)
      Pending: The question was accepted, and waits to be answered by the guest
      Published: The answer is given, and the item is ready to be shown on the website.
      Rejected: If moderator reject item, it will not appear on the guest screen nor on the
      website

The normal workflow would be:

  1. Admin created interview, status draft
  2. Admin set interview status to pending. If the questions timeframe is current, the interview
     appears on website and waits for questions. Existing questions can be listed on the
     website, so other reader can see what already was asked. Answers will not shown yet.
  3. The moderator accept or reject new questions. Spam etc. can be deleted instantly.
  4. Within the interview timeframe, the guest answers the questions. Answered questions
     automatically get status published.
  5. The admin set the interview status to published, so the questions and answers are shown
     on the website.

238
FRONTEND/TEMPLATE ENGINE
In this article:

      Interview
      Interview Item
      List of Interviews
      List of Interview Items

As a template designer, you need to understand which variables can be displayed and how the
relate to each other. An interview is composed of two type of objects:

      Interview: this keeps data about the interview itself, such as title, description, image,
      moderator, guest, question and answer timeframes
      Interview item: an item is a pair of one question and one answer. Each interview can
      contain multiple interview items



Interview

The interview object has the following properties:

      name: interview name
      title: alias for name
      identifier: interview identifier in the Campsite database
      description_short: short description
      description: full description
      questions_limit: max. amount of questions per reader
      status: draft, pending, published, offline
      last_modified: timestamp of last modification
      moderator_user_id
      guest_user_id
      defined
      image: the image object assigned to this interview
      image_description
      questions_begin: from this timestamp questions can be added by reader
      questions_end: until this timestamp questions can be added by reader
      interview_begin: from this timestamp questions can be answered by guest
      interview_end: until this timestamp questions can be answered by guest
      in_questions_timeframe: is now within questions timeframe
      in_interview_timeframe: is now within interview-timeframe
      language: language object
      moderator: user object of the interview moderator
      guest: user object of the interview guest
      is_user_admin: is the logged-in user interview-admin
      is_user_moderator: is the logged-in user interview-moderator
      is_user_guest: is the logged-in user interview-guest
      invitation_sent: timestamp when invitation was sent



Interview Item

An Interview Item contains an pair of one question and it's answer. For each interview, a certain
number of interview items are used.


The Interview Item object has the following properties:


                                                                                                    239
      identifier: interview item identifier in the Campsite database
      interview_id: the identifier of the interview containing this item
      question: the question text
      status: draft, pending, published, offline
      answer: text of the answer
      item_order
      last_modified: timestamp of last modification
      defined
      questioneer: the user object of the questioneer
      interview: the interview object containing this item



List of Interviews

Purpose:

Select the list of interviews according to the given constraints and current environmental
variables. The code between "{{ list_interviews }}" statement and "{{ /list_interviews }}" is
repeated for every interview in the list.

Syntax:
{{ list_interviews [length="<integer_value>"] [columns="<integer_value>"]
  [constraints="<list_of_interview_constraints>"]
  [order="<order_condition>"]>

}}

<list_of_instructions>
{{ /list_interviews }}

where:

      length="<integer_value>": <integer_value> specifies list_length and forces the list to have
      at most list_length items. If the list contains more items than list_length items the ones not
      fitting in can be listed using If NextItems/PreviousItems statements.

      columns="<integer_value>": <integer_value> specifies columns_number and sets an
      environment variable. This is incremented as if the items would be placed in a table cell.
      The counting starts from one and the variable is incremented for every new element.
      When it reaches the maximum value it is reset to one. This is very useful in building tables
      of data. For details see If List.

<list_of_instructions> may contain any statement except: "set_interview".

<list_of_interview_constraints>= [<interview_constraint>] <list_of_interview_constraints>
                                 | <iinterview_constraint>
<interview_constraint>= id <integer_operator> <integer_value>
                        | name <string_operator> <string_value>
                        | language_id <integer_operator> <integer_value>
                        | moderator_user_id <integer_operator> <integer_value>
                        | guest_user_id <integer_operator> <integer_value>
                        | status <string_operator> <string_value>
                        | <date_constraint>


<date_constraint>= interview_begin <date_operator> <date_value>
                   | interview_begin_year <integer_operator> <integer_value>
                   | interview_begin_month <integer_operator> <integer_value>
                   | interview_begin_wday <integer_operator> <integer_value>
                   | interview_end <date_operator> <date_value>
                   | interview_end_year <integer_operator> <integer_value>
                   | interview_end_month <integer_operator> <integer_value>
                   | interview_end_wday <integer_operator> <integer_value>

240
                      | questions_begin <date_operator> <date_value>
                      | questions_begin_year <integer_operator> <integer_value>
                      | questions_begin_month <integer_operator> <integer_value>
                      | questions_begin_wday <integer_operator> <integer_value>
                      | questions_end <date_operator> <date_value>
                      | questions_end_year <integer_operator> <integer_value>
                      | questions_end_month <integer_operator> <integer_value>
                      | questions_end_wday <integer_operator> <integer_value>



<order_condition>= byIdentifier desc|asc
                   | byName desc|asc
                   | byTitle desc|asc
                   | byQuestions_begin desc|asc
                   | byQuestions_end desc|asc
                   | byInterview_begin desc|asc
                   | byInterview_end desc|asc
                   | byModerator desc|asc
                   | byGuest desc|asc
                   | byStatus desc|asc
                   | byOrder desc|asc




List of Interview Items

Purpose:

Select the list of interview items according to the given constraints and current environmental
variables. The code between "{{ list_interviews }}" statement and "{{ /list_interviews }}" is
repeated for every interview item in the list.

Syntax:
{{ list_interviewitems [length="<integer_value>"] [columns="<integer_value>"]
  [constraints="<list_of_interview_constraints>"]
  [order="<order_condition>"]>

}}

<list_of_instructions>
{{ /list_interviewitems }}

where:

      length="<integer_value>": <integer_value> specifies list_length and forces the list to have
      at most list_length items. If the list contains more items than list_length items the ones not
      fitting in can be listed using If NextItems/PreviousItems statements.



                                                                                                       241
      columns="<integer_value>": <integer_value> specifies columns_number and sets an
      environment variable. This is incremented as if the items would be placed in a table cell.
      The counting starts from one and the variable is incremented for every new element.
      When it reaches the maximum value it is reset to one. This is very useful in building tables
      of data. For details see If List.

<list_of_instructions> may contain any statement except: "set_interview", "set_interviewitem".

<list_of_interviewitem_constraints>= [<interviewitem_constraint>]
                                      <list_of_interviewitem_constraints>
                                      | <iinterviewitem_constraint>
<interviewitem_constraint>= status <string_operator> <string_value>
                             | questioneer_user_id <integer_operator> <integer_value>
                             | answer <string_operator> <string_value>
                             | status <string_operator> <string_value>



<order_condition>= byIdentifier desc|asc
                   | byQuestioneer desc|asc
                   | byQuestion desc|asc
                   | byAnswer desc|asc
                   | byStatus desc|asc
                   | byOrder desc|asc




ADMIN INTERFACE
In this article:

      Admin Screen
      Moderator Screen
      Guest Screen

The administration of interviews is seperated into 3 roles:

  1. Admin: Admins can create new interviews, and have access to any action
  2. Moderator: Each interview is assigned to one moderator. His main task is to accept or
     reject incoming questions.
  3. Guest: Each Interview have one guest assigned, who is reponsible to answer the questions



Admin Screen

List of Interviews

The admin screen display an list of interview. There are language and status filters for it, and
columns can be ordered by each kind of item.

Following actions can be processed:




242
      Edit interview setting
      Change ordering of interviews
      Change interviews status (checkboxes to select multiple interviews)
      Delete interview (checkboxes to select multiple interviews)

Edit Interview

By clicking on an interview's title, an popup form appear which let you edit all interview setting.
Here you can adjust:

      Language
      Moderator: All users with proper role are listed. New moderator must be added in user
      management.
      Guest: All users with proper role are listet. A new guest login can be created here.
      Title: A title for that interview
      Image: You can upload an image to an interview. Thumbnail will automatically generated.
      Image description
      Delete Image: Use this checkbox to remove an existing image.
      Short Description: Up to 256 chars
      Description
      Questions Begin - Question End: within this timeframe readers can add their questions
      Interview Begin - Interview End: within this timeframe guest can answer
      Questions Limit: Per-reader limit
      Status: See description

The Questions timeframe can overlap with interview timeframe.


List of Interview Items

On this screen all items for an selected interview are displayed, and following actions can be
processed:

      Edit an item
      Change ordering of items
      Change status of item (checkboxes to select multiple interviews)
      Delete item (checkboxes to select multiple interviews)

Edit Interview Item

The admin is able to edit the question and answer (e.g. mistypes), and change the status here.

Invitations

Clicking the letter-symbol in the main admin page, will open an window to setup and send
invitations to reders which have register themself for this service. An red symbol indicated thet
an invitation for this interview was already sent.

The popup screen allows setup of the email parts:

      Sender: Use the syntax "Clear Name <address@domain>"
      Subject: Plain text email subject
      Template: In this template the objects $campsite->interview and $campsite->user are
      available with all their properties. In preview mode, the logged in user will be used.

Clicking the "Preview" button will save the settings and displays an preview of the email.
Carefully check it before send by clicking button "Invite now".



Moderator Screen


                                                                                                      243
Guest Screen

This screen display an list of interviews, which are assigned to the logged-in moderator. There
are language and status filters for it, and columns can be ordered by each kind of item.

The only available action is to list interview items.


List of Interview Items

On this screen all items for an selected interview are displayed, and following actions can be
made:

      Edit an item
      Change status of item (checkboxes to select multiple interviews)
      Delete item (checkboxes to select multiple interviews)

Accept/Reject items

To hand over new questions to the guest, they have to be set to status "pending".
If an question should not be answered, but stored in the system, status "rejected" is used.

Items can also be deleted here.

Use the checkboxes for multiple actions.


Edit Interview Item

The moderator is able to edit the question (e.g. mistypes), and change the status on this screen.



Guest Screen

List of Interviews

This screen display an list of interviews, which are assigned to the logged-in guest. There are
language and status filters for it, and columns can be ordered by each kind of item.

The only available action is to list interview items.


List of Interview Items

On this screen all items for an selected interview are displayed, which are passed by from the
moderator. The guest have to pick up those with status "pending" and answer them in the
popup. After answering an item, it will automatically get status "published". This does not mean
that it occours on the website, just is the interview is also published all published items will
occour.



HELP
64. Where to go for support
65. About this manual




244
64. WHERE TO GO FOR SUPPORT
Forum and mailing list: You can visit the Campsite online support forum, and sign up for the
mailing list, at http://forum.sourcefabric.org/index.php/f/10/.

This forum is mirrored by the mailing list, so posts on the forum appear on the mailing list and
vice versa. You can therefore also post a message there by emailing: campsite-
support@lists.sourcefabric.org.

To subscribe to forum updates via mail, please register or login to the forum by clicking the
appropriate link. Then click the 'Subscribe' button at the top of each forum page.

Bug reporting: Campsite needs your input to improve. If you think you've found a bug, please
visit http://dev.sourcefabric.org and sign in, using the same login and password that you
registered for the Campsite forum. Create a bug report by selecting Create Issue, then
Campsite, and then Bug. That way, the Campsite team can keep track of your problem and
notify you when it has been fixed. You can also suggest improvements and new features for
Campsite on that site.

Contact: Finally, when all other avenues have been exhausted, email us directly at
contact@sourcefabric.org and we'll try to help!




                                                                                                   245
65. ABOUT THIS MANUAL
Campsite is being developed by an international community of developers and designers
led by Sourcefabric (formerly Campware).

http://campsite.sourcefabric.org

Copyright (C) 2010 Sourcefabric o.p.s
Copyright (C) 1999-2009 Media Development Loan Fund.

LICENSE
All chapters copyright of the authors (see below). Unless otherwise stated all chapters in this
manual licensed with GNU General Public License version 2

This documentation is free documentation; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This documentation is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this
documentation; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.

AUTHORS
This manual has been edited and reworked by Daniel James, based on the collaborative effort at
FLOSS Manuals. Thanks to all contributors!




Free manuals for free software


GENERAL PUBLIC LICENSE
Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

Preamble

The licenses for most software are designed to take away your freedom to share and change it.
By contrast, the GNU General Public License is intended to guarantee your freedom to share and
change free software--to make sure the software is free for all its users. This General Public
License applies to most of the Free Software Foundation's software and to any other program
whose authors commit to using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to your programs, too.




246
When we speak of free software, we are referring to freedom, not price. Our General Public
Licenses are designed to make sure that you have the freedom to distribute copies of free
software (and charge for this service if you wish), that you receive source code or can get it if
you want it, that you can change the software or use pieces of it in new free programs; and that
you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to deny you these rights
or to ask you to surrender the rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or for a fee, you must
give the recipients all the rights that you have. You must make sure that they, too, receive or
can get the source code. And you must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2) offer you this license
which gives you legal permission to copy, distribute and/or modify the software.

Also, for each author's protection and ours, we want to make certain that everyone understands
that there is no warranty for this free software. If the software is modified by someone else and
passed on, we want its recipients to know that what they have is not the original, so that any
problems introduced by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We wish to avoid the
danger that redistributors of a free program will individually obtain patent licenses, in effect
making the program proprietary. To prevent this, we have made it clear that any patent must
be licensed for everyone's free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification follow.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License applies to any program or other work which contains a notice placed by the
copyright holder saying it may be distributed under the terms of this General Public License. The
"Program", below, refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law: that is to say, a work
containing the Program or a portion of it, either verbatim or with modifications and/or translated
into another language. (Hereinafter, translation is included without limitation in the term
"modification".) Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not covered by this License; they
are outside its scope. The act of running the Program is not restricted, and the output from the
Program is covered only if its contents constitute a work based on the Program (independent of
having been made by running the Program). Whether that is true depends on what the Program
does.

1. You may copy and distribute verbatim copies of the Program's source code as you receive it,
in any medium, provided that you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to
this License and to the absence of any warranty; and give any other recipients of the Program a
copy of this License along with the Program.

You may charge a fee for the physical act of transferring a copy, and you may at your option
offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Program or any portion of it, thus forming a work
based on the Program, and copy and distribute such modifications or work under the terms of
Section 1 above, provided that you also meet all of these conditions:

      a) You must cause the modified files to carry prominent notices stating that you changed
      the files and the date of any change.

      b) You must cause any work that you distribute or publish, that in whole or in part
      contains or is derived from the Program or any part thereof, to be licensed as a whole at
      no charge to all third parties under the terms of this License.

                                                                                                      247
      c) If the modified program normally reads commands interactively when run, you must
      cause it, when started running for such interactive use in the most ordinary way, to print
      or display an announcement including an appropriate copyright notice and a notice that
      there is no warranty (or else, saying that you provide a warranty) and that users may
      redistribute the program under these conditions, and telling the user how to view a copy of
      this License. (Exception: if the Program itself is interactive but does not normally print such
      an announcement, your work based on the Program is not required to print an
      announcement.)

These requirements apply to the modified work as a whole. If identifiable sections of that work
are not derived from the Program, and can be reasonably considered independent and separate
works in themselves, then this License, and its terms, do not apply to those sections when you
distribute them as separate works. But when you distribute the same sections as part of a
whole which is a work based on the Program, the distribution of the whole must be on the terms
of this License, whose permissions for other licensees extend to the entire whole, and thus to
each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest your rights to work written
entirely by you; rather, the intent is to exercise the right to control the distribution of derivative
or collective works based on the Program.

In addition, mere aggregation of another work not based on the Program with the Program (or
with a work based on the Program) on a volume of a storage or distribution medium does not
bring the other work under the scope of this License.

3. You may copy and distribute the Program (or a work based on it, under Section 2) in object
code or executable form under the terms of Sections 1 and 2 above provided that you also do
one of the following:

      a) Accompany it with the complete corresponding machine-readable source code, which
      must be distributed under the terms of Sections 1 and 2 above on a medium customarily
      used for software interchange; or,

      b) Accompany it with a written offer, valid for at least three years, to give any third party,
      for a charge no more than your cost of physically performing source distribution, a
      complete machine-readable copy of the corresponding source code, to be distributed under
      the terms of Sections 1 and 2 above on a medium customarily used for software
      interchange; or,

      c) Accompany it with the information you received as to the offer to distribute
      corresponding source code. (This alternative is allowed only for noncommercial distribution
      and only if you received the program in object code or executable form with such an offer,
      in accord with Subsection b above.)

The source code for a work means the preferred form of the work for making modifications to
it. For an executable work, complete source code means all the source code for all modules it
contains, plus any associated interface definition files, plus the scripts used to control compilation
and installation of the executable. However, as a special exception, the source code distributed
need not include anything that is normally distributed (in either source or binary form) with the
major components (compiler, kernel, and so on) of the operating system on which the executable
runs, unless that component itself accompanies the executable.

If distribution of executable or object code is made by offering access to copy from a designated
place, then offering equivalent access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not compelled to copy the source
along with the object code.

4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided
under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program
is void, and will automatically terminate your rights under this License. However, parties who
have received copies, or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.

248
5. You are not required to accept this License, since you have not signed it. However, nothing
else grants you permission to modify or distribute the Program or its derivative works. These
actions are prohibited by law if you do not accept this License. Therefore, by modifying or
distributing the Program (or any work based on the Program), you indicate your acceptance of
this License to do so, and all its terms and conditions for copying, distributing or modifying the
Program or works based on it.

6. Each time you redistribute the Program (or any work based on the Program), the recipient
automatically receives a license from the original licensor to copy, distribute or modify the
Program subject to these terms and conditions. You may not impose any further restrictions on
the recipients' exercise of the rights granted herein. You are not responsible for enforcing
compliance by third parties to this License.

7. If, as a consequence of a court judgment or allegation of patent infringement or for any other
reason (not limited to patent issues), conditions are imposed on you (whether by court order,
agreement or otherwise) that contradict the conditions of this License, they do not excuse you
from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent license would not permit royalty-
free redistribution of the Program by all those who receive copies directly or indirectly through
you, then the only way you could satisfy both it and this License would be to refrain entirely
from distribution of the Program.

If any portion of this section is held invalid or unenforceable under any particular circumstance,
the balance of the section is intended to apply and the section as a whole is intended to apply in
other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right
claims or to contest validity of any such claims; this section has the sole purpose of protecting
the integrity of the free software distribution system, which is implemented by public license
practices. Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that system; it is up to
the author/donor to decide if he or she is willing to distribute software through any other system
and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the
rest of this License.

8. If the distribution and/or use of the Program is restricted in certain countries either by
patents or by copyrighted interfaces, the original copyright holder who places the Program under
this License may add an explicit geographical distribution limitation excluding those countries, so
that distribution is permitted only in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of this License.

9. The Free Software Foundation may publish revised and/or new versions of the General Public
License from time to time. Such new versions will be similar in spirit to the present version, but
may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Program specifies a version number
of this License which applies to it and "any later version", you have the option of following the
terms and conditions either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of this License, you may
choose any version ever published by the Free Software Foundation.

10. If you wish to incorporate parts of the Program into other free programs whose distribution
conditions are different, write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free Software Foundation; we
sometimes make exceptions for this. Our decision will be guided by the two goals of preserving
the free status of all derivatives of our free software and of promoting the sharing and reuse of
software generally.

NO WARRANTY


                                                                                                      249
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE
PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE
PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE
PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS




250

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:15
posted:2/8/2012
language:
pages:250