drupal cms for marketing sites - taxigal · data store (drupal cms) drupal cms is used as a data...

20
Drupal CMS for marketing sites

Upload: others

Post on 29-Jul-2020

14 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

Drupal CMS for marketing sites

Page 2: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

IntroSample sites:

End to End flowFolder StructureProject setup

Content FolderData Store (Drupal CMS)

Importing/Exporting ContentDatabase Migrations

BackendConfigUnit TestingRoutingData bindingData validation

FrontendJavascript LibrariesCss StylesheetsMessagesCommon Smarty variables from controllersVariable references from Javascript

DeploymentWhat is included in the deploymentsPackaging with maven (if required)Creating a tag release and version increment

Training resourcesDrupal:Smarty:PHP:

Page 3: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

IntroThe structure for the Drupal CMS marketing sites is a different setup to a typical drupal CMS build.

The applications are designed to have a clear separation between frontend and cms.

This design is so that we can strip out the Drupal CMS at any time with a different cms and not have to change the frontend of the websites.

This allows a lot more freedom on the application builds and no strong dependencies on the CMS.

Sample sites:

HahnFacebook app: http://www.hahn.com.auDirect desktop access: http://www.hahn.com.au/fbAppTab?liked=lk_1234Mobile version: http://www.hahn.com.au/mobileApp

James BoagJames Boag's Premium:  http://jamesboagspremium.com.auJames Boag's Draught: upcomingJames Boag's Masterbrand: upcoming

James SquireMain website: upcoming

CorporateLion corporate site: upcomingLion career site: upcoming

 

 

End to End flowThe end to end flow of the website structure happens in the below diagram.

The web request comes into the server, the htaccess routes through to a controller php file.

A php service model is then retrieved from the facade, this model will talk to the json services from drupal cms.

The data is then set into a model object with key value pairs, which is then rendered through a smarty template.

The smarty template is then output as a string to the client as html.

 

Page 4: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

Folder StructureThe projects are maven projects so a specific folder structure must be adhered to.The diagram below has highlighted some key folders in the structure which should have specific files stored in.

Page 5: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

Project setupEach project has it's own unqiue database name, user and password.

This should be defined in the readme.md of the project root.

When setting up your development machine make sure to match your user and password to that defined in the readme.md.

This is because we have multiple developers working on the project at the same time and want everyone to have the same settings for when filesare checked in and out of source control we do not override the settings.

 

Content Folder

Every project has it's own content folder which is stored outside of the drupal cms folder.

This is so we can easily make deployments to the different servers without worrying about the content folder being overridden.

To have this setup on your local dev machine first download a copy of the content folder from the staging or live environment.

Page 6: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

Then when you create your virtual host in apache reference the folder by the environment variable WEBDEV_CONTENT.

This can be seen in the virtual host configuration below.

The content alias is pointing to the content folder and the WEBDEV_CONTENT variable is pointing to it's parent folder. This is because in drupalsettings.php we are creating content reference with WEBDEV_CONTENT/{project name}.

<VirtualHost *:80 > ServerName hahn.dev.local DocumentRoot"/home/aiden/Development/GitRepos/LIO0035_HahnPioneeringBeering/hahnpioneeringbeering-webapp/src/main/webapp" DirectoryIndex index.php index.html index.htm <Directory"/home/aiden/Development/GitRepos/LIO0035_HahnPioneeringBeering/hahnpioneeringbeering-webapp/src/main/webapp"> AllowOverride all Order allow,deny Allow from all </Directory> <Directory "C:/opt/temp/DevSitesContent/HahnPioneeringBeering"> AllowOverride all Order allow,deny Allow from all </Directory> Alias /content "C:/opt/temp/DevSitesContent/HahnPioneeringBeering" SetEnv WEBDEV_CONTENT "C:/opt/temp/DevSitesContent" </VirtualHost>

 

 

 

Data Store (Drupal CMS)Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS.

This is a slightly different way of thinking to the ordinary CMS setup where everything comes from the CMS.

The only information that should be stored in the CMS is the editable content (data only).

For instance in   the editable content is the modules. The content editor wanted the ability to change the modules in thehttp://www.hahn.com.aupage with the image details, copy etc.

This data is then retrieved from Drupal using the services module and outputting that information through json feeds.

The setup of the data is quite simple where we have Node Content Types with properties of the data we want to store, Image Styles for theresizing of images for the frontend, Taxonomy for tagging content to use as filters.

Views are then setup to output those Content Types and Taxonomy Terms as json feeds.

 

Node Types can be edited in the below page of the cms.

Page 7: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

 

Service Views can be edited in the below page of the cms.

Page 8: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

 

Individual JSON Service views created in the cms.

Page 9: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

 

 

