Posts Tagged ‘cpp’

An alternative method to build eZ Publish configuration files with ANT and the C Preprocessor

October 18th, 2009

eZ Publish configuration files have a major problem : they are not context aware.
This means that you can not build them especially for production or development servers.

I thought about a solution to sort of workaround this problem by using the C preprocessor and macros in configuration files.

Let’s take a simple example. When you work with override.ini directives, you have to write a few configuration directives in order to load the correct template for the correct context, for example, a nodeID. But if this nodeID change between servers, you could have for example this on your development machine :

[foo_bar]
....
Match[node]=123

this on your staging machine :

[foo_bar]
....
Match[node]=456

this on your production machine :

[foo_bar]
....
Match[node]=789

When it comes to industrialize the process of creating correct configuration files with correct nodeIDs (or any other configuration directives) things become more and more complex.

It would be interesting to be able to include the correct values depending on the context in which you want to use your configuration files.

This is where the C preprocessor comes into play, by using specific macros like #include or #ifdef we can generate context aware configuration files without any problem, simply by including the correct configuration file and integrate it into the real eZ Publish one.

For example for override.ini.append.php, this gives the following override.ini.append.php file :

<?php /* #?ini charset="utf-8"?

[full_folder]
Source=node/view/full.tpl
MatchFile=full/folder.tpl
Subdir=templates
Match[class_identifier]=folder

[line_folder]
Source=node/view/line.tpl
MatchFile=line/folder.tpl
Subdir=templates
Match[class_identifier]=folder

// some comments
// in the ini file
// they will automatically
// transformed into correct
// eZINI comments

#ifdef CONTEXT_DEV
#include "override.ini.dev"
#endif

#ifdef CONTEXT_STAGING
#include "override.ini.staging"
#endif

#ifdef CONTEXT_PROD
#include "override.ini.prod"
#endif

*/ ?>

With the following included files

override.ini.dev

// global overrides
[my_dev_override]
Source=path/to/template.tpl
MatchFile=path/to/matchfile.tpl
Subdir=templates
Match[node]=11111

override.ini.staging

// global overrides
[my_staging_override]
Source=path/to/template.tpl
MatchFile=path/to/matchfile.tpl
Subdir=templates
Match[node]=22222

override.ini.prod

// global overrides
[my_prod_override]
Source=path/to/template.tpl
MatchFile=path/to/matchfile.tpl
Subdir=templates
Match[node]=33333

So when we run (note this is not that simple, but I took a few shortcuts in order to be quick)

 cpp -P -DCONTEXT_PROD=1 override.ini.append.php

We get the following result :

<?php /* #?ini charset="utf-8"?

[full_folder]
Source=node/view/full.tpl
MatchFile=full/folder.tpl
Subdir=templates
Match[class_identifier]=folder

[line_folder]
Source=node/view/line.tpl
MatchFile=line/folder.tpl
Subdir=templates
Match[class_identifier]=folder

# some comments
# in the ini file
# they will automatically
# transformed into correct
# eZINI comments
# global overrides

[my_prod_override]
Source=path/to/template.tpl
MatchFile=path/to/matchfile.tpl
Subdir=templates
Match[node]=33333

*/ ?>

As we can see, override.ini.append.php has been created with the correct production nodeID.

Since calling cpp is quite annoying with this ini syntax (mostly due to the presence of PHP comments) I decided to automate the process by wrapping everything into an Ant build script. With the script, building all configuration files should be as easy as running :

 ant clean && ant dev

or

 ant clean && ant staging

or

 ant clean && ant prod

You will find attached a tarball with a fake eZ Publish instance plus settings and context files.
By running of of the commands above, you can generate your configuration files in no time.

Here is an explanation of the ant script’s behaviour. First you have to have the following directory structure :

.
|-- build.xml
|-- common.xml
`-- fakeezinstance
    |-- build.xml
    |-- extension
    |   `-- myextension
    |       |-- build.xml
    |       `-- settings.orig
    |           |-- dbsettings.dev
    |           |-- dbsettings.prod
    |           |-- dbsettings.staging
    |           |-- site.ini.append.php
    |           `-- siteaccess
    |               `-- site.com
    |                   |-- override.ini.append.php
    |                   |-- override.ini.dev
    |                   |-- override.ini.prod
    |                   `-- override.ini.staging
    `-- settings.orig
        |-- override
        |   |-- override.ini.append.php
        |   |-- override.ini.dev
        |   |-- override.ini.prod
        |   `-- override.ini.staging
        `-- siteaccess
            `-- site.com
                |-- override.ini.append.php
                |-- override.ini.dev
                |-- override.ini.prod
                `-- override.ini.staging

As you can see any original settings are located into settings.orig directories. Each of them contains configuration files, I just created an example with override.ini and site.ini. But you can use any configuration file. For each .ini file I created a context file, dbsettings.dev/staging/prod for site.ini for example.

Once the configuration files are ready, we can simply run :

 ant clean && ant prod

And you will see that all settings folder will be created with the correct values.

If you want to add another extension in the build, the only thing you have to do is to copy the build.xml file available in extension/myextension and create a settings.orig directory structure. If you do not want your extension(s) to be processed by the build script, just do not copy the build.xml file and create the settings directory structure as you would normally do.

So one can say that there is a lot of blank lines in the files onces they have been preprocessed. That is true, but remember that those files are supposed to be read by eZ Publish only. If fakeezproject.taryou need to change anything, just update the file you want in settings.orig and rerun the build process, it takes less than 2 seconds.

Download the fakeezproject.tar archive, go in fakeproject ant run ant prod for example.

‘Hope that helps.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)