Newsletter Themes

The Newsletter plugin provides two methods to create a newsletter: the composer where you drag and configure blocks (like Gutenberg) or selecting a theme which generates the full newsletter content at once (and the you can edit it).

Newsletter themes can be useful for quick newsletters creation, specially if you have a custom theme tailored to your communication needs and to your site style. While themes can be used for one click newsletter creation, the preferred way to compose an email is the block editor for which you can create custom blocks.

Packaged themes

Packaged themes are stored in the plugin folder  wp-content/plugins/newsletter/emails/themes and they can be used as starting point for your custom themes.

New themes MUST NOT be added to this folder (anyway on recent Newsletter plugin version they wouldn’t be loaded).

Later we’ll see how to add a theme to Newsletter, but before we need to understand how it is structured.

What is a theme and how is it structured?

Technically a theme is a folder. The folder name will be the unique identifier of the theme (so try to use an unique name, maybe add a personal prefix). Inside the folder there must be at least the theme.php file. As we see later, this is the file which generates the newsletter.

The file theme.php should start with a comment section with some keywords (like used on WordPress):

<?php
/*
* Name: My theme
* Type: standard
* Description: My great theme
*/

Other files in the theme folder could be:

  • theme-options.php – a special coded file to generate an options panel for that theme
  • screenshot.png – a 300×450 (no exceptions!) image representing the theme (.png only!)
  • theme-text.php – a php script which generates the textual version of the newsletter

Of course other files can be added as support for your theme, like PHP scripts, images and so on.

What should the theme generate?

It should generate a FULL HTML page (starting from the <DOCTYPE> and ending with </html>) containing an HTML correctly readable from email clients (which is not exactly what is usually coded for a regular webpage). It can contain tags (or placeholders) which are then replaced by Newsletter while sending the email to each subscriber and all reference to external element (usually only images are allowed by email clients) and all links MUST be full URLs.

Adding a theme in the extensions folder (method 1)

The first way to add a theme to Newsletter is to place its folder with its files inside:

wp-content/extensions/newsletter/emails/themes

for example, if your theme folder is named mytheme you’ll have the folder

wp-content/extensions/newsletter/emails/themes/mytheme

with inside at least the theme.php as seen above. The folder name mytheme is used as unique theme identifier hence you cannot use default as folder name since it conflicts with the packaged theme and will be ignored.

Registering a theme (method 2)

The preferred way to add a theme is to register it and this is the method plugin and WordPress theme developer should use. The theme structure does not change and you need a folder containing the theme (as before, the folder name will be the theme identifier). Then you should listen to the newsletter_register_theme action and:

add_action('newsletter_register_themes', function () {
  tnp_register_theme(ABSOLUTE PATH TO THE THEME FOLDER);
});

For example, if you’re a WordPress theme developer, you can add a sub-folders structure like newsletter/themes (you can reserve the newsletter/blocks for custom Newsletter composer blocks) and inside store the theme folder. If you name it, for example, mytheme1 in your function.php you can add:

add_action('newsletter_register_themes', function () {
  tnp_register_theme(__DIR__ . '/newsletter/themes/mytheme1');
});

of course you can register more than one theme:

add_action('newsletter_register_themes', function () {
  tnp_register_theme(__DIR__ . '/newsletter/themes/mytheme1');
  tnp_register_theme(__DIR__ . '/newsletter/themes/mytheme2');
});

How to add themes to an addon

Automated and Autoresponder addons support custom themes. To add a custom theme to those addons you need t use the method 1, storing it in the extensions folder, respectively:

wp-content/extensions/newsletter-automated/themes

and

wp-content/extensions/newsletter-autoresponder/themes

Merge and override is no more supported

The old possibility to override only a part of a theme files (like the theme-text.php) creating a special override folder IS NO MORE supported (to simplify the theme management and debug).

Newsletter provides a merge and override system for themes.

Theme CSS styling

As well as the basic structure and logic, the new version of Newsletter is different from previous versions by the fact that it no longer uses a ‘style.css’ file. I decided to remove it because themes now can have specific configuration options and sometime the CSS elements can be generated from configuration. So the style must now be embedded in the theme.php file itself. But remember that <style> section are most of the time ignored or not so well interpreted by email clients.