Importing/Exporting Content

To export content from a staging to production environment and vice versa please use the content import/export module.

In the drupal shortcuts menu there are two links 1 for export content and 1 for import content.

To export just click the export content and it will prompt to save a txt file of the content.

To import this content click the import content and you will see a form with some options.

Select the export file as the file to import and then select the parameters of the import for which content types to import etc.

Page 10: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

1. 2. 3. 4. 5.

 

Database Migrations

The database of drupal is very complex so data migrations can be a real pain.

The solution at the moment is to do the following steps. 

This is currently in the process of being automated.

Export the content from the admin panel.Make a copy of the database.Export your current database.Import your database on the server.Import the content that was exported in step 1.

 

Page 11: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

BackendThe backend is a simple mvc structure which has a lot of helper classes which allow you to easily get request information and to mock requestsfor unit testing.

The php folder is where all the controllers and business logic should be stored. Please refer to previous projects on the structure of the controllersand models.

The webapp folder is the web root of the website. No php files are needed here other than the files which are currently in the existing structure.

The WEB-INF/views is the smarty views folder. All smarty views should be stored in this location.

 

Config

The configuration of the website is controlled by  WEB-INF/config.ini

This configuration should have all of the settings which are needed to control the application and which change between environments.

This file has references to css and javascript which will be changed in the final deployment through the maven configuration.

This happens by updating the pom.xml where the plugin  is setup. This plugin needs to reference the same css and js asmaven-minify-plugin referenced in the config.ini.

This will enabled the css and js to be merged and minified in the deployment process.

Please make sure to look at the overriding configuration which is stored in assembly/config.ini.

This overriding config.ini should be the same as the WEB-INF/config.ini except with dynamic variables to change settings between the differentenvironments.

These settings come from the pom.xml when processing the config.ini, see below snippet for pom.xml configuration.

<plugin> <groupId>net.rumati.maven.plugins</groupId> <artifactId>velocity-maven-plugin</artifactId> <version>0.1.2</version> <executions> <execution> <id>config-override</id> <phase>prepare-package</phase> <goals> <goal>velocity</goal> </goals> <configuration> <template>${basedir}/src/main/assembly/config.ini</template> <outputFile>${basedir}/target/auto-generation/webapp/WEB-INF/config.ini</outputFile> <properties> ... <googleanalyticsid>${googleanalyticsid}</googleanalyticsid> <buildFinalName>${buildFinalName}</buildFinalName> <publicContentLocation>${publicContentLocation}</publicContentLocation> ... </properties> </configuration> </execution> </executions></plugin>

 

Page 12: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

 

Unit Testing

All php code should be developed to be easily mockable and testable.

This should use interfaces for model services so a mocked version and an implementation can be created.

There should be no direct references to $_SERVER variables, the HttpServletRequest object in the facade should be used to pull out variablessuch as server name and request parameters etc.

This allows controllers and models to be built and tested without the need for running through a web server.

All unit tests should be stored under test/php, please refer to previous projects for references.

 

Routing

All routes should be defined in .htaccess file.

Any dynamic parts of the url structure should be passed through to the controller as redirect parameters.

This allows the controller to be completely separated from the route so there are no dependencies on url structures etc.

An example of a route which does this in hahn is below.

You will see in this example we have api/modules/{Service_method}.json as the route.

The Service method is the dynamic parameter to pass to the controller so that is defined by using the redirect parameter E=ServiceMethod:$1

RewriteRule ^api/modules/([^/\.]+)\.json$ view.requesthandler.php[E=ExecuteController:APIModulesCommand,E=ServiceMethod:$1,L]

This is then picked up by the controller using the following code.

$serviceMethod = $request->getRedirectParam("ServiceMethod");

 

Data binding

Data binding throughout the application uses annotations which are parsed through an annotation parser and used to bind data between thefrontend requests, drupal and traction.

 

These can be seen by the below example from an entity class.

You will notice annotations for DrupalField and TracField.

In the drupal annotation parser it will look for properties with DrupalField and if found will bind the node object field which is retrieved from drupalto the property in the entity class.

In the traction sdk it will look for properties with TracField and if found will add that property into a request to send to traction.

Page 13: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

/*** @Entity*/class ContactEntity{ /** * @DrupalField(name="nid",customfield=false) * @var integer $nodeid */ public $nodeid; /** * Special field used for when inserting into traction. * Response object id will be populated * @TracCustomerId * @var integer $id */ public $tractionCustomerId; /** * @DrupalField * @TracField(name="FIRSTNAME") * @var string $firstname */ public $firstname = null; /** * @DrupalField * @TracField(name="LASTNAME") * @var string $lastname */ public $lastname = null;}

 

