Elefant PHP Content Management System

Meet Sitellite's successor: Elefant CMS

A modern PHP framework and content management system based on the improved features of PHP 5.3+. Elefant is an extremely fast and easy to use CMS that inherits all the best of Sitellite, without the fat. Learn more »


Component Overview

Audience

This lesson is intended for programmers. It covers the information necessary to get started hacking on the Sitellite core source code.

Obtaining the source

Sitellite's source code is managed using the Git distributed version control system, and the Sitellite source code is stored at the following location:

If you're looking to make changes to Sitellite, your best bet is to install Git and then fork the Sitellite project on GitHub. GitHub makes it easy to send your changes back to the main project codebase afterwards using what they call a "pull request", and by forking you can easily make small or large-scale changes over time in a controlled manner.

I won't cover too much about using Git and GitHub here, since their website provides many guides for learning those tools already.

 

Keeping in sync

Since your project now contains a complete duplicate of the original Sitellite codebase, you will want to be able to merge future changes to Sitellite into your forked project as well. Git provides a straight-forward way of accomplishing this via the "git remote" command.
git remote add core git://github.com/lux/sitellite.git
# fetch the core sources
git fetch core

# create a branch for the core sources
git checkout -b core core/master

# switch back to your master branch to merge changes
git checkout master

# merge the changes
git merge core

# commit the changes to your master branch
git commit -a -m "Updating core sources"

# push them to your github project
git push origin master
# switch to the core branch
git checkout core

# get the latest changes to core
git pull

Now just switch back to your master branch like before then merge and commit the changes.

Git is a very powerful versioning system and its commands can seem a bit daunting at first, but once you get used to the basics you'll be up to speed with it in no time.

Reporting bugs

Sitellite's issue tracking system is hosted by Lighthouse here:

You can browse existing bugs and feature requests here, or report your own by registering for an account.

Finding help

You can find help from other Sitellite developers and users in either of two places: The Sitellite community forum, and the new Sitellite email discussion group.

The forum is historically the place where discussion has occurred, but for Sitellite 5 we also created the email discussion group on Google Groups, in the hopes of providing a more flexible medium for discussions.

The following standards have been put in place to ensure a high level of quality throughout the Sitellite codebase. You are not required to follow these for your own projects, however if you intend to contribute your changes back into the Sitellite core, then the code must meet these standards as part of our quality assurance review process.

Why have coding standards?

Code conventions are important to programmers for a number of reasons:

  • 80% of the lifetime cost of a piece of software goes to maintenance.
  • Hardly any software is maintained for its whole life by the original author.
  • Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly. If you ship your source code as a product, you need to make sure it is as well packaged and clean as any other product you create.

Indentation and spacing

<?php

// query the database for some info
$result = db_fetch ('select * from some_table');

// check for errors
if (! $result) {
	trigger_error (db_error ());
}

// loop through and display the results
foreach ($result as $item) {
	echo template_simple ('some_template.spt', $item);
}

// let's concatenate a string.  note the ample space.
$a = 'one' . 'two';

?>
Tabs are preferred to spaces, because although most editors can be set to generate a set number of spaces when the Tab key is hit, I find backspacing to be inconsistent, and I don't like hitting backspace 4 times in a row. Tabs help preserve our fingers. Tab stops should be set at the equivalent of 4 spaces in your editor.

Code must be indented properly, as shown in the examples throughout this document.

Just remember, more space is better than less, so adding blank lines between structures, declarations, and such is highly encouraged.

Braces

Braces are always required.

The initial brace is always kept at the end of the line that initiates its block, as opposed to being on its own on the line below. This is the case consistently across conditional and looping structures, functions, classes, and anywhere else curly braces are used.

Naming

<?php

class NewClass {
	var $someProperty;

	function propertySetter ($value) {
		$this->someProperty = $value;
	}
}

function some_function () {
	// ...
}

?>
For global functions, we maintain the PHP style of using underscores to separate words in function names. However for necessarily long names for classes, methods, and properties (which should be generally avoided anyway) we use the Java way: countActiveUsers.

Note that under no circumstances do we Ever Capitalize Every Word Of Our Code Like Some Companies Do (VB Anyone?). This would be grounds for flogging, but instead we let the carpel tunnel take care of you instead. ;)

Private properties and methods should start with a single underscore (not two, as that has special meaning in PHP and could cause strange behaviour and/or naming conflicts). For example, $someObject->_privateMethod ().

Constants are always upper-cased, with underscores separating words. A constant defined in a specific class or package should be prefixed with that class or package name. For example, the saf.Template.Simple package defines a constant named SIMPLE_TEMPLATE_DELIM_CURLY.

Commenting

Comments should be liberal. Code should be written in such a way that it is self-explanatory. For code that is not so obvious, comments are required. For classes, PhpDoc-style documentation is required. A note on comment content: Try not to document how a block of code does something, but rather document what it does.
<?php

