 |
|
Friday, April 22. 2005
I'll be documenting how to setup a Syntax CMS site and use it to build a simple blogging site. This post will focus on getting the framework up and running and future posts will be about setting up content types (data objects) to publish a blog. Some of this post is duplicative of the INSTALL intructions bundled with Syntax and I will not be going through all the details of setting everything up. Instead, I'll be trying to provide a practical look at what it takes to install and troubleshoot a new instance.
Web and Database setup
Of course, you'll need to have PHP4, Mysql and a webserver already setup before you proceed. We'll assume you have setup your apache server or a vrtual host that serves requests from directory called /var/www/htdocs/my_blog/public. You should also have downloaded the latest . Syntax CMS release 1.2.1.Extract the archive into the directory /var/www/htdocs/my_blog. Note that it will create both a private/ and public/ directory under my_blog. Syntax CMS is setup to keep configuration files, PHP libraries and classes, and any other code out of your document root. The public directory contains anything your site visitors will need to view your site - images, css, javascript, as well as the web-based Content Adminsitration application and developer tools.
The next step is to create our database and a user. From the mysql command line:
create database myblog;
grant all on myblog.* to myblogdb@localhost identified by 'secret';
You'll need to update the database connection parameters in private/config/db.conf.php to match the database name, host, user, and password used above. Next, from your my_blog directory, dump the database file to create and populate the necessary database tables:
mysql myblog < dump.sql
Testing and Troubleshooting
If you're web server and database are setup correctly, you can check your syntax settings by requesting the /admin/testing URL in your browser. You should see a page similar to the screenshot below. This script tests various components of the framework to make sure they are configured correctly. Pay attention to the boxes in red, they'll indicate something that is not set correctly and provide the fix for them.

Once you've quashed any warnings you have from the testing script, you're ready to start customizing Syntax CMS to behave like a blog. There is enough out-of-the-box functionality that at this point you could use it to serve up a basic website after customizing the section, header, and footer templates to match the look you want, but that is not the point of this overview.
In our next part, we'll look at Content Types - what they are and how to define them.
Friday, April 1. 2005
We came across an odd mod_rewrite behavior today that is worth documenting. Some of the code uses the environment variables SCRIPT_URI and SCRIPT_URL, which are supposed to be registerd by mod_rewrite. However, if you use the "RewriteEngine on" directive in .htaccess to enable rewrites but don't have a similar line in your apache configuration or vhost configuration block, rewrites will work but those variables will not be set.
Wednesday, February 23. 2005
Once Syntax 1.2 is released, some confusion may arise from two similar methods within the Section object. Remember, sections are essentially the pages on your site. With the nice cleanup of URL paths that Sandy worked on, sections now have a method called getUrlPath(). They have for some time now, had a method called getNavPath. So, what exactly is the difference and when do you use or need each one?
First, getUrlPath() returns the full, complete, and unique path to the section including it's root node. Typically, the root node is the homepage of your site and is named _home. A sample URL Path would be _home/about/contact_us. URL Paths can be used to get a section object by calling Section::getByUrlPath( _home/about/contact_us ).
In comparison, getNavPath() returns the part of the URL Path needed to navigate to a section on a web page. Essentially, it removes the root element for your site set by the constant NAV_ROOT_EL in config/static.conf.php. In the example above, calling getNavPath() for your section would return '/about/contact_us. To build a link to that page on a template, you'd use the following code:
echo "<a href=\"/section".$section->getNavPath()."\">"
Tuesday, January 18. 2005
Here is a quick example of how the Syntax API accelerates development by making it easy to search for a collection of objects. In this case, I had an array with some country info, including the name. I needed to see if any documents were tagged to that country:
Step one, figure out the numeric id of the country:
pxdb_import( 'content.output.pxdb_picktable' );
$country_picktable = new pxdb_picktable( 'country' );
$pick_id = $country_picktable->lookup_value( $country['name'] );
Step two, use a Document Collection to find matching records:
$documents = new DocumentCollection();
$documents->findByCountries( $pick_id );
$documents->execute();
If you use dbasis to generate the code for your abstract collection object, it will create methods for filtering/finding by any relationship or pick field in your object.
Thursday, December 23. 2004
I've checked into CVS, a new feature to the Syntax site administration application that automagically creates filters for working with content type lists. As your content repository grows, finding a specific record or set of records was only doable thorugh the search form. Now, in the left sidebar, syntax will provide a list of drop-down select menus based on the picklists used by the current datatype. You can also filter to show only approved or only unapproved records.
Besides the automatic generation of these, you can control the filters in two ways. You can suppress their appearance by setting a preference named 'admin_filters', using the content type integer id as the key and zero as the value. You can also specify which fields are used in the filters by creating a view called 'admin_filters' for a content type. Only picklist fields will be used so text or relationship fields added here are ignored. The image below shows the filters in action for an 'Organization' content type.

