Simplenews: Style & Custom Theme a newsletter with table layout

Last updated on
12 September 2019

The Drupal 6.x version of Simplenews has full support for CCK template files, for Drupal 5.x it is not possible to use the normal .tpl.php files to make a custom theme for the output of the newsletter, so you have to use contemplate instead.

For Drupal 6

In the simplenews module there are 4 tpl.php files available. One for the block, status, body and footer. The body and footer are the most important ones. They also allow you to style each newsletter in a completely different way.

If you have a newsletter with tid 1126 then copy the body and footer tpl.php files and put them in your admin theme folder and rename them to: simplenews-newsletter-body--1126.tpl.php and simplenews-newsletter-footer--1126.tpl.php. With these you can style the body and footer of newsletter 1126.

Contemplate is not needed for Drupal 6. Use these template files instead. Don't forget to clear the (theme registry) cache.

The contents of those template files are the same as explained in this tutorial which was originally written for Drupal 5.

For Drupal 5

The following instructions describe how you can theme your newsletter with a table and multiple cck fields using the contemplate module for theming the email output. I will also explain how to theme the newsletter add/node form and UI to get a uniform look in input and output.

I will also show how to use nodereference fields to output full nodes, links to nodes or certain fields in a simplenews newsletter, so you can easily assemble content from the whole site.

In this tutorial we will *not* use the "Simplenews template" module as that modules gives you only a header and footer, which is OK for simple designs, but not sufficient for more complex table based designs of newsletters.

Click here for an example of the edit newsletter screen

Click here for the corresponding newsletter

Part 1: Design and preparations

  1. Make the design of your newsletter in xhtml/css and test it in several email clients. You will notice that even Internet Explorer 6 does a very good job compared to most email clients. You will have to use tables (and probably even nested tables) for your layout, preferably no background images, a width of about 600px and inline css. Check the code of some newsletters with nice designs you receive.
  2. Install Simplenews, Mimemail, CCK, Tinymce, IMCE, Contemplate modules. Mimemail has been very badly maintained over the past two years and is still in alpha with plenty of bugs. If you are using Mimemail and have php code in your templates you need to set the input format for mimemail to php code at admin/settings/mimemail.
  3. The htmlmail module has become mature and is a recommended alternative for mimemail. The emogrifier option, which can take some css code inline, is very handy to save on template files. Install the rel_to_abs module if you use a wysiwyg editor with htmlmail so links become absolute.

  4. The Drupal mimemail module allows you to create a file your current theme called mail.css (for instance, sites/all/themes/YOURTHEME/mail.css) with css code for the newsletter (and other emails send by the system!), but this external css will only have effect in desktop based email clients. Web based email clients like Hotmail, Gmail and Yahoo remove all css which is not inline (so no external files, or
    definitions possible). The reason they do so is to prevent that your newsletter css would change completely the Hotmail, ... interface itself. If you want a newsletter without external css, you can create an empty mail.css file. For more information about the html and css output of mimemail see http://drupal.org/node/291762.
  5. Determine which parts of your newsletter you will make CCK fields of and what kind of fields you will need for titles, text, links.... I used text fields and nodereference fields. For images we will use the image uploading and resizing functionality of TinyMCE. I tried imagefield, and it worked only half: the image did not display in the email and imagecache did not apply correctly, so some work is needed if you would prefer imagefield instead of the editor. For links I'm using two text fields: one for title and one for url (see next part why).