Anyway, emails cannot usually refer to external CSS, hence styles must always be embedded.

A second reason is that the resulting HTML is now fully stored on the database since the delivery engine is now “unrelated” to the module which generated the message (and how it generated it).

Important note about CSS

The CSS part of a theme must be uniquely identified by only one block of <style></style> tags. Newsletter only extracts the CSS once from the first set of <style> tags when passing the style information to the visual editor. Hence any other <style> tags elsewhere in the file will not be accessed.

Theme files: Nuts and Bolts

The theme.php file

The main theme file, and the only one required, must be named theme.php and is the one used to generate the HTML part of your emails. It is a normal PHP file that, when it runs, it must produce an HTML page. This file benefits from some PHP variables that are prepared by Newsletter that can be used to create dynamic content. These include:

  • $theme_options – is an associative array with theme options. Each key on this file must be prefixed by “theme_”. Theme options, as we see later, contains everything the theme needs to generate it’s content as configured by the user. A theme can have no options or tons of options.
  • $newsletter – is a reference to a Newsletter class instance for who need advanced functions.
  • $theme_url – is the URL to the theme base folder and should be used to refer images. Pay attention that if a theme is the merge of a packaged theme and a customization with its parallel folder, the URL point the theme folder inside the plugin, not the parallel version.
  • $theme_subject – is an empty variable you can use to “pass up” an alternative subject to the theme caller. It’s used to “suggest” a subject on newsletter composer

The theme-text.php file

This file acts identically to theme.php but must generate a plain text that will be used as textual (alternative) part of messages.

It is optional.

The theme-options.php file

Themes can have their own options, from colors to text, from ‘categories’ to ‘number of posts to include’.

Creating an options file does require some coding, but you can start from pre-packaged themes option files, to get you a quick start. More below.

Custom ‘Theme Configuration Panel’

Newsletter has a special class named ‘NewsletterControls’ which enables you to create input elements (text, textarea, list of categories, etc).

Within the theme-options.php file, an instance of this class is available in the variable $controls and should be used to build the theme configuration panel.

Really important! You must prefix all theme options with “theme_”: this way Newsletter can recognize them and store theme separately and linked to their theme.

Themes with the latest posts

A theme can generate a simple “static” page or embed the latest posts of the blog. It’s up to the theme to offer options to selected the post categories, the maximum number of posts and so on. Assuming a theme needs to create a post list it should:

  • extract the posts
  • cycle through them

The post cycle

While a WordPress theme uses the ”while have_posts(), the_post()” kind of loop on a Newsletter theme it’s better to use the combination of ”get_posts()” and “setup_postdata()”. That avoids the sticky posts, at least. The packaged themes, specially the default theme, is internally documented.

The cycle should look like:

<?php foreach ($posts as $post) { setup_postdata($post); ?>

The post list

The post list depends on the options a theme exposes to the user. Usually a theme should offer at least the selection of the categories and the maximum number of posts to display.

To extract the posts, just add to your theme the code you find on theme-1, which looks like:

$filters = array();
// Maximum number of post to retrieve
 $filters['showposts'] = (int)$theme_options['theme_max_posts'];
 if ($filters['showposts'] == 0) $filters['showposts'] = 10;
 // Include only posts from specified categories. Do not filter per category is no
 // one category has been selected.
 if (is_array($theme_options['theme_categories'])) {
 $filters['cat'] = implode(',', $theme_options['theme_categories']);
 }
// Retrieve the posts asking them to WordPress
 $posts = get_posts($filters);

As you can see, adding new options to your theme, you can totally change how the theme works and a study of the WP_Query class (of WordPress) should be the starting point to discover all type of filter available.

Custom post types

Many themes add new post types to WordPress. For example: product, topic, reply, forum, movie, and so on. WordPress only extracts its own (which are of type “post”. Anyway the filter for the get_posts() function can be changed to extract any kind of posts.

$filters['post_type'] = array('post', 'topic');

The above example extracts all standard WordPress ‘posts’ as well as bbPress topics.

Happy coding!



Have you ever considered going premium?

With a premium plan, you'll get whole collection of 30+ professional addons, along with a full year of updates and priority support. No automatic renewals, frequent releases and a solid 30 days refund policy.