/**
 * This is a sample comment.
 *
 * @access public
 */
class Foo {
    /**
     * This is another sample.
     *
     * @access public
     */
    function bar ($asdf) {
        // This is an inline comment.
        echo $asdf;
    }
}

?>

PHP-Specific Issues

File names for PHP files should always end in .php, never .php3 or .php4. This is in the name of portability.

Full <?php open tags are absolutely required. This is fundamental to the portability of the software.

Platform-specific "tricks" (not that there are many in PHP) must be avoided unless absolutely necessary, in which case an Atticus Finch worthy argument must be made for them. This includes calling shell scripts that are only available on a Unix platform. This of course does not apply if your app is intended for a specific platform.

PHP extensions that are not available in a default PHP build must be avoided in the name of portability. This is a regretful thing, as there are some really useful non-default extensions available. For custom code, if the client's server environment will specifically support extra extensions, the use of such extensions is acceptable. This of course also does not apply to app writers, who have the choice of adding compatibility requirements (although we encourage app writers to try to meet the same level of compatibility as Sitellite itself.

Compatibility with a minimum PHP version must be maintained (usually two dot-releases behind the current stable release) in order to preserve portability. Major version number changes will be handled carefully as special cases.

Quality Assurance

All new code and bug fixes must be accompanied by proper documentation, which may often just be a verbose description in the CVS changelog.

phpt tests may be included as a separate file in saf/tests, which can be run as part of a centralized quality assurance process.

Miscellaneous

Files should always be saved with Unix line breaks, regardless of the platform.

example.com is the recommended URL to use for examples and documentation, as per RFC 2606. yourWebSite.com is also acceptable.

References

As far as PHP projects go, Sitellite is fairly large at over 300,000 lines of code. This chapter will break the codebase down into its different areas so you can more easily find what you're looking for when hunting down bugs or adding new features.

Sitellite's Standard Library

At the core of Sitellite is a collection of PHP classes. They vary in purpose from input handling and validation to database access to template parsing. They aren't all consistent, since Sitellite grew over a period of about 8 years already, and even PHP has changed quite a bit in that time. But to go back now and make everything consistent is not just impractical, but also wastes time that can be better spent moving forward. So we move forward instead.

The classes live in the "saf/lib" folder. You'll find the reference documentation for them here:

The core classes of interest to general Sitellite developers are saf.CGI, saf.Database, saf.Template.*, saf.Loader, saf.Misc.Document, saf.MailForm, and saf.I18n. There are others that are also handy too, but these are probably the most frequently used.

Template Engines

Sitellite contains two template engines, XT and SimpleTemplate, although only XT is required. The other is there as a convenience to app developers and is better suited for use in apps than for global design files. But if you prefer Smarty or another template language, feel free to include that in your custom apps and use that instead. Sitellite is not exclusionary at all of external libraries. In fact, we'd prefer to use external libraries wherever possible since that reduces development time.

XT Templates

The XT template engine (saf.XML.XT) is an XML-based template engine inspired by Zope's template engine. Since it's XML-based, templates must be valid XML and the output is syntactically valid but not semantically valid XHTML.

XT templates live in the inc/html folder in template sets. A template set is a collections of templates and related files (CSS, Javascript and images) that comprise a complete design for a site. Most sites only need one or two templates (global design and possibly a custom homepage look), but some use separate templates for each sub-section of a site.

SimpleTemplate

SimpleTemplate files live in the "html" sub-folder of an app. Their syntax is described elsewhere.

Configurations

The global configurations go in the "inc/conf" folder. Additional configurations related to sessions go in the "inc/sessions" folder, but these rarely change. The core configuration files are inc/conf/config.ini.php and inc/conf/cache.php. These files are now typically managed through the Control Panel > Admin menu in the Sitellite GUI instead of being edited directly.

An inc/conf/properties.php file can also contain global custom settings, which is usually only used on highly custom sites for preloading libraries before any template parsing has happened. A more extensible way of loading custom settings would be a good future feature...

Applications

Requests sent to Sitellite either call pages in the database or applications. All applications live in their own folders inside the "inc/app" folder, and apps are also broken down into numerous sub-folders described in the "Programming in Sitellite" lesson.

The 'index' File

All request parsing happens through Sitellite's "index" file. This is a PHP script minus the extension, but the .htaccess file clues Apache in so it's handled properly. This script loads all the necessary libraries automatically, checks whether a request should go to the cache or be dynamic, connects to the database, and builds the request based on the specified page or app request and output mode.

Historically, requests in Sitellite had an "/index/" prefix which called this file, but as of Sitellite 5 the default is to dynamically map requests to "index" via mod_rewrite and to leave that part out.

Those are all the major components of Sitellite, and should give you a good idea where to look to start hacking on your pet bug or new feature. Make sure to join the discussion and get involved – we're always eager for new help!