Part 2: Output of the newsletter

  1. TinyMCE: Add in visibility node/add/simplenews and node/*/edit to the url list where the editor is visible.
  2. IMCE: Allow resizing of images, I used imagefields in the rest of the site, and had only two image sizes in the newsletter so adjusted the settings of IMCE so all images were resized to 330px x 330px (the main image had a width of 330px) and IMCE thumbnails to 210px x 210px (the images in the right column had a width of 210px). Of course if you know about pixels you could easily put these values yourself into the resize field but this user interface is rather meant for a end user that does not (want) to know/remember about pixels. Add help text to explain which image option to choose.
  3. CCK: Remove Body and build all the textfields, textareas and nodereference fields which you will need. Choose for the nodereference fields which content types you would like to have in the select list. If you would like to have a list of links to nodes in your newsletter choose "multiple" for the nodereference field. If you want to output full nodes in your newsletter, go to display fields of the nodereference field and choose "full node".
  4. Go in admin to Content templates (admin/content/templates/simplenews) click on edit for the one of simplenews, click to "replace body output", copy and paste the full body output in a temporary file and save the file as a copy of the original body just to have the variables ready.
  5. Make a directory sites/all/contemplates and put a file in there with name node-simplenews-body.tpl.php. Check at admin/content/templates/simplenews if you see the message "This template is being read from sites/all/contemplates/node-simplenews-body.tpl.php . Please make changes to this file or remove it to continue editing here." so you are sure your content template file is working. Copy and paste the html body of the newsletter you made in part 1 in that file and replace the static parts of the newsletter that need dynamic content with the variables that you have in the original contemplate body. This file determines the layout of your newsletter in the email.
    1. For text fields this is something like print $node->field_nieuwsbr_actie[0]['view']
    2. The nodereference fields are very handy to output links to nodes or the full content or teaser of nodes in your newsletter. I did not test the teaser display for the nodereference, but think it is the way you could use if you want to output only specific cck fields of the node. You should specify in the display settings of the content type which fields you want to have visible in the teaser. Then by choosing "teaser" in the display settings of the nodereference field you should get only those specified fields of the node in your newsletter. Be careful as this will influence teasers of that content type in the rest of the site also of course (but there you could use views and views theming to display fields of a node).
    3. For links I'm not using the link field as the css in a newsletter is inline, so it is better to make a text field for link title and another one for the link url and add them like: <a href="http://<?php print $node->field_nieuwsbr_extra_link[0]['view'] ?>" target="_blank" style="padding: 2px; background-color: #999999; color: #ffffff; text-transform:uppercase;"><?php print $node->field_nieuwsbr_extra_lktitel[0]['view'] ?></a>
    4. To get automatically generated lists of content, you can also output views (for instance a view of a nodequeue) by adding the following code to node-simplenews-body.tpl.php:
      // Get the view NewsletterArticlequeue
      $view = views_get_view('NewsletterArticlequeue');
      // check if the view exists and if so output the view
      if(!empty($view)){ 
      print '<h2>Featured articles</h2>';
      print views_build_view('block', $view);
      }
      
      A teaser view does not work perfect out of the box as the links (read more, printfriendly version, share, ...) are printed as well which does not look good in a newsletter. Use a list view with title and body as fields. Select for the body field "teaser" as option to get the teaser part of the body. That way you don't have the links.
      A list view is easy to style in Drupal 5 as you can use views theming to theme the list view via an additional template file.
      For a table view you might want to add some extra css styles inline to the html of the table and td tags, for instance to make sure that the first column of your table has a width of 150px and has a bold font.
      This can be easily done by overriding the theme function for the view and adding the style to the td: $row[0]['style'] .= 'width:100px; font-weight:bold;'; or you can add inline css styles to the table element return theme('table', $view->table_header, $rows, array('style' => 'width:100%;')); The complete override to be pasted in template.php for a view called NewsletterTable is:
      /**
       * Display the nodes of a view as a table. Added extra inline styles to td and table elements
       */
      function phptemplate_views_view_table_NewsletterTable($view, $nodes, $type) {
        $fields = _views_get_fields();
      
        foreach ($nodes as $node) {
          $row = array();
          foreach ($view->field as $field) {
            if ($fields[$field['id']]['visible'] !== FALSE) {
              $cell['data'] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $node, $view);
              $cell['class'] = "view-field ". views_css_safe('view-field-'. $field['queryname']);
              $row[] = $cell;
            }
          }
      
      	// Add some inline css styles to the td of the first column 
      	$row[0]['style'] .= 'width:100px; font-weight:bold;';
              // Add some inline css styles to the td of the second column
      	$row[1]['style'] .= 'font-style:italic; font-size:12px;';
      
          $rows[] = $row;
        }
      
        // Add some inline css styles to the table tag
        return theme('table', $view->table_header, $rows, array('style' => 'width:100%;'));
      
      }
      
  6. Paste the whole static body part of your newsletter design in the body part of the content template
  7. Now you should have a newsletter where you can add titles, text, images, links to nodes or full nodes. Test to check. You could stop here if you are satisfied, but I find it nicer if the user interface, the node/add/simplenews page is in the same design as the newsletter itself.

Part 3: Style the UI: the newsletter input form

  1. Make a file node-simplenews-edit.tpl.php and put it in your theme folder
  2. Add the following code to template.php to connect this template file for your simplenews newsletter edit form:
    <br />
      function phptemplate_node_form($form) {
        if ($form['#node']->type == 'simplenews') {
        return _phptemplate_callback('node-simplenews-edit', array('form' => $form));
        }
        else {
        return theme_node_form($form);
        }
        }
        
  3. Copy the newsletter code from the body part of the contemplate (or the file where you took it from) and paste it here.
  4. Remove any parts you don't need here (I removed the link on top of the newsletter with the link to the node if your email client cannot read the newsletter).
  5. Replace all parts that have dynamic content with the corresponding drupal_render code:
    Example: print $node->field_nieuwsbr_actie[0]['view'] becomes print drupal_render($form['field_nieuwsbr_actie']['0']['value']);
  6. I could not print out the multiple nodereference fields this way so to make it easy I just wrapped them in a group and printed the input of the group. It's a workaround, so if anybody knows how to drupal_render nodereference fields (or image fields) let me know. With the "group workaround" just go to content types, add a group for each nodereference field and put that field inside the group. Then just drupal_render the group: print drupal_render($form['group_promoties']);
  7. Put print drupal_render($form); after the newsletter code to output the rest of the simplenews fields. Wrap it in a div if you need some margin, padding or background or make an extra row in your table design.
  8. Go to node/add/simplenews to check if it looks ok. Add a class to the main table if it is necessary to fix some margins or paddings. This is no longer an email so you can use external css files again.
  9. Send a newsletter to check.

Part 4: Style the online version of the newsletter

  1. Make a link on top of your newsletter, something like "Cannot read this newsletter? click here", with a link to the node of this newsletter (check variables in content template): <a href="http://www.example.com/node/<?php print $node->nid ?>" target="_blank">click here </a>
  2. Make a file node-simplenews.tpl.php and put it in your theme directory.
  3. Style node-simplenews.tpl.php the usual way.

Help improve this page

Page status: No known problems

You can: