B4J Library [BANanoMJML] - A Responsive Email Framework using the Abstract Designer

Mashiane

Expert
Licensed User
Ola

Download

Complete Youtube Playlist

Get details of latest tutorial projects here

NB: Ensure that you have unique names for the components on the designer

In other news: This library has been purely created with the BANanoCVC (CustomViewCreator)

This has been one of my bucket list things, the ability to create response emails. We will take a step by step approach into creating a variety of responsive emails that you can send to customers etc. This library is based on MJML, we will build it as we go along and then release it.

Whilst there are tools like this on the interweb, some cost money (whilst based on the original MJML framework) and some not. So I wondered if this could be done.

I managed to find another library created by someone else that helps wrap MJML inside a browser as its built for NodeJS.

The first project.

project1.png


For our first project, we will create some basic components which we will later compile to HTML for sending via email. To do this we fire our abstract designer and drag and drop some components to it.

bananomjml - master.png


Reproduction

1. Drop a MJApp on a new layout, give it a name of emailapp.
2. Drop a MJBody inside the MJApp, give it a name of emailbody.
3. Drop 6 MJSections inside the MJBody, these will will name companyheader, imageheader, introductiontext, twocolumnsection, icons and socialicons.
4. These will have a background-color of #f0f0f0, #f0f0f0, #fafafa, white, #fbfbfb and #f0f0f0 respectively
5. Save the layout as myemail.

Creating Company Header
Creating the Image Header
Creating the Intro Text
Creating the 2 columns Section
Creating Icons
Creating Social Sharing Buttons

#FirstProjectConcluded
 
Last edited:

Mashiane

Expert
Licensed User
Building the Company Header

We create a new layout via the abstract designer, we will save this as ch

1. Drag n drop a MJColumn on the designer stage.
2. Drag n drop a MJText inside the MJColumn

You should have this..

ch.png


Update the Caption, color, fontsize, fontstyle to meet your needs. We now need to inject this layout inside the company header on the master layout named myemail.

Lets go to the code..

1. We generate members from the abstract designer for out myemail layout. This gives us..

B4X:
Private companyheader As MJSection
    Private emailbody As MJBody
    Private icons As MJSection
    Private imageheader As MJSection
    Private introductiontext As MJSection
    Private socialicons As MJSection
    Private twocolumnsection As MJSection
2. We need to build our responsive emails, lets initialize the library and then get the compiled html for our email from mjml.

B4X:
Sub Init
    'initialize the app
    MJMLApp.Initialize
    'load the main layout
    BANano.LoadLayout("#template", "myemail")
    'load the ch to 
    companyheader.Element.LoadLayout("ch")
    'get the overall template for our email
    Dim stmp As String = MJMLApp.template
    'lets compile it to HTML
    Dim window As BANanoObject = BANano.Window
    Dim mjml As BANanoObject = window.getfield("mjml")
    Dim mjml2html As BANanoObject = mjml.GetField("default")
    Dim Response As Map = mjml2html.Execute(Array(stmp))
    Dim html As String = Response.get("html")
    Log(html)
    
End Sub
3. The log(html) call should be able to provide us with the current look and feel of our email. From the console, this is what we get so long...

html preview.png


This is the html that needs to be sent via email (whether php or otherwise to). What we need to do is to inject this to an iframe so that we can see how our email looks like so long and also send it as a test email.

#watch this space!
 

Mashiane

Expert
Licensed User
Preview the Company Header

NB: Refresh the shown web page a couple of times after compilation to show the output


1. Anyway, we will want to send the generated HTML file as is, so its just better to save it. To do this we fire BANanoPHP.

We get the html content and then save it to the root of our server app.

B4X:
'get the html content for the email
    Dim shtml As String = MJMLApp.HTML
    '
    'we will save the file externally
    Dim bPHP As BANanoPHP
    bPHP.Initialize
    BANano.CallInlinePHPWait(bPHP.FILE_WRITE, bPHP.BuildWriteFile("./myemail.html", shtml))
