Creating an email newsletter using SimpleNews and phplist



Similar documents
Interspire Website Publisher Developer Documentation. Template Customization Guide

Essential HTML & CSS for WordPress. Mark Raymond Luminys, Inc mraymond@luminys.com

So you want to create an a Friend action

css href title software blog domain HTML div style address img h2 tag maintainingwebpages browser technology login network multimedia font-family

Joomla! Actions Suite

Using your Drupal Website Book 1 - Drupal Basics

Building Your First Drupal 8 Company Site

The Essential Guide to HTML Design

Introducing our new Editor: Creator

JJY s Joomla 1.5 Template Design Tutorial:

JTouch Mobile Extension for Joomla! User Guide

Table of Contents. What is ProSite? What is Behance? How do ProSite & Behance work together? Get Started in 6 Easy Steps.

Joomla! template Blendvision v 1.0 Customization Manual

Inspiring Creative Fun Ysbrydoledig Creadigol Hwyl. Web Design in Nvu Workbook 1

Scoop Hosted Websites. USER MANUAL PART 4: Advanced Features. Phone: scoop@scoopdigital.com.au Website: scoopdigital.com.

Configuring the JEvents Component

Manage Website Template That Using Content Management System Joomla

BT CONTENT SHOWCASE. JOOMLA EXTENSION User guide Version 2.1. Copyright 2013 Bowthemes Inc.

Content Author's Reference and Cookbook

User Guide for Smart Former Gold (v. 1.0) by IToris Inc. team

Coding HTML Tips, Tricks and Best Practices

HTML and CSS. Elliot Davies. April 10th,

A send-a-friend application with ASP Smart Mailer

A quick guide to. Social Media

The Essential Guide to HTML Design