If you are doing html form binding this can be done by using the below annotations to bind fields to specific data types automatically.

You will notice BindType annotation is used here.

See RequestBindUtils::bindToRequest for supported binding types.

Page 14: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

/*** @Entity*/class NominationEntity{ /** * @var string $story_description */ public $story_description = null; /** * @var string $friend_email */ public $friend_email = null; /** * @BindType(type="datetime") * @var DateTime $invitation_date */ public $invitation_date = null; /** * @BindType(type="boolean") * @var bool $optin_nominee */ public $optin_nominee = false;}

A controller which handles this bind can be seen with the code snippet below.

// create bind model$bindModel = new WinnerFormVO();RequestBindUtils::bindToRequest($bindModel, $request,array("winner_country","winner_state","winner_postcode","agreeterms","optin"), null);

 

Data validation

Data validation uses a simple validation api with a lot of helper methods.

See ValidationUtils for supported methods.

An example use of a validator class snippet is below.

Page 15: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

class NominationWinnerValidator{ public function __construct(){ } /** * Validates model parameters * @param NominationEntity $model * @param HttpServletRequest $request * * @return Errors */ public function validate($model, $request){ $errors = new Errors(); ValidationUtils::rejectIfNullOrEmpty($errors, "winner_firstname",$model->winner_firstname); ValidationUtils::rejectIfMax($errors, "winner_firstname", $model->winner_firstname,50); ValidationUtils::rejectIfNotPattern($errors, "winner_firstname",$model->winner_firstname, "/^[^\\d]+$/"); return $errors; } }

 

 

FrontendThe frontend uses standard html markup running through smarty templates.

All templates should be named with .tpl extension.

Templates should not contain any php code.

If data needs to be parsed to the templates that should come from the model object that the controllers pass to smarty.

Static file references should always use the model attribute called {$cdnResourcesPath}. This allows all css, js, images etc anything which issitting under the webapp/resources path to be referenced.

This allows for a lot of flexibility if needing to store files on a cdn or updating the path references for deployments.

For example:

If you are referencing a css file in  resources/css/file1.css and the application is already deployed then when you make updates to this file youwant updates to be rendered immediately without clients clearing their cache.

By adding {$cdnResourcesPath} infront of the file to look like this {$cdnResourcesPath}/css/file1.css then the deployed file will look like  http://domain.com/static/123454654/css/file1.css.

This makes deployments extremely simple since all static resources are time stamped for each deployment so references to them are updatedimmediately and no references to the updated files need to be changed in html.

 

Page 16: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

Javascript Libraries

All javascript files should be added in the webapp/resources path under js folder.

To import the javascript file into the html do not create a script reference in the html!

You will need to add the reference in the webapp/WEB-INF/config.ini and the pom.xml.

This is because the config.ini will be used to retrieve the list of javascript files and the pom.xml will be used to minify those javascript libraries intoa single js file.

Please refer to the below snippets from a previous project.

 

Config.ini

...desktop_view_js[] = "/frontend/js/lib/jquery/jquery-1.7.2.js"desktop_view_js[] = "/frontend/js/lib/jquery/jquery-class.js"...

 

pom.xml

...<jsSourceFile>lib/jquery/jquery-1.7.2.js</jsSourceFile><jsSourceFile>lib/jquery/jquery-class.js</jsSourceFile>...

 

Css Stylesheets

All css files should be added in the webapp/resources path under css folder.

To import the css file into the html do not create a link reference in the html!

You will need to add the reference in the webapp/WEB-INF/config.ini and the pom.xml.

This is because the config.ini will be used to retrieve the list of css files and the pom.xml will be used to minify those css files into a single css file.

Please refer to the below snippets from a previous project.

 

Config.ini

...desktop_view_css[] = "/frontend/css/core.css"desktop_view_css[] = "/frontend/css/main.css"...

 

pom.xml

Page 17: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

...<cssSourceFile>core.css</cssSourceFile><cssSourceFile>main.css</cssSourceFile>...

 

Messages

All copy in the frontend should come from the messages.ini file unless coming from the cms.

This allows for translations to be done on the copy in the website or the copy can be migrated to the cms at a later stage.

The messages file is a standard php ini file, use below references for example.

To retrieve a message in smarty templates call the message like the following.

<p>{$messages["messagesGroupName"]["messageKey"]}</p>

For example if your messages file looks like this.

[messages]mymessagekey="Lorem ipsum"

Then you would call this message like so.

<p>{$messages["messages"]["mymessagekey"]}</p><!-- Output would be <p>Lorem ipsum</p> -->

 

Common Smarty variables from controllers

The table below is a list of variables which can be accessed from smarty templates in the existing projects.

This can be used as a reference to what variables you can use.

