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":
- 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
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):
- Arabic
- Belarusian
- Chinese (Simplified)
- Chinese (Traditional)
- Croatian
- Czech
- Dutch
- English
- French
- Georgian
- German
- Korean
- Polish
- Portuguese
- Romanian
- Russian
- Serbian (Cyrillic)
- Serbo-Croatian (Latin)
- Spanish
- Swedish
Further translations can be added using a tool built into Campsite called the "Localizer".
Content Features
- 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
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
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.
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:
- Configure apache: create an apache virtual host (optional)
- Setup your php.ini file
- Copy the Campsite package to a directory on your server.
- Unarchive it using the command: tar xzvf <Campsite_source>.
- Enter Campsite directory: "cd campsite".
- Copy the content of implementation/site directory into the document root directory of the apache virtual host.
- 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
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:
-
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:
- Backup the instance using campsite-backup-instance
- Perform a new Campsite 3.3 install
- 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.
-
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.
-
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
-
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.
-
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].
-
Edit the Campsite virtual host file.
-
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.
-
Edit the first virtual host definition and replace the existing <VirtualHost [...]> tag with:
<VirtualHost [my_IP_addresss]:80>
-
Edit the second virtual host definition and replace the existing <VirtualHost [...]> tag with:
<VirtualHost [my_IP_address]:443>
-
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:
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);
"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)
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
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.
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".
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
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
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!
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
If the folder does not exist: create it. And set the rights to readable and writeable for apache.
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:
Optional programs:
Installing MySQL under Windows Vista
MySQL has a number of known issues installing under Windows Vista. You must:
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:
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.
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:
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 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.
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.
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
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
Automated tasks
Campsite has tools that perform the following automated tasks:
- sending emails to administrative users containing the latest events that took place in Campsite
- sending emails to subscribers alerting them when their subscription ends
- automatic changing of the status of issues and articles scheduled for certain actions
- automatic indexing the article content (update the search engine database)
- 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.
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.
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.
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:
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
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
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
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
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:
- Configuring the publication, and specifying the templates to be used
- Establishing the structure of your publication, with issues and sections
- 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.
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:

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

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

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.

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

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

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

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

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.

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.

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.

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:

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

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

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:

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

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

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.

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

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

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.
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.
Here is what each of the options means:
- 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.

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

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

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

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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

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.

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

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

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:

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:

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.
[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> 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.
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.
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.
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
- 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.
Template Quickstart Guide: "How do I..."
- In this chapter:
- How to create a list of the most popular articles in a section
- How to create breadcrumbs
- How to do article pagination?
- How to display the most recently published articles?
- How to make a hard-coded link to an article?
- How to check if there are any articles in a section?
- How to display content based on the day of the weeek or date
- 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>
>
<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>
>
<a href="{{ uri options="issue" }}">{{ $campsite->issue->name }}</a>
>
<a href="{{ uri options="section" }}">{{ $campsite->section->name }}</a>
?>
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:
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" }}
{{ 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 }}
{{ /if }}
Furthermore, you can use all smarty date_format conversion specifiers for this or similar purpose:
-
%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
-
%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.
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 }}
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:
{{ 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 }}
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: /en/may30/news/summer_is_coming. 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.
<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.)
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
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:
- 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
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
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
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 }}
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# >
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#" }}
Template Language Reference
- In this chapter:
- Language Elements; Conventions
- Basic Syntax
- Template Objects
- Environmental Control
- Lists
- Forms
- Miscellaneous
- Campsite Modifiers
-
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:
- 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.
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'}}
{{* 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.. *}}
{{* $Id: Exp $ *}}
{{* $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
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}}
|
|
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.
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.
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}
{$articleTitle|lower|truncate:30|spacify}
{$articleTitle|lower|spacify|truncate:30:". . ."}
|
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.
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:
- 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:
- 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:
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:
- 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":
$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
-
- Setting the Context Article
- Breaking an article into multiple parts
-
- Subtitle
- Subtitles List
- Current List
- Displaying Image Info
-
- Displaying Topics
-
- Topic
- Article Topics List
- Displaying Attachments
-
- Article Attachment
- Article Attachments List
- Comments
-
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
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
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
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:
- 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:
- 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>">
- 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:
- 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
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:
- 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:
- 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
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:
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:
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
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
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".
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>" }}
{{ 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 }}
Constraints:
Cannot be used inside "list_article_comments" statement.
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
|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>
|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:
- 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
- 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"
- 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.
| <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:
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" }}
<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 }}
<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:
- 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:
- 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:
- 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 |
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.
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:
- list_subtopics
- set_topic
- set_default_topic
- unset_topic
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>
<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 }}
- <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 }}
- <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.
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:
{{ 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:
- 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:
{{ 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
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 }}">
Syntax:
{{ captcha_image_link }
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:
- 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.
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" 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 }}
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ö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 }} | Section: {{ $campsite->section->name }}
</li>
{{ if $campsite->current_list->at_end }}
</ul>
<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" }}">«</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" }}">»</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 }}
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:

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" }}">«</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" }}">»</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" }}
{{ 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.
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
| 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:
|
<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 }}
|
- 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
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=/">
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:
- %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 }}
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>
<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.
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:
-
Create the new templates in a separate directory
-
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).
-
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>
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.
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:
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.
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.
Polls Plugin
- In this chapter:
-
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)
{
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 }}
{{ /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 |
Ø{{ $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>
<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" }}&f_poll_nr={{ $campsite->poll->number }}&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 }}
{{ /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
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
| 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>
| 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 |
|
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:
- Admin created interview, status draft
- 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.
- The moderator accept or reject new questions. Spam etc. can be deleted instantly.
- Within the interview timeframe, the guest answers the questions. Answered questions automatically get status published.
- The admin set the interview status to published, so the questions and answers are shown on the website.
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:
- 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> |
|
<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>
| 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.
- 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:
- Admin: Admins can create new interviews, and have access to any action
- Moderator: Each interview is assigned to one moderator. His main task is to accept or reject incoming questions.
- 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:
- 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
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.
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!
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.
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.
- 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.
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
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