How To Change Your Site On Drupal Cloud On A Pcode On A Microsoft Powerstone On A Macbook Or Ipad (For Free) On A Freebie (For A Free Download) On An Ipad Or Ipa (For

css href title software blog domain HTML div style address img h2 tag maintainingwebpages browser technology login network multimedia font-family

Installing and Using Joomla Template Created with Artisteer

Citrix StoreFront. Customizing the Receiver for Web User Interface Citrix. All rights reserved.

Startup Guide. Version 2.3.9

OPENTABLE GROUP SEARCH MODULE GETTING STARTED ADD RESERVATIONS TO YOUR WEBSITE

We automatically generate the HTML for this as seen below. Provide the above components for the teaser.txt file.

CMS Training Manual. A brief overview of your website s content management system (CMS) with screenshots. CMS Manual

MAGENTO THEME SHOE STORE

Software User Guide. WordPress Plugin Version 1.0

Do I have to use the blog section of the site? No. Your blog is hidden by default so it won't be available unless you choose to turn it on.

Caldes CM2: Marketing s Support Document v1.12

RESPONSIVE DESIGN BY COMMUNIGATOR

Hypercosm. Studio.

MASTER DRUPAL 7 MODULE DEVELOPMENT

Terms and Definitions for CMS Administrators, Architects, and Developers

Lisa Sabin-Wilson WILEY. Wiley Publishing, Inc.

The easy way to a nice looking website design. By a total non-designer (Me!)

This guide provides additional information about topics covered in the webinar

WP Popup Magic User Guide

Creating a Restaurant Website

Sitecore InDesign Connector 1.1

Shopping Cart Manual. Written by Shawn Xavier Mendoza

Content Author's Reference and Cookbook

!!!!!!!! Startup Guide. Version 2.7

MARKETING BEST PRACTICES.


Sense/Net ECM Evaluation Guide. How to build a products listing site from the scratch?

Web Design Basics. Cindy Royal, Ph.D. Associate Professor Texas State University

PASTPERFECT-ONLINE DESIGN GUIDE

Recreate your Newsletter Content and Layout within Informz (Workshop) Monica Capogna and Dan Reade. Exercise: Creating two types of Story Layouts

Build Your Mailing List

How To Customize A Forum On Vanilla Forum On A Pcode (Forum) On A Windows (For Forum) On An Html5 (Forums) On Pcode Or Windows 7 (Forforums) On Your Pc

RADFORD UNIVERSITY. Radford.edu. Content Administrator s Guide

Building A Very Simple Website

GETTING STARTED WITH DRUPAL. by Stephen Cross

CREATING AND EDITING CONTENT AND BLOG POSTS WITH THE DRUPAL CKEDITOR

Drupal CMS for marketing sites

Salesforce Customer Portal Implementation Guide

Joomla! template JSN Mico Customization Manual

The Social Accelerator Setup Guide

Contents. Downloading the Data Files Centering Page Elements... 6

Web Authoring CSS. Module Descriptor

Mail Programming Topics

User Guide. Chapter 6. Teacher Pages

Development Perspective: DIV and CSS HTML layout. Web Design. Lesson 2. Development Perspective: DIV/CSS

Kentico CMS, 2011 Kentico Software. Contents. Mobile Development using Kentico CMS 6 2 Exploring the Mobile Environment 1

Designing portal site structure and page layout using IBM Rational Application Developer V7 Part of a series on portal and portlet development

Web Design and Databases WD: Class 7: HTML and CSS Part 3

Dreamweaver and Fireworks MX Integration Brian Hogan

Last week we talked about creating your own tags: div tags and span tags. A div tag goes around other tags, e.g.,:

Developers Guide. Designs and Layouts HOW TO IMPLEMENT WEBSITE DESIGNS IN DYNAMICWEB. Version: English

ConvincingMail.com Marketing Solution Manual. Contents

Design principles of the Drupal CSC website

Flare Tips and Tricks. Tips and tricks. Importing content Lists. Variables and snippets Condition tags Printed documentation WebHelp.

Content Management Software Drupal : Open Source Software to create library website

Joomla User Manual, Version 1.5

Joostrap RWD Bootstrap Template

BASICS OF WEB DESIGN CHAPTER 2 HTML BASICS KEY CONCEPTS COPYRIGHT 2013 TERRY ANN MORRIS, ED.D

Global Preview v.6.0 for Microsoft Dynamics CRM On-premise 2013 and 2015

Dashboard Skin Tutorial. For ETS2 HTML5 Mobile Dashboard v3.0.2

Advanced Web Development SCOPE OF WEB DEVELOPMENT INDUSTRY

Campaign Guidelines and Best Practices

Volunteers for Salesforce Installation & Configuration Guide Version 3.76

GUIDE TO CODE KILLER RESPONSIVE S

Transcription:

Creating an email newsletter using SimpleNews and phplist Maurice Tomkinson (maurice@hopestreetcentre.co.uk) Versions: Drupal Core: 6.22 Simplenews: 6.x-2.x-dev PHPlist: 6.x-1.x-dev I ve been working on adding mailing list functionality to my web site, and it s taken me several weeks to put together a setup that I m happy with. I found quite a lot of help out there on the forums and blogs, but it comes in small chunks, so I thought it might be helpful to others who trying to do something similar if all the steps were drawn together in one place. This is only one of many possible solutions it worked for me, whether it is good for you will depend on what you are setting out to achieve. I wanted to keep my mailing list separate from my Drupal users list, which determined my choice of packages in the end. I started with Simplenews, and liked the way it allowed me to select a list of content nodes from my site, add a table of contents, sort it into a logical order, and assemble it into a newsletter. Starting with existing content, the time taken to assemble an acceptable newsletter is a matter of minutes. What I wasn t happy with was that Simplenews used Drupal s user membership mechanism to manage its mailing lists. Fine for a small group of colleagues, but I m aiming for thousands of subscribers, and I don t want them all logged into Drupal, where a slight error on the permissions table could give them all editing capabilities on my site! I therefore looked into external mailing list engines and came across the PHPlist application, which has an integration module for Drupal (also called PHPlist). Unfortunately as far as I can tell this integration module lacks the content selection capabilities of Simplenews. It has a mechanism for passing the URL of a node to PHPlist, but due to some problem (presumably with my hosting platform) I couldn t get PHPlist s URL placeholder to work. I don t think this is anything to do with Drupal, other PHPlist users who use the package independently of Drupal are reporting similar problems, but I spent many hours trying to find a solution without success. Before giving up on PHPlist I went down the track of trying to use RSS the application has a mechanism for importing an RSS feed and turning it into a newsletter, which would have been great if I could get it to work. Unfortunately I had problems with RSS too PHPlist would accept some feeds but display unhelpful error messages with others. Because the support for PHPlist is not great there isn t the sheer volume of problem reports and fixed that Drupal has I eventually gave up on RSS too. I then realised that I didn t have to use either of these mechanisms. A small tweak to PHPlistbackend.module would allow me to send the full HTML of my content to PHPlist rather than a URL placeholder. I achieved this by modifying the function PHPlistbackend_nodeapi as follows: 'message' => '[URL:'. $url. ']', becomes 'message' => $node->content['body']['#value'],

and $message['message'] = '[URL:'.$url.']'; becomes $message['message'] = $node->body; This allows the full content of my newsletter node to be fed into PHPlist s message database. To make this happen I rely on the PHPlist integration module s features. I won t discuss setting up the PHPlist module as its configuration pages under Site Configuration > PHPlist are self-explanatory, but it s worth noting that the switch to enable its functionality on a specific content type is hidden in the Workflow Settings drop-down (which took a while to find in the documentation). I m actually using a content type called Newsletter issue which was created for me when I installed Simplenews, and has a machine-readable type of simplenews. Thus both modules access the one newsletter content type. I have noticed that there is a warning in the documentation that there may be a compatibility problem between Simplenews and the PHPlist module, and the advice is not to use the two modules together. Perhaps it s because I only use limited functionality of both modules, but I haven t come across this problem yet. Enabling the workflow setting Send as newsletter for the Newsletter issue content type then exposes a set of Newsletter options on the editing page for the Newsletter issue node. These are Newsletter status, Senddate and Lists. The lists selection is the only one I use, and it is populated from the mailing lists created in the PHPlist application itself. One of these has to be selected or the newsletter can t be saved. As soon as Save is clicked on a newsletter issue the PHPlist integration module gets to work and puts the node content into the PHPlist database. It is now ready for sending by the PHPlist application. So by this point I had a mechanism for going from content nodes to newsletter via Simplenews, and newsletter to mailshot via the PHPlist application and its Drupal integration module. So far so good. Unfortunately the newsletter didn t look the way I wanted it and the images in my content nodes were missing. It was time for some theming. I m using the theme blogbuzz, and I therefore have a directory sites/all/themes/blogbuzz which contains the theming information. In there is a file called template.php, and it is this file I modified to do all my customisation. I m not sure if that s the right place, but it worked for me! The starting point for customising the Simplenews newsletter format is in the sites/all/modules/simplenews_content_selection directory and a file called scs.theme.inc. In there is a function called theme_scs_node_output which looks like this: /** * Each selected node goes true this function to create a nice body */ function theme_scs_node_output($node) $output = ''; $output = '<div id="node_'. $node->nid. '">'; $output.= '<h1>'. $node->title. '</h1>'; $output.= '<p>'. node_teaser($node->body). '</p>'; $output.= '<p>'. l(t('read more'), 'node/'. $node->nid). '</p>';

return $output; Following instructions I pasted this into my above-mentioned template.php and renamed it blogbuzz_ scs_node_output. If you are using a different theme you will replace blogbuzz with your theme s name. Later I also ended up overriding a second theme function theme_scs_newsletter_output which I copied and renamed in a similar way. To get Drupal to recognise these new functions the Theme Cache needs to be refreshed (easy to forget!) Eventually I realised that once Drupal has recognised the new functions it s not necessary to keep refreshing the cache every time you change the PHP code. Getting the images to appear was much harder than I expected. Drupal has more than one mechanism for displaying images, and if you re looking at code snippets it s easy to get confused about which one is which. A lot of the snippets relate to CCK ImageField objects which are inserted into content types using the Manage Fields mechanism. I don t do it this way, I use Image Attach, and the problem is that the two mechanisms are coded differently, so that a piece of code that works for one won t work for the other. The images created by the Image Attach mechanism are stored as separate nodes, and the content node just stores a nid for the image node. To get the image node ($image) from the content node ($node) I use the code: $image = node_load($node->iids[0]); Another thing to remember about Image Attach is that it doesn t store one picture, but many of different sizes. This is controlled by the settings page Site Configuration > Images > Files and Sizes. By default there are three sizes, Original, Thumbnail and Preview, but none of these were the size I wanted so I created another size called Newsletter which I scaled to 250x250. The relative URL for this new image size can be obtained by this line of code: $imageurl = $image->images['newsletter']; One small quirk here I found that although the name of the size newsletter has an initial capital in the Files and Sizes page it needs a lower case string to access in the code. Another thing to remember is that once your content leaves Drupal and flies off into the aether any relative URLS will be broken, so $imageurl needs to be converted to an absolute URL so that your email can retrieve it from your site. Drupal provides a built-in function url() to do this: $absimageurl = url($imageurl, array('absolute'=>true)); In passing, I should mention that printing out the node contents in a comment helped a lot while I was working out what was going on. The following code snippet does this ($output is the string that stores the newsletter content as it s being created, and you can replace $node with any object you like): $output.= '<!--' ; // treat the output as a comment $output.= print_r ($node, TRUE); // output the contents of $node $output.= '-->'; // close the comment block

The comment block can then be viewed by switching to Source mode (if you have it) in your WYSIWYG editor. When Simplenews has created a newsletter it stores it in a newsletter node and opens up an editing page so that you can make any adjustments you want. Unfortunately I discovered that the HTML that was appearing in my editor was different to the HTML that my PHP code was emitting. Unwanted tags were appearing all over the place! I use CKEditor as my WYSIWYG plugin, and although I can t be totally sure it appears that CKEditor was taking it upon itself to modify my HTML. This mainly affected font styles and anchor tags. What should have been: <DIV><H1>My Newsletter</H1></DIV> was coming out as <DIV><H1><SPAN style="font-family: serif; FONT-SIZE: 12px">My Newsletter</SPAN></H1></DIV> The additional SPAN tag was overriding the font size that I wanted, and there seemed to be nothing I could do about it! Eventually I discovered that it was better to remove all the CSS formatting (eg. the <H1> tags) and substitute inline formatting, because the CSS can get ignored by email clients. Once I removed the CSS and inserted my own style instructions, CKEditor seemed to settle down and leave my code alone. Another problem with CKEditor was with anchor tags. Once of the nice features of Simplenews is that it provides an optional contents list, with local links to anchors in the body of the newsletter. The way it does this is to emit a <DIV> tag with an id at the start of each component node, and sets up a jump using an <A> tag from the contents list: <A href="#node_192">contents list link to node 192</A> should jump to <DIV id= node_192 Unfortunately, although this is technically correct, CKEditor seems not to like the id in a DIV statement, and responds by expanding href= #node_192 to href= http://example.com/node/401/edit#mode_192. If an email reader clicked on this link it would take them back to editing the newsletter! (Hopefully they wouldn t have the permission to do so, but it s very messy!) After much trial and error I found that replacing the id in the DIV tag with an alternative HTML form: <A name= node_192 > kept CKEditor happy and stopped it trying to convert my href to an absolute URL. As one final touch I created a pair of unpublished nodes on my site to contain a header and a footer for the email (so much eaiser to manage in Drupal than in the PHPlist application).

To summarise, the complete listing of customised code I produced is here: // Helper function to get node object from its aliased url function get_node_from_alias($pathalias) $pathsource = drupal_lookup_path('source', $pathalias); $temp = explode("/", $pathsource); $nid = $temp[1]; $node = node_load(array('nid' => $nid)); return $node; // blogbuzz_scs_node_output formats an individual node function blogbuzz_scs_node_output($node) $output = ''; $imagetag = ''; $image = node_load($node->iids[0]); $imageurl = $image->images['newsletter']; // Retrieve the url for the preview version $temp = 'node/'.$node->nid; $absurl = url($temp, array('absolute'=>true)); if (!empty($imageurl)) $imagetag = '<img src="'. url($imageurl, array('absolute'=>true)). '" />'; $output = '<div style="background-color:#fff5d2;">'; $output.= '<a name="node_'.$node->nid.'"></a>'; $output.= '<div style="background-color:#ccbbbb; padding-top: 5px; paddingbottom: 5px;">'; $output.= '<SPAN style="font-size: 20px; FONT-FAMILY: Georgia, \'Times New Roman\', Times, serif; color: #660000">'; $output.= l($node->title, $absurl); $output.= '</span></div>'; if (!empty($imageurl)) $output.= '<div style="float: right; margin-left: 1em;">'; $output.= l($imagetag, 'node/'.$node->nid, array('html'=>true)); $output.= node_teaser($node->body); $output.= '<br>' ; $output.= l(t('read more...'), $absurl); $output.= ' <div style="clear: both;"></div>'; return $output; // blogbuzz_scs_newsletter_output formats a complete newsletter. function blogbuzz_scs_newsletter_output($nodes, $toc) $body = ''; $contents = ''; $nodeheader = get_node_from_alias('newsletter/header'); $nodefooter = get_node_from_alias('newsletter/footer'); if ($nodeheader) $output.= $nodeheader->body; $output.= '<div style="background-color:#ccbbbb; padding-top: 5px; paddingbottom: 5px;">'; $output.= '<SPAN style="font-size: 24px; FONT-FAMILY: Georgia, \'Times New Roman\', Times, serif; color: #660000">'; $output.= 'My Newsletter<br>'; $output.= '</span></div>'; $titles = array(); foreach ($nodes as $node) // Node information $body.= theme('scs_node_output', $node);

if ($toc) // ToC (if required) $output.= '<p>table of Contents</p><div>'; foreach ($nodes as $node) // Node information $contents.= '<a href="#node_'. $node->nid. '">'. $node->title. '</a><br>'; $output.= $contents; $output.= $body; if ($nodeheader) $output.= $nodefooter->body; return $output;