Tuesday 06 January 2009 2:01:36 pm
This subject has been touched upon before, and at least once by myself. I'd like to ask for feedback relating to my successful efforts at 'deploying' an eZ site to flat HTML files: The current version of ez publish contains a very simple script for creating an 'offline' version of an ezpublish website. It is also quite limited, as are many such systems in other CMS's. We needed a much more advanced method of doing this to provide an identical off-line version of our ezpublish site and so our solution also grabs background-images used in CSS and fetches RSS files. In order to achieve this we've created 2 new, and modified 3 existing files: <b>New Files:</b> * <b>ez-deploy.sh</b> This is a bash script that invokes <b>wget</b> and if necessary - <b>sed</b> - to fetch and post-process an ez website from a pre-specified URL.
#!/bin/bash
# Shell script to deploy an eZ Publish website invoked from ezpublish interface
# Russell Michell May/Nov 2008
date1=`date +%s`
#-----------------
# Sanity checking:
#-----------------
if [ ! $1 -a ! $2 ]
then
echo "Error: Incorrect arguments passed to script: $0"
echo "Arg 1: <url-to-fetch>"
echo "Arg 2: <local-dir-to-stuff-things-into>"
exit
else
URL=$1 #The URL to fetch
DIR=$2 #The dir to pile everything into locally
fi
#-----------------------------------------
# Define array of virtual-dirs to exclude:
#-----------------------------------------
EXCDir[0]="/duty/user"
EXCDir[1]="/duty/ezinfo"
for exclusion in "${EXCDir[@]}"
do
NoDirLIST+="$exclusion,"
done
# Remove trailing comma: ("%%" means "delete FROM the RIGHT, TO the LAST instance of what follows")
NoDirLIST=${NoDirLIST%,*}
#------------------------
# Build the wget command:
#------------------------
CMD="wget -Emp" # -m recursion, time-stamping. -E converts pages .* to .html. -p download all inline files (imgs, css etc)
CMD="$CMD -l 10" # -l recursion depth (5 is default)
CMD="$CMD -nH" # -nH disables host-prefixed directories upon download
CMD="$CMD -k" # -k Convert the links in the document to make them suitable for local viewing (inc images, styles, js etc)
CMD="$CMD -P$DIR" # The path to the local directory to save stuff to
CMD="$CMD -X $NoDirLIST" # Exclude predefined dirs in $NoDirLIST from the download
CMD="$CMD -np" # -np Contents below a certain hierarchy will be downloaded only
CMD="$CMD --follow-ftp" # --follow-ftp Follows ftp:// protocol hyperlinks in webpages
CMD="$CMD --no-cache" # --no-cache ensure latest page/file-versions are always requested
# To log or not to log?
if [ $3 ]
then
LOG=" -a $3"
CMD="$CMD $LOG"
else
LOG=""
fi
# Appends an extra slash if one not passed in $URL
lastchar=`expr substr $URL ${#URL} 1`
if [ $lastchar != '/' ]
then
CMD="$CMD -q $URL/"
IMGURL=$URL
else
CMD="$CMD -q $URL"
IMGURL=${URL:0: (${#URL} -1)} # equiv to substr($URL,0,strlen($URL)-1) in PHP
fi
# Do it, do it:
$CMD
#----------------------------------------------------------------
# WGET won't parse .css files for background images - get manually:
#----------------------------------------------------------------
IMGURL="${IMGURL/\/duty//}" #Lose my siteaccess from the URL to get images
wget -m -nH -P$DIR $IMGURL/extension/duty/design/ezwebin/images/$LOG
wget -m -nH -P$DIR $IMGURL/var/ezwebin_site/storage/images/media/images/$LOG
#-----------------
# Post Processing:
#-----------------
# For some reason wget won't create 'index.html' in directories, artifically create the homepage at least:
if [ -f "$DIR/duty.html" ] # 'duty' is the name of my siteaccess
then
/bin/mv "$DIR/duty.html" "$DIR/index.html"
fi
# WGET won't parse RSS for URLs - process these manually:
/bin/find $DIR -type f -name '*.rss' -execdir /home/russellm/sbin/ezpublish/ez-deploy-sed.sh {} \;
# Using the wget -E flag has the side-effect of renaming text/plain pages to .txt.html, let's lose a few:
/bin/find $DIR -type f -name '*.txt*' -exec rm {} \;
date2=`date +%s`
TIME=$[ $date2-$date1 ]
echo Deployment process completed in: ${TIME}s
* <b>ez-deploy-sed.sh</b>
#!/bin/bash
# wget won't parse RSS files. Post-process for static deployment:
# Russell Michell November 2008
if [ ! $1 ];
then
exit 65
else
/bin/sed '/:808[0-9]\/duty\/\?/s//\/cms-deploy\/ezpublish\/duty\//g' $1 > "$1.tmp"
mv "$1.tmp" $1
fi
<b>Existing Files:</b> * <b>settings/siteaccess/<my-access>/site.ini.append.php </b> Added a new section: [DeploySettings] and 3 settings for it:
1: ShellScript=/path/to/sbin/ez-deploy.sh
2: ShellScriptArgTargetDir=/var/www/htdocs/cms-deploy/ezpublish/
# Keep the output from wget's "-a" flag 3: DeployLog=enabled * <b>kernel/content/action.php</b> Added an extra elseif clause on line 200 that invokes the shell script using exec():
// Invoke a shell-script to deploy a static version of an ezpublish website:
else if ( $http->hasPostVariable( 'SetDeploy' ) &&
$http->hasPostVariable( 'ContentObjectID' ) && $http->hasPostVariable( 'ContentNodeID' ) )
{
$nodeID = $http->postVariable( 'ContentNodeID' );
$siteINI = eZINI::instance( 'site.ini' );
$deployScript = $siteINI->variable( 'DeploymentSettings', 'ShellScript' );
$deployScriptArgTargetDir = $siteINI->variable( 'DeploymentSettings', 'ShellScriptArgTargetDir' );
$deployLogEnabled = $siteINI->variable( 'DeploymentSettings', 'DeployLog' );
$deployScriptArgFetchURL = 'http://'.$siteINI->variable( 'SiteSettings', 'SiteURL' );
// To log, or not to log:
$logFile = '';
if($deployLogEnabled == 'enabled')
{
// Pass optional 3rd argument (Path to log-dir) to shell script to tell wget to use the -a flag
// This is hard-coded for now - how do you get the ez working dir??
$logFile = '/var/www/htdocs/ez-DEV/var/log/deploy.log';
}
// the command to invoke wget via our shell script:
$exec = "{$deployScript} {$deployScriptArgFetchURL} {$deployScriptArgTargetDir} {$logFile}";
if(!exec($exec))
{
// Need a better error - get one...
return $module->handleError( eZError::EZ_ERROR_KERNEL_ACCESS_DENIED, 'kernel' );
}
return $module->redirectToView( 'view', array( 'full', $nodeID, $languageCode ) );
}
* <b>design/<my-design>/override/templates/website_toolbar.tpl</b>
Added an extra <div> to the ezwebin toolbar in an override for website_toolbar.tpl so a button is displayed and editors can login, press it on any page and the whole site is re-crawled and deployed:
<!-- Begin Static Deployment Button -->
<div id="ezwt-deploy">
<form method="post" action={"content/action"|ezurl} class="right">
<input type="hidden" name="HasMainAssignment" value="1" />
<input type="hidden" name="ContentObjectID" value="{$content_object.id}" />
<input type="hidden" name="NodeID" value="{$current_node.node_id}" />
<input type="hidden" name="ContentNodeID" value="{$current_node.node_id}" />
<input type="submit" name="SetDeploy" value="Deploy Me" />
</form>
</div>
<!-- End Static Deployment Button -->
If anyone thinks this might be useful and would like to try this out on their ez installs, the code and modifications are all here. Maybe the ez Crew might consider improving eZ's core-code to incorporate this or simialr functionality in some future release? Of course suggestions for improvement are always welcome, I imply no guarantee that this will work for everyone and it has not undergone any of the unit tests that a completed ez product or eZ code should always undergo. <b>Questions/Possible Improvements</b>
* Restrict the display/action of the "Deploy Me" button in the toolbar to users with specific permissions
* Selectively deploy parts of the site at a time
* Transfer the array of exclusions from the shell-script to site.ini
* Report the time taken to deploy to the screen. At present, this is restricted to invoking ez-deploy.sh from the CLI * Is there a way to do something like this without having to modify any files in 'kernel'? As maintaining something like this begins to get hard, even in SVN when you have to modify core-code.
Thanks a lot folks, keen to get feedback :-) Russ
Russell Michell, Wellington, New Zealand.
We're building! http://www.theruss.com/blog/
I'm on Twitter: http://twitter.com/therussdotcom
Believe nothing, consider everything.
|