We also ensure that in our library we add an iframe that will take the whole screen and will show the email.

B4X:
body.Append($"<iframe id="emailframe" width="100%" height="100%" frameborder="0" src="./myemail.html"></iframe>"$)
When we run the demo now and refresh the browser, we are able to see the skeleton of what we want to achieve.

emailoutput.png


For now this concludes the Company Header. Let's move to the next section of the email.

Yippie!!!!

PS: As we want everything to happen internally in the library, we changed a few things..

B4X:
Sub Init
    'initialize the app
    MJMLApp.Initialize
    'load the main layout
    BANano.LoadLayout("#template", "myemail")
    'load the ch to 
    companyheader.Element.LoadLayout("ch")
    
    'save the email
    MJMLApp.Save
End Sub
So the file is written to disk.

1598290782911.png
 
Last edited:

Mashiane

Expert
Licensed User
Creating the Image Header

The image header as an image, some text and a button. We need to create these for our email. For images, its always better if these are accessible on the interweb.

1598292331051.png


1. Create a layout, name it ih (i.e image header)
2. Drag and drop a MJColumn and give it a unique name, set its width to 600px.
2. Drag and drop a MJText inside the MJColumn, set its attributes with align="center", color="#fff", font-size="40px", font-family="Helvetica Neue". Also set its caption to be what you want, we will use 'My Slogan Here'
3. Drag and drop a MJButton inside the MJColumn after the MJText, set its attributes with background-color="#F63A4D", href="#" and the caption should be "Promotion"
4. We have this as ih.
4. Now we need to set the background image on the master email layout. Set the following properties for the imageheader component in myemail layout, background-url="http://1.bp.blogspot.com/-TPrfhxbYpDY/Uh3Refzk02I/AAAAAAAALw8/5sUJ0UUGYuw/s1600/New+York+in+The+1960's+-+70's+(2).jpg", background-size="cover" and background-repeat="no-repeat"

Now we need to load ih inside the imageheader component, lets fire this..

B4X:
'load the image header
    imageheader.Element.LoadLayout("ih")
Now after updating, our code should be like this:

B4X:
Sub Init
    'initialize the app
    MJMLApp.Initialize
    'load the main layout
    BANano.LoadLayout("#template", "myemail")
    'load the ch to
    companyheader.Element.LoadLayout("ch")
    '
    'load the image header
    imageheader.Element.LoadLayout("ih")
  
    'save the email
    MJMLApp.Save
End Sub[code]

Now when we run this app, this is what will be generated for our email, so far we are going well..

[ATTACH type="full"]99046[/ATTACH]
 

Attachments

Last edited:

Mashiane

Expert
Licensed User
Creating the Intro-Text

When we are done creating the introduction text, we should see something like this. As you can see, we are very close to finishing this particular email.

introtext.png


The intro text shows My Awesome Text and a LoremIpsum. We fire the abstract designer, add a MJColumn, some MJTexts and a MJButton. We have dome something similar before.

1. Drag and Drop a MJColumn and set its width to 400px.
2. Drag and Drop a MJText inside the MJColumn and set its attributes as:

font-style="italic"
font-size="20px"
font-family="Helvetica Neue"
color="#626262"
the caption should be My Awesome Text

3. Drag and drop another MJText inside the new MJColumn we have created. Set its attributes to be

color="#525252" and in the property bag, check LoremIpsum. This will generate a LoremIpsum for the Text

4. Drg and Drop a MJButton inside the MJColumn and set its attributes to be

background-color="#F45E43" and
href="#"
set the caption to be Learn more

We are done, we need to load this layout, lets save it as "introtext" and then back to our code, we need to load it.

So the final code so long is supposed to be