These variables are inserted from the php controller by calling SupportUtils::addDefaultModelVariables($model, $facade).

Variable Description Type

{$config} The config ini object Array

{$messages} The messages ini object Array

{$browser} The browser object to retrieve user agentdata

Browser

{$isMobile} The is mobile boolean to determine if useragent is mobile.

This is short syntax for callingbrowser->isMobile()

Boolean

Page 18: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

{$isTablet} The is tablet boolean to determine if useragent is tablet.

This is short syntax for callingbrowser->isTablet()

Boolean

{$request} The http request object. This can bereferenced if requiring to check for serverparams etc.

HttpServletRequest

{$webRootPath} The absolute path to web root. Use this forany files which need to be reference from theroot of the website

String

{$cdnRootPath} The absolute path to the cdn root. Use thisfor any files which are static and referencedfrom the root of the cdn.

If cdn paths are not defined this defaultsback to webRootPath

String

{$resourcesPath} The absolute path to the static resourcesfrom the root of the website.

This should only be used if your wanting toreference files on the root of the websiteotherwise cdnResourcesPath should beused.

This path references files underwebapp/resources. So if you have a files inwebapp/resources/js/file1.js you wouldreference it by {$resourcesPath}/js/file1.js

String

{$cdnResourcesPath} The absolute path to the static resourcesfrom the root of the cdn.

This path references files underwebapp/resources. So if you have a files inwebapp/resources/js/file1.js you wouldreference it by{$cdnResourcesPath}/js/file1.js

String

{$contentPath} The absolute path to the static content fromthe root of the website.

This should only be used if your wanting toreference files on the root of the websiteotherwise cdnContentPath should be used.

This path references files under the contentalias for cms uploaded content.

 String

{$cdnContentPath}  The absolute path to the static content fromthe root of the cdn.

This path references files under the contentalias for cms uploaded content. 

String

{$metadata} The current metadata object for the currentpage.

MetadataVO

 

Page 19: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

Variable references from Javascript

Sometimes you may want to get absolute path references in javascript files.

These can be referenced by a window variable MainConfig.

This config object is inserted into the html page by the php controller calling SupportUtils::getHtmlConfig($model, $facade).

Here is an example of how to get the cdn resources path from javascript.

var imagePath = window.MainConfig["cdnResourcesPath"] + "/images/myimage.jpg";

 

DeploymentThe deployment process of the site happens with a maven packaging command which generates a deployable zip file that can then be extractedto the server.

Most projects should be running through which automatically runs the maven packaging commands and deploys to theBamboo build serverservers.

If the project is setup in Bamboo all which is required is to adhere to the documentation on frontend and backend in this document.

Once you have completed development of a feature or bug fix etc commit all your code into git and push to the origin server.

This will then trigger an update in Bamboo and the code will be automatically deployed to the staging server within about 10 minutes.

If you and the producer are then happy with the staging deployment ask your Tech Lead to click the deploy to live in Bamboo.

 

What is included in the deployments

Currently only files in source control are deployed to the different servers.

A solution is being worked on for content deployments, so if you need to migrate content from staging to live and vice versa please use the import/.export module

 

Packaging with maven (if required)

If it is required that you have to package up the project with maven to do a manual deployment please following the following steps.

Browse to the root of you project.

Package for staging server.

mvn cleanmvn -Pstaging package

 

Package for live server.

mvn cleanmvn package

Page 20: Drupal CMS for marketing sites - Taxigal · Data Store (Drupal CMS) Drupal CMS is used as a data store only. There are no templates or frontend code coming from the CMS. This is a

Creating a tag release and version increment

Once you do a live production deployment it is good practice to create a tag in the source control and increment the version of the project.

You can do this using the maven release plugin by following the below steps.

This will ask you a series of questions which you can hit enter on all of them except if you want to change the version names.

Browse to the root of you project.

 

Create release

mvn cleanmvn release:preparemvn release:performmvn release:clean

 

This would have created a tag in the repository and increased the version in the maven pom.xml files.

We then want to push up the changes to the origin.

git push origin --tagsgit push origin master

 

Training resources

Drupal:

Drupal Essential Training:   http://www.lynda.com/Drupal-7-tutorials/essential-training/73655-2.htmlDrupal Advanced Training: http://www.lynda.com/course-tutorials/Drupal-7-Advanced-Training/97405-2.htmlResponsive Design with Drupal: http://www.lynda.com/Drupal-tutorials/Responsive-Design-Drupal/107419-2.htmlServices Module used to pass the data from CMS to frontend: https://drupal.org/project/services

Smarty:

Crash course: http://www.smarty.net/crash_courseBest practices: http://www.smarty.net/best_practices

PHP:

PHP ini: http://php.net/manual/en/function.parse-ini-file.php