Wednesday, December 22. 2004
Syntax CMS comes with two very flexible Request handlers for routing incoming URLs. Which handler
is used is determined by the first directory in the url, i.e. http://www.example.com/section/
or http://www.example.com/content. Such requests are routed either to the section.php script
( via /section ) or to a capability of a registered module ( via /content ).
For a recent project, I needed to write a new Request handler, primarily to provide pages under a url first level
directory (/resource_centers) but also because I would need to provide a hierarchy of sections as well
as module calls all under one directory.
All a request handler does is tell syntax what php script to run, by returning
the full path to the script It could, therefore, return any sort of output to the browser/client - it
doesn't have to be a web page. These are the basic steps needed to implement your own
custom request handler.,
1. Directing your request
The first step is to route requests using mod_rewrite. You'll need to edit the .htacess file in
your public web documents root and add two rewrite rules.
RewriteRule ^resource_centers/(.+) /load.php?navtype=resource_center&request=$1 [L,QSA]
RewriteRule ^resource_centers/? /load.php?navtype=resource_center&request=$1 [L,QSA]
2. A class to handle it
When a request comes in, syntax looks for a class that extends the Request class. Save the new
file in your private/lib/syntaxcms/Request directory. The filename should be "Resource_centersRequest.class.php",
capitalize the first letter of your directory and append "Request.class.php" to it.
The class definition should look like:
require_once( dirname(_FILE_).'/Request.class.php' );
/**
Custom request class for handling resource centers
/
class Resource_CentersRequest extends Request
{
3. Implement getScript()
Now when syntax finds your request handler, it'll create an instance and try to call
a getScript method. This method takes no input and returns the path to the php script
that should be executed to handle the request. Since it extends the Request class, you
can use the getPathElement method to inspect the url path, 0 is the first element and so on.
You can also use the getVar method to get the value of GET/POST variables.
Monday, December 13. 2004
It'd be nice if a forms errors were listed as hyperlinks at the top to named anchors within the form. The message text would be the same but this way you click to jump down to the field that requires attention.
Monday, December 13. 2004
Syntax CMS has a flexible records privileges system in place that controls what users and groups can read and/or write a particular data record. As long as you use the pxdb_collections class to retrieve data, the appropriate sql and checks are added automatically. Through the Access Privileges tab in the Admin application, you can manually specify what groups can have read and/or write access to a specific record. For example, you could have a 'registered users' group that will have access to embargoed content on your site. To make sure only a logged in user in that group can see that record, you'd remove read access for the 'Everyone' group, and give read access to the 'registered users' group. On the front-end, Syntax CMS would take care of showing that record, in any collection or on a detail page, only to the 'registered users' group.
But, Syntax also assigns privileges automagically by default whenever a new record is entered. Here is how:
- The 'Everyone' group gets read privileges.
- If a user is logged in, then that user gets both read/write privileges to a record.
- The group id specified in the pxdb preference 'gid_admin' gets read/write privileges
This works fine most of the time. It'd be nice to have more control, maybe at the content type level, over if Everyone gets read access automatically or to specify additional groups that should get default read/write access to a content types's records.
Update: currently, only the admin group can see the 'Access Privileges' tab in the Admin application. Maybe we need to add a 'set_privileges' datatype priv and use that to test if a group can modify the record privileges.
To clarify, Syntax CMS has two levels of privileges. Datatype privs define what a group can do (add|edit|delete|approve) with a specific type of content ( ie documents|links|events). Record privs define what a user or group can do with a specific instance of a content type ( the link to Google, the Annual Conference event, and so on ).
Tuesday, December 7. 2004
If you're looking to install an Apache, MySql, PHP environment ( on either Linux or Windows ), instead of doing it piecemeal you may be better off grabing a middleware stack like XAMPP from Apache Friends. An article at IBM, details how to install such a middleware stack. This is perfect for folks who may not have the expertise, time, and or patience to install all these components seperately and, inevitably, troubleshoot the bugs that arise. Instead, you can concentrate on building your website instead of building your infrastructure. Seen in PHP Magazine.
Friday, December 3. 2004
We've rolled up another release of Syntax CMS. Sandy went on a cruft cleanup rampage and we've integrated a number of new features we've been working on. A lot of work has gone into making it possible to share the content repository among multiple sites and segregate parts of the repository among sites and/or user groups.
Public Website
- Added a Sitemap and an improved Search Module.
- Bundled templates use solely CSS to control layout and appearance.
- Removed leftover test datatypes and testing code
- For authentication of registered users, you can enable saving the user's login to a cookie.
Site Administration
- Various layout fixes to the interface.
- If sharing the content repository (database) among multiple sites, you can now control what content types show up in each admin instance explicitly.
- Section Navigator can be configured to automatically add new sections to a default section. Added a button to add a new section as a child of an existing section, instead of having to add it and then specify the parent.
- Section Navigator can be configured to only show below a specific section, instead of showing all sections.
- Removed dependecy on register_global being on (finally).
Under the Hood Enhancements
- Settings & Installation testing: makes it much less painful to get a site up and running by helping diagnose the hard-to-find show stoppers.
- Event Handling and Notification. Adding, editing, and deleting records triggers event notifications which are sent to custom Listeners. It's not actually used out-of-the-box but it provides a facility for running custom code on your own installation. We're using it to sync database records with a 3rd party e-commerce package on a client site.
- Section Navigator and all section related code respects the NAV_ROOT_EL constant when building out site navigation.
- Cleaned up template and php-code generators. Added a generator to make a simple detail template for a content type.
- Added a more advanced relationship picker widgets. Instead of forcing users to scan a huge list of SELECT OPTIONS, shows options in an iframe which is filterable.
Monday, November 22. 2004
In the upcoming release of Syntax, I've started to address the difficulty associated with getting an instance installed and up and running from the archive file. It's still doesn't work straight out-of-the-box but the new installation tests will save you hours chasing obscure and frustrating bugs. Some features, such as file uploading and Smarty templates, depend on the web server process being able to write, or outright own, specific directories. Because of that, we'll probably never get to a point where Syntax will work without some setup time.
Once you have extracted the Syntax files and setup your webserver to make the public directory available over http, you can access the installation tests at admin/testing/. The testing script goes through a handful of php scripts that output settings and test the connection settings to your Syntax CMS database, check ownsership of key directories, and checks that necessary symbolic links exist. Where possible, the script will try to correct any errors by itself but if it cannot, it shows the exact commands you need to execute to fix anything. The screenshot below is an example of output with an error found.

This was previously mentioned installation tests when I checked the instalation tests into CVS.
Thursday, November 4. 2004
I added another out-of-the-box feature into CVS today. It's a module that automatically builds a sitemap based on the sections you create for content. The output is simply unstyle, nested lists inside of a div with an id named, cleverly, "sitemap". You can use CSS selectors to customize the output of the template. You can also write your own display template to tweak the layout to your liking. This will be part of the next release, which should be real-soon-now.
An example of the sitemap module, with a few added bells and whistles.
Tuesday, November 2. 2004
I've just checked in to cvs a suite of testing scripts that check to verify that you're Syntax site is setup correctly. At Forum One, we've had an internal deployment script to use for setting up a new site. But if you're installing Syntax on a foreign server, you've had to hope that the planets are correctly aligned, that you've followed the installation instructions correctly, and that we didn't leave out a critical installation step. This script, which I've placed in the public/admin/testing directory checks the following:
- availability of smarty and Adodb.
- connection to the database specified in config/db.conf.php.
- Syntax framework initialization
- critical directories are writeable by the web server
This will be a part of the next Syntax release but until then you can check out the module ( syntax-cms/src/public/admin/testing ) from CVS on tigris.
Tuesday, October 26. 2004
Detail pages display a particular record on a site. If you have datatype specific modules, you might be tempted to have a detail.php capability within it - usually by just copying the detail.php file from the general module. Unless you'll be implementing a lot of custom code on the detail page, say to hook in to a third party shopping cart app, you're probably safer just re-using the general detail script.
Let's assume you have Press Releases to display and have put the related code in modules/press_release. Your user.conf.php file would have at least the following lines to register the module:
// The Abstract Documents Module
Modules::addModule('press_release', 'Press Releases');
Modules::setAttribute('press_release', 'content_label', 'Press Release');
Modules::setAttribute('press_release', 'datatype', array( DATATYPE_DOCUMENT ));
Modules::setAttribute('press_release', 'public_exposure', true);
Moduels::setCapability('press_release', 'list' );
By NOT specifying a detail capability above, Syntax will route requests to /content/press_releases/detail/444 through modules/general/detail.php. This gains you a few things:
- Fetching the record is done using collections, so that record privileges will be checked and enforced. If a record is restricted to a specific group or user, then it will only be displayed to them.
- Will check if the datatype is in the exposed content datatypes list.
- Breadcrumb to the detail page will be automatically built depending on if user's came to the page from a section or another module.
- Less time coding or copying this code and one less file to manage.
Detail.php is smart enough to look for a custom detail.tpl file to use to display the matching record. It will look in the first module that works with the specified datatype. So, in this case it would look for modules/press_release/templates/detail.tpl and use that file if it exists. In your custom template, you have to use the $Record variable to get information out for display.
Tuesday, October 5. 2004
I just checked in a new type of pick table that will be available in our next release. Just in case you are wondering, in Syntax a pick table is a simple database table of id, name pairs that are used mostly for categorizing other records. For example, you could have a picktable for topics, regions, and countries and use those across all your content types - people, documents, events, etc. Until now, these have been flat lists, and in truth they still are, but by adding a field called parent to a picktable, they can be displayed as a tree of options to users.
In the site administration application, child picks are drawn indented underneath their parent and sorted alphabetically. Also, you can not delete picks that have no parent ( parent=0 ) or that have children.
In an input form, if you use the pick_tree widget with a pick table with a parent column, they will be drawn as a hierarchical set of options for the user to select.
|
|