-
Notifications
You must be signed in to change notification settings - Fork 39
Mail content using content helpers
The basic usage of this library allows you to send messages throwing simple strings as the text and/or html content at the respective methods. Sometimes, though, you may want to use some basic formatting that HTML provides but don't care about a full fledged complex HTML email template. Examples: add some bold text, create a link, format a basic table.
The classes on the package net.sargue.mailgun.content
are designed
to easily build basic HTML
messages. It's not supposed to be used for building cutting edge responsive
modern HTML messages. It's just for simple cases where you need to send a
message and you want to use some basic HTML like tables and some formatting.
Some self explanatory examples:
Mail.using(configuration)
.body()
.h1("This is a heading")
.p("And this some text")
.mail()
.to("[email protected]")
.subject("This is the subject")
.build()
.send();
Mail.using(configuration)
.body()
.h3("Monthly report")
.p("Report of the number of time travels this month")
.table()
.row("Marty", "5")
.row("Doc", "7")
.row("Einstein", "0")
.end()
.mail()
.to("[email protected]")
.subject("Monthly Delorean usage")
.build()
.send();
Of course you can keep the body content and mail building separated.
Body body = Body.builder()
.h1("This is a heading")
.p("And this some text")
.build();
Mail.using(configuration)
.to("[email protected]")
.subject("This is the subject")
.content(body)
.build()
.send();
The main class is the Builder
which you use to construct a Body
using a fluent interface. Like this:
Body body = Body.builder()
.h1("This is a heading")
.p("And this some text")
.build();
A Body
is really just a tuple with two strings: the text version and the HTML version. When you are building your mail using MailBuilder
you have the MailBuilder#content()
method which accepts a Body
. Completing the example:
Mail.using(configuration)
.to("[email protected]")
.subject("This is the subject")
.content(body)
.build()
.send();
Most of the time you would probably build the content, the email and send it. So you can chain it an get a nice fluent conversation.
Mail.using(configuration)
.body()
.h1("This is a heading")
.p("And this some text")
.mail()
.to("[email protected]")
.subject("This is the subject")
.build()
.send();
As said before this is for very simple formatted messages. Most email clients can read basic HTML but the proper way is to include also a text only version. Even if it, probably, won't be used. These classes take care of that just by generating both text and HTML versions of the orders you give. Most of the time the text version is just the content. You ask for emphasis of a text? The HTML will go <em>Hello world</em>
but the text version will go just like Hello world
. The aim is to be readable not an accurate representation of the formatting. No fancy ASCII tricks here.
You will find several common HTML tags in the Builder
class. Most accept content directly or can be called without parameters if you need more complex content or to nest other directives. Remember to close your tags calling end()
.
Example of heading with direct content and nested content. They produce the same result:
Body.builder()
.h1("This is the heading")
.build();
Body.builder()
.h1()
.text("This is the heading")
.end()
.build();
There is some basic support for tabular data. The basic expected tags for table
, tr
, and td
are there along with some shortcuts. There are shortcuts for rows of size up to 4 columns.
A simple example:
Mail.using(configuration)
.body()
.h3("Monthly report")
.p("Report of the number of time travels this month")
.table()
.row("Marty", "5")
.row("Doc", "7")
.row("Einstein", "0")
.end()
.mail()
.to("[email protected]")
.subject("Monthly Delorean usage")
.build()
.send();
There is also the method rowh(String label, T data)
which I've found particularly useful when building basic HTML messages to output tabular data. For example, you have a customer, Michael, and inside an HTML email you want to show data about him.
You expect to create something like this:
Label | Data |
---|---|
ID | 2356 |
Name | Michael |
Address | 9303 Lyon Drive, Lyon Estates |
So you can build it in a compact way like this:
Mail.using(configuration)
.body()
.table()
.rowh("ID", 2356)
.rowh("Name", "Michael")
.rowh("Address", "9303 Lyon Drive, Lyon Estates")
.end()
.mail()
.to("[email protected]")
.subject("Come see my home!")
.build();
If you really need specific HTML written to the output you can use the tag
methods. Just remember to always close every tag
invokation with a end
invokation.
An example to write some colored text using the style
attribute.
Body.builder()
.p()
.text("Hello world ")
.tag("span", "style='color:red'")
.text("in color")
.end()
.end()
.build();
This will render this HTML.
<p>Hello world <span style='color:red'>in color</span></p>
All the content we are formatting and putting together in an email is basically text. But most data won't be directly text so we need to format it. Numbers, dates, currency amounts...
You certainly can format it when appending it into the message but you can also use the content converter facility.
Content converters allows you to register any number of content converters associated with a Java class. That converter will be used when calling the generic method Builder#text(T value)
.
Sample usage:
Date date = new GregorianCalendar(1985, 9, 26, 1, 22).getTime();
Configuration cfg = new Configuration();
ContentConverter<Date> converter = new ContentConverter<Date>() {
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
@Override
public String toString(Date value) {
return df.format(value);
}
};
cfg.registerConverter(converter, Date.class);
Body body = Body.builder(cfg)
.text(date)
.build();
assertEquals("26/10/1985" + emptyText, body.text());
As you can see the converters are registered to the Configuration
. Internally, they are matched in declaration order checking for assignability (inheritance). So you can have a a Date
converter which will be applied to a Timestamp
object. You will want to register the more specific converters first.
The default converter is always the last one and accepts any Object
. It just calls Object#toString()
.