B4X:
Sub Init
    'initialize the app
    MJMLApp.Initialize
    'load the main layout
    BANano.LoadLayout("#template", "myemail")
    'load the ch to
    companyheader.Element.LoadLayout("ch")
    '
    'load the image header
    imageheader.Element.LoadLayout("ih")
    '
    'load the intro text
    introductiontext.Element.LoadLayout("introtext")
   
    'save the email
    MJMLApp.Save
End Sub
So far so good, lets create the rest of the items...

introtextad.png
 

Mashiane

Expert
Licensed User
Creating the 2 Columns Section

Version 0.5 BETA on the 1st post


The 2 columns section basically has 2 columns, 1 shows the image and on the right some text. When complete, this email should now display like this.

2columns.png


So again, we fire the abstract designer, create our layout for this section and then load the layout inside the section.

We will call this layout, section1 and then load it with

B4X:
'load two columns
    twocolumnsection.Element.LoadLayout("section1")
Our final code now looks like this..

B4X:
Sub Init
    'initialize the app
    MJMLApp.Initialize
    'load the main layout
    BANano.LoadLayout("#template", "myemail")
    'load the ch to
    companyheader.Element.LoadLayout("ch")
    '
    'load the image header
    imageheader.Element.LoadLayout("ih")
    '
    'load the intro text
    introductiontext.Element.LoadLayout("introtext")
    '
    'load two columns
    twocolumnsection.Element.LoadLayout("section1")
   
    'save the email
    MJMLApp.Save
End Sub
As you have noticed, we have not written much code here as we are doing everything via the abstract designer.

This is a list of our layouts so far..

1598297346904.png


The section1 layout is designed like this..

1598297385786.png


1. Drag and Drop a MJColumn to the layout, inside that column, drag and drop a MJImage.

Set the src of the image to https://designspell.files.wordpress.com/2012/01/sciolino-paris-bw.jpg and the width to 200px.

2. Drag and drop another MJColumn to the layout to be side by side to the other. Add 2 MJTexts inside it. One will be a heading and another lorem ipsum. Remember how we did the lorem ipsum before, this also applies here.

The first MJText should have these attributes...

font-style="italic"
font-size="20px"
font-family="Helvetica Neue"
color="#626262" and the caption should be Find amazing places

The second MJText should have these attributes, LoremIpsum should be checked and the color should be #525252.

Save the layout and then load it to see your updates.

This is going very well!!!
 
Last edited:

Mashiane

Expert
Licensed User
Creating Icons

For the icons sections we just create some images inside columns. This now appears like...

1598298619696.png


So for each image here, we add a MJColumn and MJImage. Each image is set with a width of 100Px and then its URL on src.

These are the image links, "http://191n.mj.am/img/191n/3s/x0l.png", "http://191n.mj.am/img/191n/3s/x01.png" and "http://191n.mj.am/img/191n/3s/x0s.png"

1598298867008.png


We now load this layout to the master myemail layout. Our code now should be:

B4X:
Sub Init
    'initialize the app
    MJMLApp.Initialize
    'load the main layout
    BANano.LoadLayout("#template", "myemail")
    'load the ch to 
    companyheader.Element.LoadLayout("ch")
    '
    'load the image header
    imageheader.Element.LoadLayout("ih")
    '
    'load the intro text
    introductiontext.Element.LoadLayout("introtext")
    '
    'load two columns
    twocolumnsection.Element.LoadLayout("section1")
    '
    'load icons
    icons.Element.LoadLayout("iconsx")
    
    'save the email
    MJMLApp.Save
End Sub
As it is we have concluded our planned design by just using the Abstract Designer and then creating a beautiful email file. We need to actually send this email to someone, we will look in terms of how we do that.

#watch this space!
 

Mashiane

Expert
Licensed User
Creating Social Sharing Buttons - the Facebook Button

In this last part of the 1st project, we add some social sharing buttons, we will add facebook. For this I have used the b4x facebook page URL.

The email now should look like this.

1598304773384.png


For this create a layout, save it with a name of "social"

