## Before You Begin ##
Welcome to the 1.0 stable release of Apostrophe! Although this is our first official stable release, our CMS is already in regular use on a number of production sites. This release reflects the fact that our code has been stable and ready for your professional use for quite some time.
We strongly recommend that you follow the instructions in this
document which enable you to check out or copy a complete project from svn. Another good
option is to download a tarball of our complete sandbox project from [apostrophenow.com](http://www.apostrophenow.com/). *We start our own
production client sites* using the `svnforeigncopy` tool described here, so you will get
maximum support by following that approach.
## Overview ##
This document has four major sections:
* Installation
* Editor's guide
* Designer's guide
* Developer's guide
These are intended to be read consecutively, except for the installation section which is not appropriate if you are not installing Apostrophe yourself. Stop reading when you know what you need to know!
The installation section is intended for developers and system administrators with some knowledge of PHP and command line tasks.
The editor's guide is suitable for end users who will have administrative responsibilities on the site, such as editing and managing content. No programming skills required.
The designer's guide addresses the needs of front-end developers, discussing how to edit and manage stylesheets, page templates and page layouts.
Finally, the developer's guide explores how to extend Apostrophe with new content slots that go beyond our provided rich text and media features and new "engines" that extend the CMS with full-page content that doesn't always fit neatly into the page metaphor. Most readers will never need to refer to this section.
See the end of this document for information about community and professional support, the Apostrophe community and how to participate in further development.
### Guiding Philosophy ###
[Apostrophe](http://www.apostrophenow.com/) is a content management system. Apostrophe is open source, and built upon the great work of other open source projects. That's why our apostrophePlugin is a plugin for the [Symfony](http://www.symfony-project.org/) web application framework.
The philosophy of Apostrophe is that editing should be done "in context" as much as possible, keeping confusing modal interfaces to a minimum and always emphasizing good design principles and an intuitive user experience. When we are forced to choose between ease of use and a rarely used feature, we choose ease of use, or make it possible to discover that feature when you truly need it.
Before we decided to write our own CMS, we used sfSimpleCMSPlugin, and although our system is quite different you can see its influence in Apostrophe. We'd like to acknowledge that.
### Who Should Use Apostrophe Today? ###
Right now Apostrophe is best suited to PHP developers who want to make an intuitive content management system available to their clients. Apostrophe is very easy for your clients to edit, administer and maintain once it is set up. Right now, though, Apostrophe installations does call for some command line skills and a willingness to learn about Symfony. We are working to reduce the learning curve.
Front-end developers who do not yet have PHP and Symfony skills but wish to set up an Apostrophe site by themselves should consider tackling the [Symfony tutorial](http://www.symfony-project.org/jobeet/1_4/Doctrine/en/) to get up to speed. It's not necessary to complete the entire tutorial, but it helps to have at least a passing familiarity with Symfony.
And of course we at [P'unk Avenue](http://www.punkave.com/) are available to develop complete Apostrophe sites for those who see the value in a truly intuitive CMS and do not have the development resources in-house to implement it.
### Apostrophe Features ###
Standard features of Apostrophe include version control for all content slots, locking down pages for authenticated users only, and in-context addition, deletion, reorganization and retitling of pages. When a user is logged in with appropriate privileges intuitive editing tools are added to the usual navigation, neatly extending the metaphors already present rather than requiring a second interface solely for editing purposes.
Apostrophe also introduces "areas," or vertical columns, which users with editing privileges are able to create more than one slot. This makes it easy to interleave text with multimedia and other custom slot types without the need to develop a custom PHP template for every page.
Apostrophe includes support for media management, including a built-in media library that allows you to manage locally stored photos and remotely hosted videos. When media are embedded in pages they are automatically sized to cooperate with the page templates created by the designer.
Rich text editing, of course, is standard equipment. And unlike most systems, Apostrophe intelligently filters content pasted from Word and other programs to ensure there are no design-busting markup conflicts.
### Supported Browsers ###
Editing works 100% in Firefox 2+, Safari 4+, Chrome and Internet Explorer 7+.
Editing is expressly not supported in Internet Explorer 6. Of course,
browsing the site as a user works just fine in Internet Explorer 6. Although IE 6 cannot support our full editing experience, we recognize the need to support legacy browser use by the general public when visiting the site.
### System Requirements ###
apostrophePlugin requires the following. Note that virtually all of the
requirements are included in the asandbox project which you can easily
check out from svn, copy from svn to your own repository as described below, or just download as a tarball.
The following must be installed on your system:
* PHP 5.2.4 or better, with a PDO driver for MySQL (PHP 5.3.x works but is still rather buggy as of this writing; this refers to PHP's bugs, not ours)
* MySQL (tested), SQLite (tested), or another relational database supported by PDO and Doctrine (a few nonessential features are MySQL-specific)
* For the media features: GD support in PHP, or the netpbm utilities. netpbm uses much less memory
* Optional, for previews of PDFs in PDF slots: ghostscript (you must also have netpbm to use this feature)
A few truly excellent hosting companies already have netpbm and ghostscript in place. If you have a Virtual Private Server
(and you should, shared hosting is very insecure), you can most likely install
netpbm and ghostscript with a few simple commands like `sudo apt-get install netpbm`
and `sudo apt-get install ghostscript`.
If you are choosing a Linux distribution, we recommend Ubuntu. Ubuntu includes a sufficiently modern version of PHP right out of the box. If you are using Red Hat Enterprise Linux or CentOS, you will need to upgrade PHP to version 5.2.x on your own. This is unfortunate and Red Hat really ought to get a move on and fix it.
#### PHP Libraries ####
** All of these are included in the sandbox project, no need to install them. ** We list them here for developers who want to know what we're relying on.
* Doctrine
* The Zend framework, for search
* Symfony 1.3 or 1.4
#### Symfony Plugins ####
** All of these are included in the sandbox project, no need to install them. ** We list them here for developers who want to know what we're relying on.
* sfSyncContentPlugin
* sfJqueryReloadedPlugin
* sfDoctrineGuardPlugin
* sfWebBrowserPlugin
* sfFeed2Plugin
* sfDoctrineActAsTaggablePlugin
* apostrophePlugin
Note that if you checked out or copied our sandbox project from svn, all of the components "provided with asandbox" are provided as svn externals, which means they update automatically when you type `svn update`. Wherever possible we've pinned these to stable branches, not development versions.
Optional components of interest: apostrophePlugin is compatible with sfShibbolethPlugin (the 1.2 trunk version) and sfDoctrineApplyPlugin.
Mac users can most easily meet the PHP requirements by installing
the latest version of [MAMP](http://www.mamp.info/). Note that MAMP's PHP
must be your command line version of PHP, not Apple's default install of PHP.
To fix that, add this line to the `.profile` file in your home directory:
export PATH="/Applications/MAMP/Library/bin:/Applications/MAMP/bin/php5/bin:$PATH"
Of course your production server will ultimately need to meet the same requirements with regard to PHP and PDO.
Apple's default version of PHP for Snow Leopard is theoretically capable of working with Apostrophe, but unfortunately Apple chose to ship a very bleeding-edge version and as of this writing they have not updated it to address the many PHP bugs since discovered. As of this writing we recommend the latest in the PHP 5.2.x series, not PHP 5.3.x, due to numerous hard crashes at the PHP level with PHP 5.3.x.
The use of Microsoft Windows as a hosting environment has not yet been fully validated, however our core features do not depend heavily upon Unix-specific functions and utilities.
## Installation ##
There are two ways to get started with Apostrophe. You can start with our sandbox project, which we heartily recommend, or add the apostrophePlugin to your existing Symfony project. The latter only makes sense for experienced Symfony developers whose sites are already well underway. I'll describe both approaches.
### Ways to Download the Apostrophe Sandbox Project ###
#### Download The Tarball ####
The easiest way is to just [download a tarball of the sandbox project.](http://www.apostrophenow.com/downloads/asandbox-stable.tar.gz) This tarball is updated nightly from the stable branch of our sandbox. This is a great way to get started, but note that you won't be able to get security and stability fixes just by typing `svn update` this way.
#### Check It Out From Subversion ####
Alternatively you can check it out with subversion:
svn co http://svn.symfony-project.com/plugins/apostrophePlugin/asandbox/branches/1.3 asandbox
That will check out the 1.3 stable branch, which is suitable for use with both Symfony 1.3 and Symfony 1.4.
If you prefer to live dangerously and use our most bleeding-edge code, you can check out the trunk instead:
svn co http://svn.symfony-project.com/plugins/apostrophePlugin/asandbox/trunk asandbox
We love it when you do this, because it results in more feedback for us, but you should definitely consider using the stable branch for your client projects.
#### Our Favorite: Copying the Sandbox to Your Own Repository ####
Checking out the sandbox from svn is a nice way to get started, but you'll soon wonder how to save your own changes when the project is part of our own svn repository. That's why we recommend that you instead
copy it to your own repository with [svnforeigncopy](https://sourceforge.net/projects/svnforeigncopy/) each time you want to start a new site. That's what we do. With `svnforeigncopy` you get a copy of the asandbox project in your own svn repository, with the `svn:ignore` and `svn:externals` properties completely intact. You don't get the project history, but since 99% of the code is in the externally referenced plugins and libraries, that's really not a big deal. The important thing is that you are still connected to the latest bug-fix updates for our plugin.
This will give you all of the necessary plugins and the ability to
`svn update` the whole shebang with one command.
### Apache Configuration ###
Once you have fetched the code by your means of choice, you're ready to configure your testing web server to recognize a new website. Light up the folder `asandbox/web` as a virtualhost named `asandbox` via MAMP, `httpd.conf` or whatever your web hosting environment requires. As with any Symfony project you'll want to allow full Apache overrides in this folder. See `config/vhost.sample` for tips on virtual host configuration for Apache. Make sure the directives in `web/.htaccess` will be honored by your server.
(Confused about this MAMP stuff? Wondering how you can test websites on your own computer? You really need to pick up [MAMP](http://www.mamp.info/) if you are on a Mac. Windows and Linux users should consider using [XAMPP](http://www.apachefriends.org/en/xampp.html). These are all-in-one packages with PHP, MySQL, Apache and everything else you need to test real websites on your own computer.)
### Symfony Configuration ###
Yes, this is a preconfigured sandbox project, but you do have to adjust a few things to reflect reality on your own computer.
Now create the `config/databases.yml` file, which must contain
database settings appropriate to *your* system. Copy the file
`config/databases.yml.sample` as a starting point:
cp config/databases.yml.sample config/databases.yml
If you are testing with MAMP the default settings
(username root, password root, database name asandbox) may work
just fine for you. If you are testing on a staging server you will
need to change these credentials.
Also create your `properties.ini` file:
cp config/properties.ini.sample config/properties.ini
In Symfony `properties.ini` contains information about hosts that a project can be synced to, in addition
to the name of the project. The sample properties.ini file just defines the name of the project. You'll
add information there when and if you choose to sync the project to a production server via `project:deploy` or our enhanced version, `apostrophe:deploy`. See the Symfony documentation for more information about that technique.
At this point you're ready to use the checkout of Symfony's 1.4.x stable branch
that is included in the project. If you want to use a different installation
of Symfony, such as a shared install for many sites (note that only 1.3.x and 1.4.x are likely to work), copy config/require-core.php.example to config/require-core.php and edit the
paths in that file.
Next, cd to the `asandbox` folder and run these commands:
./symfony doctrine:build --all
./symfony doctrine:data-load
This will create a sample database from the fixtures files.
If you prefer, you can pull down our full demo site as an alternative to the somewhat bland fixtures site:
./symfony apostrophe:demo-fixtures
Note that this task will run for quite a while as media files are included in the download.
Now set the permissions of data folders so that they are writable by the web
server. Note that svn does NOT store permissions so you can NOT assume they are
already correct:
./symfony project:permissions
Our apostrophePlugin extends project:permissions for you to include the
data/writable folder in addition to the standard web/uploads, cache and log folders. Handy, isn't it?
If you prefer you can do this manually:
chmod -R 777 data/a_writable
chmod -R 777 web/uploads
chmod -R 777 cache
chmod -R 777 log
More subtle permissions are possible. However be aware that most
"shared hosting" environments are inherently insecure for a variety
of reasons. Production Symfony sites should run on a virtual machine of their own, or share a VM only with other sites written by you. So before criticizing the "777 approach," be sure
to [read this article on shared hosting and Symfony](http://trac.symfony-project.org/wiki/SharedHostingNotSecure).
Next, build the site's search index for the first time (yes, search is included). It doesn't live in
the database so it needs to be done separately. After this, you won't
need to run this command again unless you are deploying to a new
environment such as a staging or production server and don't plan to sync your content with sfSyncContentPlugin:
./symfony apostrophe:rebuild-search-index --env=dev
(You can specify `staging` or `prod` instead to build the search indexes
for environments by those names. You'll want that later when working on a production server.)
You can now log in as `admin` with the password `demo` to see how the
site behaves when you're logged in (if you used the apostrophe:demo-fixtures task, the password will be `demo`). Start adding subpages, editing slots, adding slots to the multiple-slot content area... have a ball with it!
### The Hard Way: Adding apostrophePlugin To An Existing Site ###
*Those who installed the sandbox just now can skip right over this section.*
Installing the sandbox is the easy way to install Apostrophe. The notes that follow assume you're doing it the hard way, without starting from the asandbox project.
Begin by installing the following Symfony plugins into your Symfony 1.3/1.4 project:
* sfJqueryReloadedPlugin
* sfDoctrineGuardPlugin
* sfDoctrineActAsTaggablePlugin
* sfWebBrowserPlugin
* sfFeed2Plugin
* sfSyncContentPlugin (recommended but not required)
* And of course, [apostrophePlugin](http://www.symfony-project.org/plugins/pkContextCMSPlugin)
We strongly encourage you to do so using svn externals. If you are using that approach you will need to be sure to create the necessary symbolic links from your projects web/ folder to to the web/ folders of the plugins that have one. For best results use a relative path:
cd web
ln -s ../plugins/apostrophePlugin/web apostrophePlugin
# Similar for other plugins required
The search features of the plugin rely on Zend Search, so you must
also install the Zend framework.
[The latest version of the minimal Zend framework is sufficient.](http://framework.zend.com/download/latest) If you choose to install this system-wide
where all PHP code can easily find it with a `require` statement, great.
If you prefer to install it in your Symfony project's
`lib/vendor` folder, you'll need to modify your `ProjectConfiguration` class
to ensure that `require` statements can easily find files there:
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
// We do this here because we chose to put Zend in lib/vendor/Zend.
// If it is installed system-wide then this isn't necessary to
// enable Zend Search
set_include_path(
sfConfig::get('sf_lib_dir') .
'/vendor' . PATH_SEPARATOR . get_include_path());
// for compatibility / remove and enable only the plugins you want
$this->enableAllPluginsExcept(array('sfPropelPlugin'));
}
}
Create an application in your project. Then create a
module folder named `a` as a home for your page templates
and layouts (and possibly other customizations):
mkdir -p apps/frontend/modules/a/templates
The CMS provides convenient login and logout links. By default these
are mapped to sfGuardAuth's signin and signout actions. If you are
using sfShibbolethPlugin to extend sfDoctrineGuardPlugin, you'll
want to change these actions in apps/frontend/config/app.yml:
all:
sfShibboleth:
domain: duke.edu
a:
actions_logout: "sfShibbolethAuth/logout"
actions_login: "sfShibbolethAuth/login"
You can also log in by going directly to `/login`. If you don't want to display the login link
(for instance, because your site is edited only you), just shut that feature off:
all:
a:
login_link: false
You will also need to enable the a modules in
your application's `settings.yml` file. Of course you may need
other modules as well based on your application's needs:
enabled_modules:
- a
- aSync
- aNavigation
- aMedia
- aMediaBackend
- aRichTextSlot
- aTextSlot
- aRawHTMLSlot
- aSlideshowSlot
- aVideoSlot
- aImageSlot
- aButtonSlot
- aPDFSlot
- aFeedSlot
- sfGuardAuth
- aUserAdmin
- aGroupAdmin
- aPermissionAdmin
- sfGuardPermission
- taggableComplete
- aNavigation
- default
- aAdmin
Apostrophe edits rich text content via the FCK editor. A recent version of FCK is
included with the plugin. However you'll need to enable FCK in your settings.yml file, as follows:
all:
rich_text_fck_js_dir: apostrophePlugin/js/fckeditor
Now, load the fixtures for a basic site. Every site begins with a home
page with all other pages being added as descendants of the home page:
./symfony doctrine:build --all
./symfony doctrine:data-load
#### .htaccess Rules For Media ####
The media module of Apostrophe uses carefully designed URLs to allow images to be
served as static files after they are generated for the first time. This
is done at the Apache level to maximize performance: PHP (and therefore
Symfony) don't have to get involved at all after the first time an image
is rendered at a particular size.
The following special .htaccess rules are required to enable this. These
should be copied to your .htaccess file after the
`RewriteBase /` rule, if you are using one, but before any other rules.
###### BEGIN special handling for the media module's cached scaled images
# If it exists, just deliver it
RewriteCond %{REQUEST_URI} ^/uploads/media_items/.+$
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .* - [L]
# If it doesn't exist, render it via the front end controller
RewriteCond %{REQUEST_URI} ^/uploads/media_items/.+$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
###### END special handling for the media module's cached scaled images
#### Routing Rules ####
By default Apostrophe will map CMS pages to URLs beginning with `/cms`:
/cms/pagename
And leave all other URLs alone. This is appropriate if the CMS is a minor part of your site. If the CMS is the main purpose of your site, shut off the automatic registration of the route above:
a:
routes_register: false
And register these as the LAST rules in your application's `routing.yml` file instead:
# A default rule that gets us to actions outside of the CMS.
# Note that you can't have CMS pages with a slug beginning with /admin
# on a site that uses this particular rule. You could use a
# different prefix. Or you could provide rules for every
# module, or even for every action. This is just the simplest way.
default:
url: /admin/:module/:action/*
# A homepage rule is expected by a and various other plugins,
# so be sure to have one
homepage:
url: /
param: { module: a, action: show, slug: / }
# Put any routing rules for other modules and actions HERE,
# before the catch-all rule that routes URLs to the
# CMS by default.
# Must be the last rule
a_page:
url: /:slug
param: { module: a, action: show }
requirements: { slug: .* }
Thanks to Stephen Ostrow for his help with these rules.
#### Enhanced Form Controls ####
To get the benefit of the progressively enhanced form controls
featured in our admin tools, you'll need to add apostrophePlugin's
aControls.js to your view.yml file:
default:
... Other things ...
javascripts: [/apostrophePlugin/js/aControls.js]
We're done installing Apostrophe! On to the editor's guide, which briefly explains how to edit content with Apostrophe- briefly because it is so much more fun to simply use it.
## Editor's Guide ##
This section is devoted to users who will participate in editing, maintaining and administering the content of the site. All of these tasks are performed through your web browser. No command line skills are required.
Access your new Apostrophe site's URL to see the home page.
Click "log in" and log in as the admin user (username admin, password demo)
to see the editing controls. Notice that editing controls are added to the normal experience of the site. This greatly reduces the learning curve for editors.
### Managing Pages ###
When a user has appropriate privileges on a page, they are able to make
the following changes via a simple "breadcrumb trail" that appears at the top of the page:
* Rename the page by clicking on the page title
* Add a child page beneath the current page
* Open the page management settings dialog via the "gear" icon
for less frequent changes
Apostrophe emphasizes "unpublishing" pages as the preferred way
of "almost" deleting them because it is not permanent. Anonymous users, and users who do not
have editing privileges on the page, will see the usual 404 Not Found error.
But users with suitable editing privileges will see the page with its title
"struck through" and will be able to undelete the page if they desire. This prevents the loss of content.
You can also delete a page permanently via the small X in the lower right
corner of the page settings dialog. Most of the time that's a shortsighted
thing to do, but it is useful when you create an unnecessary page by accident.
The side navigation column also offers an editing tool: users with
editing privileges can change the order of child pages listed there
by dragging and dropping them. (If a page has no children, the side
navigation displays its peers instead, including itself.) You can do the same thing with the tabs at the top of the page. Also check out the "Reorganize" button, which is discussed in more detail later.
### Editing Slots ###
What about the actual content of the page? The editable content
of a page is stored in "slots" (_note to developers: not the same thing as Symfony slots_).
CMS slots can be of several types:
* Plaintext slots (single line or multiline)
* Rich text slots (edited via FCK)
* Feed slots (RSS or Atom feeds, such as Twitter feeds, inserted into a page)
* Raw HTML slots (best avoided in good designs, but useful when you must paste raw embed codes)
* Media slots (image, slideshow, video, PDF, button)
* Custom slots (of any type, implemented as described in the developer's guide section)
Once you have logged in, you'll note that each editable slot has an "Edit" button or, in the case of the media slots, "Select Image" and similar buttons.
Every slot also offers version control. The arrow-in-a-circle icon
accesses a dropdown list of all changes that have been made to that slot,
labeled by date, time and author and including a short summary of the change
to help you remember what's different about that version. Pick any version to preview it. Click "Save as current version" to permanently revert to that version.
### Editing Areas ###
In addition to single slots, apostrophePlugin also supports
"areas." Areas are vertical columns containing more than one slot.
Editing users are able to add and remove slots from an area at any time,
selecting from a list of slots approved for use in that area. The slots
can also be reordered via up and down arrow buttons (used here instead
of drag and drop to avoid possible browser bugs when dragging and dropping
complex HTML, and because drag and drop is not actually much fun to use
when a column spans multiple pages).
The usefulness of areas becomes clear when rich text slots are interleaved with media slots. Media slots provide a robust way to manage photos and videos without wrecking the layout of the site. You can upload photos and select and embed videos freely without worrying about their size and format.
### Revising History ###
Did you make a mistake? Not a problem! Both slots and areas allow you to roll back to any previous edit. Just click "History," preview versions by clicking on them, and click "Save As Current Revision" when you find the version you want.
### Editing Media ###
Click "Add Slot," then "Image," then "Select Image." You will be taken to the media area of the site.
Here you can select any of the images that have already been uploaded to the site, or upload new images. This media repository provides a clean way to keep track of the media you have available.
You can do much the same thing with video. YouTube is tightly integrated with Apostrophe, and you can easily search YouTube from within the media interface. You can also paste embed codes from other sites and add thumbnail images for those videos manually.
You can organize media with categories and tags. Add new categories using the "Manage Categories" button at the left, in the media browser area.
It's possible to add a media page to the public-facing part of the site that displays only media in certain categories. To do that, go to the home page, add a new page and give it a title that relates to a media category. When the new page appears, click the gear icon. When the page settings dialog appears, select "Media" from the "Page Engine" menu.
Once you select Media, a category selector will appear. Pick the appropriate category, then click Save. Note that you can select more than one category.
The page will now refresh and display a media browser that anyone on your site can use to see media in that category, most recent first, with all of the browsing features that are standard in the media area.
### Reorganizing the Site ###
Apostrophe offers drag-and-drop reordering of the children of
any page via the navigation links on the left-hand side. You can also reorder the tabs at the top of any page by dragging and dropping.
However, there are times when you want to do something less linear, like moving a page up or down in the page tree.
To do that, click on the "Reorganize" button at the top of any page. This will take you to the reorganize tool, a page where you can drag and drop pages to any position in the page tree for quick and painless reorganization of the site.
This tool is only available to site administrators such as the `admin` user.
## Designer's Guide ##
This section explains how to go about customizing the appearance and behavior of the site without writing new code (apart from simple calls to insert slots and otherwise use PHP as a templating language). It is intended to be read by front end designers (also known as front end developers).
Some familiarity with Symfony is expected. You will need to edit files like `apps/frontend/config/app.yml` to adjust settings, and you will be creating `.php` files although full PHP programming skills are not required.
### Title Prefix ###
By default, the title element of each page will contain the title of that page.
In many cases you'll wish to specify a prefix for the title as well.
You can do so by setting `app_a_title_prefix` in `app.yml`. This option supports
optional internationalization:
all:
a:
# You can do it this way...
title_prefix:
en: 'Our Company : '
fr: 'French Prefix : '
# OR this way for a single-culture site
title_prefix: 'Our Company'
Note that all changes to `app.yml` should be followed by a `symfony cc` command:
./symfony cc
### Creating and Managing Page Templates and Layouts ###
Where do slots appear in a page? And how do you insert them?
Slots can be inserted in two places: in your site's <tt>layout.php</tt>
file, which decorates all pages, and in page template files, which can
be assigned to individual pages.
### How to Customize the Layout ###
By default, the CMS will use the
<tt>layout.php</tt> file bundled with it. If you wish, you can turn this
off via app.yml:
all:
a:
use_bundled_layout: false
CMS pages will then use your application's default layout. One strategy
is to copy our <tt>layout.php</tt> to your application's template folder
and customize it there after turning off use_bundled_layout.
### How to Customize the Page Templates ###
The layout is a good place for global elements that should appear on
every page. But elements specific to certain types of pages are better
kept in page templates. These are standard Symfony template files with
a special naming convention.
Page template files live in the templates folder of the a module.
We provide these templates "out of the box:"
* homeTemplate.php
* defaultTemplate.php
homeTemplate.php is used by our default home page, and defaultTemplate.php
is the default template if no other template is chosen.
You can change the template used by a page by using the
template dropdown in the breadcrumb trail. This does not delete
the slots used by the previous template, so you can switch back
without losing your work.
How do you create your own template files? *Don't* alter the templates
folder of the plugin. As always with Symfony modules, you chould
instead create your own a/templates folder within your
application's modules folder:
mkdir -p apps/frontend/modules/a/templates
Now you can copy homeTemplate.php and defaultTemplate.php to this folder,
or just start over from scratch. You can also copy _login.php if you don't
like the way we present the login and logout options. The same applies
to _tabs.php and _subnav.php. We *do not recommend* altering the rest of the templates unless
you have a clear understanding of their purpose and function and are
willing to make ongoing changes when new releases are made. In general,
if you can use CSS to match the behavior of our HTML to your needs,
that will be more forwards-compatible with new releases of the CMS.
If you add additional template files, you'll need to adjust
the `app_a_templates` setting in `app.yml` so that your
new templates also appear in the dropdown menu:
all:
a:
templates:
home:
Home Page
default:
Default Page
mytemplate:
My Template
### Custom Navigation in Templates and Layouts ###
Apostrophe supports three types of navigation components. These can be found in the aNavigation module. Including these navigation elements is as easy as including a component in your template or in `layout.php`. The three types of navigation elements are:
* An accordion tree
* A tabbed or vertical menu of links to child pages
* A breadcrumb trail from the home page to the current page.
The navigation element, once used, will no longer require any additional SQL queries no matter how many similar navigation elements are included in a template or layout.
#### Accordion Navigation ####
Accordion-style navigation can be easily included in your template by doing the following. Accordion navigation is a compromise between showing the entire page tree and showing just the breadcrumb. Accordion navigation includes everything that would be included in a breadcrumb trail, plus the peers of all of those pages. This makes it easy to navigate to related pages at any level without being overwhelmed by a comprehensive list of all pages on the site. These links are rendered as nested `ul` elements.
<?php include_component('aNavigation', 'accordion', array('root' => '/', 'active' => $page->slug, 'name' => 'normal')) ?>
Parameters
* root (required) - This is the slug of the root page that the menu should start from. Often the home page
* active (required) - The page to build the navigation down to, will also recieve a css class of current
* name (required) - The unique name of the navigation element for your template. This influences CSS IDs and can be used for styling
#### Tabbed Navigation ####
The tabbed navigation provides a navigation element that displays all of the children of a page. Note that depending on your CSS you can render it as a vertical menu. For an example, see the "subnav" area of the `asandbox` project; see `a/templates/_subnav.php).
<?php include_component('aNavigation', 'tabs', array('root' => '/', 'active' => $page->slug, 'name' => 'tabs')) ?>
Parameters
* root (required) - This is the parent slug of the tabs that are displayed.
* active (required) - This is the page that if in the navigation will recieve a current css class of current
* name (required) - the unique name of the navigation element for your template.
#### Breadcrumb ####
<?php include_component('aNavigation', 'breadcrumb', array('root' => '/', 'active' => $page->slug, 'name' => 'bread')) ?>
Parameters
* root (required) - This is the root slug of the page the breadcrumb should begin with. Usually the home page
* active (required) - This is the last element that the navigation should descend to. Usually the current page
* separator (optional) - The separator to use between items, defaults to " > "
* name (required) - the unique name of the navigation element for your template.
### Inserting Slots in Layouts and Templates ###
Of course, creating layouts and templates does you little good if you
can't insert user-edited content into them. This is where the
CMS slot helpers come in.
Here's how to insert a slot into a layout or page template:
<?php # Once at the top of the file ?>
<?php use_helper('a') ?>
<?php # Anywhere you want a particular slot ?>
<?php a_slot('body', 'aRichText') ?>
Notice that two arguments are passed to the <tt>a_slot</tt>
helper. The first argument is the name of the slot, which distinguishes
it from other slots on the same page. *Slot names should contain only
characters that are allowed in HTML ID and NAME attributes*. We recommend
that you use only letters, digits, underscores and dashes in slot names.
The slot name will never be seen by the user. It is a useful label
such as `body` or `sidebar` or `subtitle`.
The second argument is the type of the slot. "Out of the box,"
apostrophePlugin offers a useful array of slot types:
* aText (plaintext)
* aRichText (allows WYSIWYG formatting)
* aFeed (brings any RSS or Atom feed into the page)
* aImage (still images from the media repository)
* aSlideshow (a series of images from the media repository)
* aButton (an image from the media repository, and an editor-configurable link)
* aVideo (video from YouTube and other providers)
* aPDF (PDF documents from the media repository)
* aRawHTML (Unfiltered HTML code)
The use of these slots is largely self-explanatory and we encourage you to play with the demo and try them out.
You can add additional slot types of your own and release and
distribute them as plugins as explained in the developers' section in this document.
#### aText Slots ####
aText slots contain only plaintext (actually, valid HTML text, which can include valid HTML and UTF-8 entities). URLs are automatically rendered as links, email addresses are rendered as obfuscated `mailto:` links, and newlines are rendered as line breaks.
Note that the special slot name `title` is reserved for the title of the page
and is always of the type `aText`. While you don't really need to provide an additional editing interface for the title, you might also want to insert it as an `h1` somewhere in your
page layout or template as a design element:
<h1>
<?php a_slot('title', 'aText') ?>
</h1>
The behavior of most slot types can be influenced by passing options to them from the template or layout. You do this by passing an array of options as a third argument
to the helper, like this:
<h1>
<?php a_slot('aboutus', 'aText', 'multiline' => true) ?>
</h1>
The `multiline` option specifies that a plaintext slot should permit multiple-line text input.
#### aRichText Slots ####
Here is a simple example of a rich text slot:
<?php a_slot('ourproducts', 'aRichText') ?>
The rich text slot allows users to edit content using a rich text editor. The HTML they enter is filtered for correctness and to ensure it does not damage your design. Read on for more information about ways to adjust these filters.
The `tool` option is one of the most useful options for use with rich text slots:
<h2>
<?php a_slot('subtitle', 'aRichText',
array('tool' => 'basic')) ?>
</h2>
Here we create a subtitle rich text slot on the page which is editable, but only
with the limited palette of options provided in FCK's `basic` toolbar (bold, italic and links).
Note that you can create your own custom toolbars for the FCK rich text editor. Add these to `web/js/fckextraconfig.js` and they will be found automatically. Here is an example:
FCKConfig.ToolbarSets["Sidebar"] = [
['Bold','Italic']
] ;
For more complete examples of what can be included here, see `apostrophePlugin/web/js/fckeditor/fckconfig.js`. (You do not need to, and should not, duplicate this entire file in `fckextraconfig.js`. Just add and override things as needed.)
Other notable options to `aRichText` slots include:
* allowed-tags is a list of HTML elements to be permitted inside the rich text. By default Apostrophe filters out most HTML elements to prevent pasted content from Microsoft Word and the like from wrecking page layouts. You can pass an array of HTML element names (without angle brackets), or a string like that accepted by the PHP `strip_tags` function.
This allows us to write a better version of the `subtitle` slot above that filters the HTML to make sure it's suitable to appear inside an `h2` element:
<h2>
<?php a_slot('subtitle', 'aRichText',
array('tool' => 'basic', 'allowed-tags' => '<b><i><strong><em><a>')) ?>
</h2>
Note that we list both the `b` tag and the `strong` tag here. We do this because different browsers submit slightly different rich text.
The default list of allowed tags is:
`h3, h4, h5, h6, blockquote, p, a, ul, ol, nl, li, b, i, strong, em, strike, code, hr, br, div, table, thead, caption, tbody, tr, th, td, pre`
* allowed-attributes is a list of HTML attributes to be accepted, on a per-element basis. Unlike `strip_tags` Apostrophe's robust, high-performance HTML filter, `aHtml::simplify`, removes all inappropriate HTML attributes. Here is the default list of allowed attributes:
array(
"a" => array("href", "name", "target"),
"img" => array("src")
);
* allowed-styles is a list of CSS style names to be permitted, again on a per-element basis. By default, no styles are permitted in rich text editor content. You can alter this to allow more creative table styling, at the cost that a truly persistent user might manage to wreck the page layout. The format is the same as that used above for allowed attributes.
#### aFeed Slots ####
The aFeed slot allows editors to insert an RSS feed into the page:
<h2>
<?php a_slot('subtitle', 'aFeed') ?>
</h2>
When the user clicks "Edit," they are invited to paste an RSS feed URL. When they click "Save," the five most recent posts in that feed appear. The title of each feed post links to the original article on the site of origin as specified by the feed.
You can change this behavior with the following options. The defaults are shown as examples:
* `'links' => true` determines whether links to the original posts are provided.
* `'dateFormat' => 'Y m d'` lets you specify your own date and time format (see the PHP date() function). 'Y m d' is not actually our default, as our default is more subtle than can be output with the date function alone (we include the year only when necessary and so on). Our default is very nice, but very American, so feel free to override it.
* `'markup' => '<strong><em><p><br><ul><li>'` changes the list of HTML elements we let through in markup. We apply our usual aHtml::simplify() method, which is smarter than PHP's `strip_tags` alone.
* `'interval' => 300` specifies how long we hold on to a feed before we fetch it again. This is important to avoid slowing down your site or getting banned by feed hosts. We rock Symfony's caching classes to implement this. Check out aFeed::getCachedFeed if you're into that sort of thing.
* `'posts' => 5` determines how many posts are shown.
#### aImage Slots ####
Image slots are used to insert single still images from Apostrophe's built-in media repository:
<?php a_slot('landscape', 'aImage') ?>
Options are available to control many aspects of image slots:
* `'width' => 440` determines the width of the image, in pixels. Images are never rendered larger than actual size as upsampling always looks awful.
* `'height' => 330` determines the height of the image, in pixels. It is ignored if `flexHeight' => true is also present.
* `'resizeType' => 's'` determines the scaling and cropping style. The `s` style scales the image down if needed but never changes the aspect ratio, so the image is surrounded with white bars if necessary (see `flexHeight` for a way to avoid this). The `c` style crops the largest part of the center of the image that matches the requested aspect ratio.
* `'flexHeight' => false` determines whether the height of the image is scaled along with the requested width to maintain the aspect ratio of the original. Set this option to `true` to scale the height.
* `'defaultImage' => false` allows you to specify the URL of an image to be displayed if no image has been selected by the editor yet. Otherwise no image is displayed until an editor chooses one.
* `'title' => false` specifies whether the title associated with the image in the media repository should be shown on the page. CSS can be used to display this title in a variety of interesting ways.
* `'description' => false` specifies whether the rich text description associated with the image in the media repository should be shown on the page.
* `'link' => false` specifies a URL that the image should link to when clicked upon. Note that in most cases you probably want to use an aButton slot for this sort of thing.
These options suffice for most purposes. There is one more option, `constraints`, which takes an array of constraints that can be used to limit which images the user can select from the media repository. By default no constraints are applied. The possible constraints are:
* 'aspect-width' and 'aspect-height' specify an aspect ratio. The media browser will show only media that match this aspect ratio. Both must be specified. For instance:
'constraints' => array('aspect-width' => 4, 'aspect-height' => 3)
* 'minimum-width' and 'minimum-height' specify minimum width and height in pixels. Only media meeting these minimum criteria will be shown. You are not required to use both options although it usually makes sense to specify both.
* 'width' and 'height' specify that only images of that **exact** width and/or height should be selectable for this image slot. It is not mandatory to specify both, and if you are using `flexHeight` you might not want to specify a height constraint.
Here are three examples:
This slot will render the image 400 pixels wide. The original must be at least 400 pixels wide. The height will scale along with the width.
<?php a_slot('landscape', 'aImage', array('width' => 400, 'flexHeight' => true, 'constraints' => array('minimum-width' => 400))) ?>
This slot will be render images at 640x480 pixels. The original must be at least 640 pixels wide. The aspect ratio must be 4x3.
<?php a_slot('landscape', 'aImage', array('width' => 640, 'height' => 480, 'constraints' => array('minimum-width' => 640, 'aspect-width' => 4, 'aspect-height' => 3))) ?>
This slot will crop the largest portion of the center of the selected image with a 400x200 aspect ratio and scale it to 400x200 pixels. The selected image must be at least 400 pixels wide.
<?php a_slot('landscape', 'aImage', array('width' => 400, 'height' => 200, 'resizeType' => 'c', 'constraints' => array('minimum-width' => 400))) ?>
#### aSlideshow Slots ####
Slideshow slots allow editors to select one or more images and display them as a slideshow. The exact behavior of the slideshow can be controlled by various options.
Here is a simple example:
<?php a_slot('travel', 'aSlideshow') ?>
By default users can select any images they wish and add them to the slideshow, and the slideshow will advance when they click on an image. Left and right arrows to move back and forward in the slideshow appear above the image unless turned off by the `arrows` option.
Slideshows with images of varying dimensions can be confusing to look at unless the aspect ratio is the same. Fortunately slideshows support all of the sizing, cropping and constraint options that are available for the aImage slot (see above). We recommend either using `resizeType => 'c'` to crop to a consistent size (and therefore aspect ratio) or using the `aspect-width` and `aspect-height` parameters to the `constraints` option to ensure a consistent aspect ratio.
**In addition to all of the options supported by the aImage slot** (see above), slideshow slots support the following additional options:
* `'random' => false` determines whether the slideshow is shown in the order selected by the editor or in a random order. Set this option to `true` for a random order.
* `'arrows' => true` indicates that arrows to move forward and backward in the slideshow should appear above the image. By default they do appear. You can turn this off by passing `false`.
* `'interval' => false` sets the interval for automatic advance to the next image in the slideshow. By default the slideshow does not advance automatically. For automatic advance every ten seconds pass `'interval' => 10`. Slideshows automatically repeat once they have advanced to the final image. If the user clicks on the slideshow, auto-advance stops, and the user can navigate manually by clicking to advance or using the arrows if present.
* `'credit' => false` determines whether the credit field from the media repository is shown with each image.
#### aButton Slots ####
Button slots are similar to image slots. However, they also allow the editor to specify a target URL and a plaintext title. When they click on the button, they are taken to the URL.
Here is an example:
<?php a_slot('logo', 'aButton') ?>
Button slots support all of the options supported by the aImage slot (see above). In particular you might want to specify a default image.
If the title and/or description options are turned on, they are rendered as links to the button's destination URL.
#### aVideo Slots ####
The aVideo slot allows video to be embedded in a page.
Apostrophe's media repository does not store video directly. Instead Apostrophe manages videos hosted on external services such as YouTube, Viddler and Vimeo. YouTube is tightly integrated into Apostrophe, so editors can search YouTube directly from the repository in order to easily add videos. Embed codes for other video services can also be added to the media repository. Either way, Apostrophe wrangles the necessary embed codes and ensures that they render at the desired size.
Here is an example:
<?php a_slot('screencast', 'aVideo') ?>
** The video slot supports all of the options supported by the image slot** (described above), with the following differences and exceptions:
* The `width` option defaults to 320 pixels.
* The `height` option defaults to 240 pixels.
* The `resizeType` option is ignored. As a general rule video hosting services do not permit cropping and choose their own approaches to letterboxing. We recommend using the `flexHeight` option if there is any doubt about the dimensions of the video.
* The `constraints` option is supported. The constraints will be applied based on the dimensions of the original video (if from YouTube). For videos from other hosting services (pasted as embed codes in the media repository) constraints are based on the dimensions of the thumbnail manually uploaded by the editor.
* The `link` and `defaultImage` options are not supported.
#### aPDF Slots ####
The aPDF slot allows PDF documents to be embedded in a page. If ghostscript and netpbm are installed on the server, thumbnail previews of the first page are automatically displayed in PDF slots, and clicking on them launches the PDF. If they are not available, a clickable PDF icon is still displayed as a way of launching the PDF.
aPDF slots support the following options, which behave as they do for the aImage slot (described above):
* The `width` option defaults to 170 pixels.
* The `height` option defaults to 220 pixels.
* The `flexHeight` option is available to scale the thumbnail based on the page size, although this is only relevant if netpbm and ghostscript are available.
* The `defaultImage` option is available. The default image appears when no PDF has been selected yet.
* The `constraints` option is available, and can be used to select only PDFs with a certain aspect ratio, such as 8.5x11 (use the aspect-width and aspect-height parameters). This option should not be used when netpbm and ghostscript are not available as the true size of the PDF is not known in this case.
#### aRawHTML Slots: When You Must Have Raw HTML ####
Honestly, we're not big fans of raw HTML slots. Editors tend to paste code that breaks page layouts on a fairly regular basis. That's why our rich text slots filter it so carefully.
However there are times when you must have the embed code for a mailing list signup form service or similar third-party website feature.
In these situations the aRawHTML slot is useful.
Here is an example:
<?php a_slot('mailinglist', 'aRawHTML') ?>
This slot displays a multiline text entry form where the editor can paste in HTML code directly. This code is not validated in any way, so you should think carefully before offering this feature to less experienced editors.
There is a way to recover if you paste bad HTML that breaks the page layout. Visit the page with the following appended to the URL:
?safemode=1
When this parameter is present in the URL, raw HTML slots will escape their contents so that you see the source code, safely defanged. You can then click "Edit" and make corrections as needed.
That's it for the standard slots included with Apostrophe! Of course there will be more. And you can add more yourself. See the developer's section of this document.
### Inserting Areas: Unlimited Slots in a Vertical Column ###
Slots are great on their own. But when you want to mix paragraphs of text with
elements inserted by custom slots, it is necessary to create a separate
template file for every page. This is tedious and requires the
involvement of an HTML-savvy person on a regular basis.
Fortunately apostrophePlugin also offers "areas." An
area is a continuous vertical column containing multiple slots which
can be managed on the fly without the need for template changes.
You insert an area by calling a_include_area($name) rather than
a_include_slot($name):
<?php a_include_area("sidebar") ?>
When you insert an area you are presented with a slightly different
editing interface. At first there are no editable slots in the area.
Click "Insert Slot" to add the first one. You can now edit that
first slot and save it.
Add more slots and you'll find that you are also able to delete them
and reorder them at will.
By default new slots appear at the top of an area. If you don't like this,
you can change it for your entire site via `app.yml`:
all:
a:
new_slots_top: false
An area has just one version control button for the entire area. This
is because creating, deleting, and reordering slots are themselves
actions that can be undone through version control.
In a project with many custom slot types, you may find it is
inappropriate to use certain slot types in certain areas. You can
specify a list of allowed slot types like this:
<?php a_include_area("sidebar",
array("allowed_types" => array("aText", "myCustomType"))) ?>
Notice that the second argument to `a_include_area` is an
associative array of options. The `allowed_types` option allows us to
specify a list of slot types that are allowed in this particular area.
In addition, you can pass options to the slots of each type, much as
you would when inserting a single slot:
a_include_area("sidebar",
array("allowed_types" => array("aText", "myCustomType"),
"type_options" => array(
"aText" => array("multiline" => 1))));
Here the `multiline` option specifies that all
`aText` slots in the area should have the
`multiline` option set.
### Global Slots and Virtual Pages ###
Most of the time, you want the content of a slot to be specific to a page.
After all, if the content was the same on every page, you wouldn't need
more than one page.
However, it is sometimes useful to have editable content that appears
on more than one page. For instance, an editable page footer or page
subtitle might be consistent throughout the site, or at least throughout
a portion of the site.
The quickest way to do this is by adding a "global slot" to your page template or layout.
Just set the `global` option to `true` when inserting the slot:
<h4>
<?php a_slot('footer', 'aRichText',
array('toolbar' => 'basic', 'global' => true)) ?>
</h4>
The content of the resulting slot is shared by all pages that include
it with the `global` option.
Note that you can use the `global` flag with areas as well as slots:
<?php a_area('footer', array(
'allowed_types' => array('aRichText', 'aImage'),
'global' => true
)) ?>
By default, global slots can be edited only by users with editing
privileges throughout the site. Otherwise users with control only over
a subpage could edit a footer displayed on all pages. See below for more information about
how to override this rule where appropriate.
#### Virtual Pages: When Global Slots Are Not Enough ####
Global slots will do the job for most situations that front end developers will encounter. If you're not a PHP developer looking to use slots and areas to manage dynamic content related to your own code, it's probably safe to skip this section, although it is sometimes useful to apply these techniques if you would otherwise have hundreds of global slots in your design.
Conceptually, all global slots reside together on a virtual page with the slug `global`. Since there is no leading `/`, this page can never be navigated to. The `global` virtual page resides outside of the site's organizational tree and is used only as a storehouse of shared content.
For headers and footers, this works very well. But if you have a larger amount of shared content, the model begins to break down. Fortunately there's a solution: group your content into separate virtual pages.
When you include a slot this way:
<h4>
<?php a_slot('biography', 'aRichText', array('toolbar' => 'basic', 'slug' => "bio-$id")) ?>
</h4>
You are fetching that slot from a separate virtual page with the slug `bio-$id`, where `$id` might identify a particular user in the `sfGuardUser` table.
Apostrophe will automatically create the needed virtual page object in the database the first time the slot is used. This technique can be used for areas as well.
But why is this better than using `'global' => true`? Two reasons: performance and access control.
#### Performance, Global Slots and Virtual Pages ####
Yes, you could manage dynamic content like biographies with just the global flag, if you chose dynamically generated names for your slots and areas. But since Apostrophe loads all current global slots into memory the first time a global slot is requested on a page, the CMS would be forced to load all of your biographies on just about every page of the site. That's clearly not acceptable. For that reason it's important to use a separate virtual page for each individual's biography, etc.
As a rule of thumb, add database IDs to virtual page slugs, not area or slot names.
#### Access Control For Global Slots and Virtual Pages ####
By default, only sitewide admins can edit slots included from other virtual pages. This is fine for headers and footers seen throughout the site, but doesn't work well for biography slots. In other words, users should be able to write their own autobiographies.
You can address this problem by passing `'edit' => true` as an option to the slot or area. This overrides the normal slot editing privilege checks, so you should do this only if the user ought to have the privilege according to your own judgment. For instance, you might do something like this:
<?php $myid = sfContext::getInstance()->getUser()->getGuardUser()->id ?>
<h4>
<?php a_slot('biography', 'aRichText', array('toolbar' => 'basic', 'slug' => "bio-$id", 'edit' => $id === $myid)) ?>
</h4>
Once again, you can do this with areas as well.
#### Including Slots From Other "Normal" Pages ####
It's possible to use the `slug` option to include a slot from another normal, navigable page on the site. However, if you do so, keep in mind that you don't want to create a situation where the same slot is included twice on the page itself.
Also keep in mind that normal pages can be moved around on the site, which will break templates that contain explicit slugs pointing at their old locations. You can avoid this by determining the slug option dynamically, or by using a virtual page instead (no leading / on the slug).
### CSS: Styling Apostrophe ###
By default, `apostrophePlugin` provides two stylesheets which are
automatically added to your pages. There's a lot happening there,
particularly with regard to the editing interface, and we recommend
that you keep these and override them as needed in a separate
stylesheet of your own. However, you can turn them off if you wish
in `app.yml`:
all:
a:
use_bundled_stylesheet: false
If you do keep our stylesheets and further override them, you'll
want to specify `position: last` for the stylesheets that should
override them. This is automatically done for the stylesheet
`web/css/main.css` in our sandbox project, and we recommend you
make your customizations there.
#### The Golden Rule: Use Classes, Not IDs ####
You may want to style individual areas and slots without introducing
wrapper divs to your templates. To do that, pay attention to the CSS
classes we output on the outermost wrappers of each area. You'll note
that standalone slots still have an area wrapper in order to implement
their editing controls and make it easier to write consistent CSS:
<div id="a-area-12-body" class="a-area a-area-body">
You may be tempted to use the `id` attribute. *Don't do that.* The id attribute contains the page ID, which differs from page to page and should never be used in CSS.
Instead, take advantage of the classes on this div:
.a-area-body
{
css rules specific to the area or slot named 'body'
}
Note that if you need different behavior on different pages in a way that can't be achieved by adding different slots and using different variants of each slot, you should use a separate template for each type of page.
### Access Control: Who Can Edit What? ###
By default, an unconfigured Apostrophe site that was not copied from our sandbox follows these security rules:
* Anyone can view any page without being authenticated.
* Any authenticated (logged-in) user can edit any page,
and add and delete pages.
This is often sufficient for simple sites. But Apostrophe can
also handle more complex security needs.
### Requiring Login to Access All Pages ###
To require that the user log in before they view any page
in the CMS, use the following setting in `app.yml`:
all:
a:
view_login_required: true
### Requiring Login to Access Some Pages ###
To require the user to log in before accessing a particular page,
just navigate to that page as a user with editing privileges
and click on the "lock" icon.
By default, locked pages are only accessible to logged-in users. Of course, on some sites this is too permissive, especially when users are allowed to create their own accounts without further approval. In such situations you can set up different credentials to access the pages. To require the `view_locked` credential to view locked pages, use the following app.yml setting:
all:
a:
view_locked_sufficient_credentials: view_locked
Then grant the `view_locked` permission to the appropriate sfGuard groups, and you'll be able to distinguish user-created accounts from invited guests.
### Requiring Special Credentials to Edit Pages ###
Editing rights can be controlled in several ways. It may seem a bit confusing, so keep in mind that the default set of permissions, groups and `app.yml` settings in our sandbox project works well and allows the admin to assign editing and managing privileges anywhere in the CMS page tree as they see fit. Editing privileges allow users to edit a page, while managing privileges allow them to also create and delete pages.
Read on if you believe you may need to override this configuration. You will need to do that if you are not using our sandbox project as a starting point, as the default behavior of the plugin is to allow any logged-in user to edit as they see fit (often quite adequate for small sites without unprivileged user accounts).
Editing and managing privileges are granted as follows:
1) Any user with the `cms_admin` credential can always
carry out any action in the CMS, regardless of all other settings. Note that the
sfGuard "superadmin" user always has all credentials.
2) Any user with `edit_sufficient_credentials` can always edit
pages (but not necessarily add or delete them) anywhere on the site. For instance,
if you add such users to the `executive_editors` sfGuardGroup and grant that
group the `edit` permission, then you can give them
full editing privileges with these settings:
all:
a:
edit_sufficient_credentials: edit
*If you do not specify any editing credentials at all, then any logged-in user can edit anywhere.* This is useful for small sites.
Similarly, any user with `manage_sufficient_credentials` can always
add or delete pages anywhere on the site, in addition to editing content. So
complete settings might be: