Bonnier Publications A/S publish magazines in Denmark, Norway, Sweden, Finland and Holland. All the magazines have websites, some of which are quite significant and have a large amount of traffic and reasonable revenue, while others are simple presentation sites. Altogether Bonnier Publications (BP) has more than 40 sites in five different languages.
For many years, BP has used the Java-based CMS Polopoly for all their sites, but this has not been optimal and especially programming the sites was far too slow, even for the smallest adjustments.
During the summer of 2008, BP decided that their CMS technology needed replacing to enable their editorial staff and sales departments to take full advantage of the Internet's dynamic potential. They chose Drupal CMS, and Peytz & Co. was appointed strategic partner and asked to handle the platform migration.
From Java to Drupal
The task was handled in a cooperation between Peytz & Co. and BP’s own technical department, whereby Bonnier’s own developers were at the same time taught Drupal programming. Their developers quickly started playing with Drupal and PHP, some of them even in their spare time, so they were prepared for the new platform. Six months after launch, Bonnier’s own developers were developing larger Drupal sites themselves.
Design and advertisements
It was stressed from the beginning that the task was not to create new individual sites, but only to change the technological platform. It was also a requirement that banner advertisement formats etc. should be standardised. We therefore implemented a common design-grid for all websites that ensured that the required advert formats would fit into all sites, but still allowing each individual sites to have its own unique identity.
In reality it is difficult just to move a site from one technical platform to another. Partly because the design needed to be changed anyway, so it would fit into the new standard grid, but also because pages are built very differently in Drupal. Additionally the CSS and markup needed to be created from scratch. With this in mind it seemed pointless replicating known errors and mistakes. On the other hand the task involved a large number of websites and developing all of them from scratch would require more resources than were assigned.
In practice a great number of compromises were agreed upon, whereby the largest site by far (iform.dk) was recreated from scratch, while other sites received smaller or larger overhauls.
In connection with the redesign, a number of rules were created for cross promotion and cross-linking (including reusing content) between the individual sites, resulting in the sites to a far greater extent being able to drive traffic to each other in the future.
This case study is based on the website iform.dk. (I Form is Danish and translate to “In Shape”)
Iform.dk has received a full makeover, including adjusting the concept and a new design. Iform.dk is published in Denmark, Norway, Sweden and Finland. An online editorial staff of 4 in Denmark handle most of the production. Some articles are translated and reused, but not all. Both Sweden and Finland have local editorial offices.
The development team
In addition to Bonnier’s sites, we also develop and host sites on our platform for other customers. Our development environment has been designed to allow developers to access and program many different sites simultaneously, including having multiple programmers working on the same site at the same time. We use CVS and were originally running a standard Multisite with an "all" folder for all the modules shared across sites and a "site" folder for all the site-specific modules. This setup quickly became an obstacle, because we could not maintain any proper overview when updating modules on 50 different sites at the same time.
We faced a dilemma: on the one hand we wanted to be able to work on shared modules regarding daily operations. On the other hand it was very necessary to be able to upgrade modules on different sites independently of each other. We solved this by developing our own tool: Drupal Wizard.
"Drupal Wizard" is a type of package handling system that helps us keep an overview of the CVS tags in our own code and contrib-code. Drupal Wizard thereby keeps the track of which module versions are being used on which sites.
With Drupal Wizard, developers can place the wizard.info file at the same level as settings.php and then control versions using CVS. In addition to this there are scripts to handle the update of modules on both our development- and live servers.
All our developers work on the same two development servers and basically only require a ssh access. This solution is very flexible and gives new developers an easy start. We have configured our servers so all developers have their own personal area (initials.site.drupal.example.com). The address points to their CVS checkouts for each project/site. Each developer has his or her own database.
In addition to this we have a staging area (test.site.drupal.example.com) for code that has been checked into CVS. We expect the staging area to be functional, but not necessarily completely developed. The staging area is updated automatically for each CVS commit made by a developer.
The next area is pre-production (preprod.site.drupal.example.com), where we manually update the project’s CVS. This is the final level before going live and we therefore only expect code that is fully functional and that fulfils the customer's requirements to be updated.
The site is hosted on a cluster of Web servers that are all behind a reverse proxy. When going online, the PHP code is rsynced to each individual server using a deployment script. A database server with a replications slave is used as a "hot" backup.
Our fileserver is an Amazon S3. Drupal communicates with the S3 using an in-house developed stream wrapper with a local cache. Private files with HTTP caching are used in the reverse proxy. This setup has required certain local changes in the core Drupal upstream code and a number of changes in the contrib modules:
- Support PHP stream wrappers: http://drupal.org/node/227232
- locale.module adds wrong js path: http://drupal.org/node/250451
Up to now, Bonnier had used the commercial CMS Polopoly versions 8 and 9. Polopoly allows existing data to be exported as XML, but as that data also resides in a MySQL database, we chose to move the whole database to the new Drupal server. At the time it seemed like an easier solution to "simply" take the data from the Polopoly table and to import it into Drupal.
However it later turned out that Polopoly had placed certain data from some articles in a file system rather than in the database. While we couldn’t figure out the reason for this, we could create a set of rules that govern when data would be fetched from the database and when it would be fetched from the file system. It was purely trial and error getting the Polopoly database/file system to function.
The old I Form had more than 3000 articles that had been accumulated over the years. The migration of the articles was also handled semi-automatically, allowing Bonnier to double check the relevance of the articles. They ended up migrating under 50% of the articles and thereby discarded many obsolete articles. This method also resulted in cleaning up the many articles that contained incorrect HTML.
In practice we handled the migration by creating article lists based on the old site structure. The editorial staff clicked on each individual article, that then opened in Drupal's node edit form. The editors checked that the article appeared to be correct and the correct images were linked up. Because we were using Drupal's standard node edit form and had filled out a correct node object, the article was also saved correctly when the editor clicked "save".
Importing jogging routes
I Form has a very successful jogging route planner that visitors have used for many years to create and save around 430.000 Danish and around 50.000 Swedish jogging routes. These routes also needed to be migrated to Drupal, but unlike the articles, we chose to fully automate this process. We created a function that used Drupal's batch functionality. The function migrated 200 routes for each batch job by creating node objects and saving them using the call to save () function. We typically let the programme run overnight, whereby it could migrate around 100.000 routes at a time.
We have chosen to spread out our content types as much as possible, to give the greatest possible flexibility.
We have used standard articles as much as possible across the site. The node types consist of multiple sections that primarily use cck fields for content. Most of the other node types use more or less the same sections as these.
Asides from taxonomy, language selection, menu settings etc., an article also consists of the following:
This section contains the fields that are used as a teaser for the article in other areas of the site. You can choose between title, text and image for the teaser - which do not have to be the same as the actual article. In addition a custom text link can be created instead of the default "Read more" text and the user can choose between one of the seven different design colours for the teaser.
Teaser’s data logic first checks whether there is any data in this section. If the teaser section is empty the programme looks in the deck field from the main section. The programme checks for an image in the teaser section first, then the topbox section and finally in the main section.
The design allows the possibility of inserting a large image at the top of an article. This image can either be the full width of the design, or have a blue text box on the right hand side. This is controlled by the top box section.
This is the article’s primary fields that contain the main text. The primary text field uses the DME module, that uses defined tags to insert images. Images are also chosen in this section and defined in the CCK node reference.
This section contains a text field for the title and a text area for one of the sidebars.
"Related articles" section
In this section articles with related content can be linked together via a node reference field. The user has the option of adding a title in a simple text field. I Form has decided that there should always be 10 related articles, so in addition to the articles chosen by the journalist, the system will automatically add the remaining articles up to 10 using the Drupal taxonomy system.
"Recommended nodes" section
Nodes can be selected from a node reference list. This is similar to the article reference, but is shown differently in the design. The selected nodes are shown in a list that is similar to the site’s overview pages.
Here one can also select whether an article should be featured in the "Recommended" section in the site’s right column.
The design includes a consistent lilac coloured toolbar at the top of the articles. This bar contains a title, some links and a drop-down menu with additional links. All this information is automatically selected for the article from the category taxonomy. Users have the possibility to override the automatic choices and also to completely remove the Toolbar from the article.
Simple node type with the possibility of implementing a specific form from the calculator module. Each form consists of some custom elements, that when submitted use a customised calculation that gives visitors results for e.g. calorie consumption, alcohol content and BMI figures.
The contest node has three fields. The competition questions are typed into a simple text field that uses predefined syntaxes to allow any number of questions. When the competition is active, this field is interpreted and converted to radio buttons (see the chapter about the Contest module).
There is a "thank you for your participation" field and a field for the terms and conditions of the competition. Unless special conditions apply to a competition, a standard value is used for this field.
One can choose to add a taxonomy word to the node, that corresponds to a permission (as in "yes please, I would like to receive a weekly newsletter".)
A simple node type that allows the implementation of iframes. Parameters like source, width, height, scrollbar etc can be set. This node additionally uses the teaser section and toolbar section.
All images on this site use this node and are implemented as node reference fields. The node is therefore in reality a central image database that allows easy access to reuse images. The actual images are uploaded using the ImageField module. The image can be tagged with a title, description and taxonomies.
All jogging routes created via the jogging route planner use this node. The actual data collection of route data is not handled via the usual node edit form, but instead via a custom form. Data is thereafter compiled as a node object and saved in the same way as when importing/migrating data.
Multiple users can add the same route to their profile. This is handled by a user reference field on the node.
This is primarily used for static articles, like for example articles about I Form, advertising information etc. The advantage of this type of article is that we can exclude advertisements from the article and that the nodes do not appear in any type of lists
This type is used to tease content that is not a node. Apart from the fields described in the teaser section, this type also includes a CCK link field to internal or external links.
The test module differs from the competition module by allowing test questions to span multiple pages. By pages we mean that having answered the first questions, the user needs to click on "next page" to continue the test.
As in the competition module, the test module also has a field that allows users to type in an unlimited number of questions with a predefined syntax, but unlike the competition module there are no right and wrong answers. Instead each question is rewarded with a number of points that the author of the test added together with the questions on the syntax field. When the visitor completes the test the number of points are added together.
Test also has a field to attach test result nodes. The test result node allows any number of test results to be attached - each with a point range. If the visitor scores for example 12 points and there is a test result node with the point range 0-20 attached, this node will be shown to the visitor as the final step of the test.
A test result is very similar to an ordinary article. As described in the previous paragraph about test node types, it shows the visitor relevant information based on his or her test answers. The reason that we do not use an ordinary article to present the test results, is that it is far easier to filter out a node type from views, search results and other lists.
Bonnier currently promote their sites individually, but despite this we have chosen that visitors only need to register once regardless of which sites they visit on the new platform. This ensures that Bonnier has the possibility of cross promoting their sites and that visitors are spared the burden of having to register the same information many times if they visit different Bonnier sites. It is however important for Bonnier to explain the advantages of this to their visitors.
All the sites share the user tables in a shared database. We are currently facing the challenge of making the user database accessible from the other sites that have yet to be migrated to the Drupal platform. Visitors need to be validated by sites that currently reside on other servers and that use other CMS platforms.
The calculator module consists of a handful of unique forms. Each form processes the data inputted by the visitor and returns results that for example are usually calorie consumption, alcohol percent and BMI figures.
The competition module Contest is dependent on the Questions module. The Questions module is the syntax interpreter that is used for both competitions and tests. It interprets the questions written by the author of the competition and converts them to a form with radio buttons and validates the answers when the user has completed the contest.
The backend interface allows the administrator to draw a winner, export the participants data to an excel file and view a list of participants. You can additionally configure the permissions for the competition (see the paragraph about the competition node). This is done directly in the taxonomy interface, where you can select whether the user as a default should have a “Yes Please” permission checkbox ticked or not. One can also choose not to allow users to be able to make that choice – so that they automatically have given permission by entering the competition.
This module makes two new actions available for the image cache presets.
We have called the first action ”Fixed crop”. It has four settings; minimum width, minimum height, x offset and y offset. Fixed crop shows a “crop image” popup link on the node edit page, close to the image field cck fields. This popup contains a jQuery cropper. When the desired area of the image has been selected, the width, height and offset is saved in the database with the image file id reference.
We have called the second action ”Master preset”. This action enables smaller up- or down-scaling of an already cropped image – while retaining the same area and aspect ratio as the original.
This module enables the user to apply a context for menu items. Input is handled by the same interface that is used to create and modify menu items. The context is simply taxonomy. This context can be used in many places, for example in code that generates a context sensitive right box based on the context of the current page. If you are for example not on a node page, but instead on a page that consists of panels, you will not have a taxonomy available to decide the context. Instead the context is provided by the module.
This module is especially popular with the person responsible for banner advertising on the site. Previously it was not possible to include a context from e.g. the front page as it consists of panels, but now any taxonomy can be fetched.
Bonnier wanted full control over the front page content and front page sections, both regarding content and design.
We used the Panels module as our foundation – as it gives us the possibility of creating pages that are divided into ’panels’ which can contain content. It also has an intuitive drag-n-drop user interface.
We have additionally developed a teaserbox module that enables the editor to choose an article or teaser, choose between various designs and finally choose the colour and various placements of text and images. Finally the result is placed in a panels pane.
Termed menus are basically a copy of the widely used contrib-module menutrails. The module ensures that if a user is on a node that is associated with a taxonomy that belongs to a menu item – the menu retains it’s context.
We found that it was necessary to write our own module, as menutrails does not support translation of menu items. We use one menu per language but menutrails only allows one menu to have trails.
We use many contrib modules and have tried to adher to standard modules as much as possible. Almost all content types are built with CCK and we use Views for most data. For different language versions we use I18N and we have configured it to select the language based on the hostname.
We have maintained a rigid structure for our HTML and CSS for some time and have continued this into our Drupal solutions. We therefore have a master theme that contains our own template structure for the modules we use most. We can thereby ensure that our html is always of the same high standard and that we once and for all have created the template files in the master theme.
RootCandy admin theme
We use the Rootcandy theme for the administrator backend and can highly recommend this theme. This is a high quality theme that makes the Drupal backend significantly more professional and pleasurable to work with. We will therefore be sticking to this theme in the future.