1598304847583.png


1. Drag and drop a MJColumn to the new layout.
2. Drag and drop a MJSocial component inside the MJColumn. Set the attributes for the MJSocial to be

font-size="15px"
icon-size="30px"
mode="horizontal"

3. Drag and drop a MJSocialElement inside the MJSocial element and update its properties to be

name="facebook" i.e the one inside the Custom Properties
href="https://www.facebook.com/b4xdev/" . You can use your own URL
Caption = Facebook

We then load this layout inside the myemail master layout. This makes out final code to be..

B4X:
Sub Init
    'initialize the app
    MJMLApp.Initialize("myemail")
    'load the main layout
    BANano.LoadLayout("#template", "myemail")
    'load the ch to 
    companyheader.Element.LoadLayout("ch")
    '
    'load the image header
    imageheader.Element.LoadLayout("ih")
    '
    'load the intro text
    introductiontext.Element.LoadLayout("introtext")
    '
    'load two columns
    twocolumnsection.Element.LoadLayout("section1")
    '
    'load icons
    icons.Element.LoadLayout("iconsx")
    '
    'load social
    socialicons.Element.LoadLayout("social")
    
    'save the email
    MJMLApp.Save
End Sub
As soon as you click the facebook button, this activates the sharing for facebook. In my case, it has loaded this page..

1598305261088.png


With all that we close our first project and launch the library for production.

Enjoy

PS: We will be playing more with this emailing thing. If you have any questions, please prefix them with [BANAnoMJML] and also try to include your example project if you are stuck and need help.

Take care and stay blessed!

TheMash
 

Mashiane

Expert
Licensed User
We have added some options to the library. As the HTML will be sent for email purposes, we by default just minify a few things.

Whilst public, these options can be set to true/ false

B4X:
minifyCSS = True
    removeEmptyAttributes = True
    collapseWhitespace = True
    Minify = True
    Beautify = False
For more details, see the MJML documentation.

PS: Viewing the generated file produces this.. (sample extract)

1598312005298.png
 

Mashiane

Expert
Licensed User
Version 1.2 now available.

We have added a .Preview method. This ensures that once generated, the email is shown in the index.html page.
The additional html file is no longer shown.

Download now from github

The final code now to run an email is:

B4X:
Sub Init
    'initialize the app
    MJMLApp.Initialize("myemail")
    MJMLApp.Minify = True
    'MJMLApp.Beautify = True
    'load the main layout
    BANano.LoadLayout("#template", "myemail")
    'load the ch to 
    companyheader.Element.LoadLayout("ch")
    '
    'load the image header
    imageheader.Element.LoadLayout("ih")
    '
    'load the intro text
    introductiontext.Element.LoadLayout("introtext")
    '
    'load two columns
    twocolumnsection.Element.LoadLayout("section1")
    '
    'load icons
    icons.Element.LoadLayout("iconsx")
    '
    'load social
    socialicons.Element.LoadLayout("social")
    
    MJMLApp.Preview
End Sub
Ta!
 

Mashiane

Expert
Licensed User
Yippie!!! Version 1.4. Available, we can now send emails via PHP. How?

EmailSent.jpg


So one can create their emails via the library and also send them.

B4X:
'send the email, build the map to pass to inline PHP
    Dim es As Map = MJMLApp.BuildEmail("mbanga.anele@gmail.com", "mbanga.anele@gmail.com", "BANanoMJML Email", MJMLApp.html)
    Dim email As String = BANano.CallInlinePHPWait("SendMJMLEmail", es)
    Dim response As String = MJMLApp.GetEmailResponse(email)
    Select Case response
    Case "success"
        BANano.Msgbox("Email sent successfully!")
    Case Else
        BANano.Msgbox("An error was experienced sending the email!")
    End Select
Ta!

PS: HelloMail example updated...
 

Mashiane

Expert
Licensed User
We are running tutorials here for different projects.


Enjoy!
 
Top