I Loves Me Some Code

My little place to write whatever I want.

By

Custom email templates with CakePHP

I was working on a CakePHP app for an internal company service. We had a need to send emails that come from custom templates. Not just the usual email template files. This needed to allow customers to be able to upload or import HTML emails and the app would push them out.

We also wanted to give them the ability to insert custom data tags for things like names, etc. So, I decided I wanted to use Mustache templates to achieve this. It would be perfect because it will also allow them to create their own custom data fields, and then insert them straight into the email templates.

I added Mustahce as a vendor plugin by putting it into the main Vendor folder. Then you just need to pass it the HTML template code and an array of data variables.

App::import('Vendor', 'mustache/Engine');
$m = new Mustache_Engine;
$vars = array(
    'firstname' => 'John'
    'lastname' => 'Doe'
);
$html = $m->render($template, $vars);

This worked great, and fulfilled that need.

Then, thinking back to my experience in building tons and tons of HTML emails, I knew that some email clients, like Gmail, love to strip out any style tags. You need to put all of your styles inline with your tags in HTML emails. So, now I needed a way to pre process the template and place all the styles inline. Usually you just use a pre mailer service like MailChimp’s inlineCss api call, or Premailer to do this. However, I needed to do this on the fly before sending it out.

I could have just used MailChimp’s api service and called it a day, but I didn’t want to rely on a third party service which could add delays and possible future problems. So, I did some searching and found a nice little class called Emogrifier. This will let you pass in raw HTML with blocks of CSS in style tags, or a separate CSS file. It does a great job and integrates into Cake just as easily as Mustache.

App::import('Vendor', 'emogrifier/emogrifier');
$e = new Emogrifier($html, $css);
$inlined_html = $e->emogrify();

You pass the HTML into the constructor when instantiating a new instance of the Emogrifier class. The second parameter is optional and can be used to pass in additional CSS styles. Emogrifier will use this CSS, and then append any CSS inside the HTML and then inline it and return the result.

So, there you have it. Custom email templates built and processed on the fly. Send it out with your email service of choice.

By

Make fast mobile websites and PhoneGap apps you can

I was tasked with building a mobile website and mobile apps for a client to go along with their new website. So, the first thing I did was hit up Google and see what kind of frameworks were available. jQueryMobile 1.1 had just been released, there was jQTouch, Sencha Mobile, Chocolate Chip UI, and so on and so on. Lots of options to choose from, so I needed to decide where to start. I downloaded all of these and took a look at them. Tried out their demos on my phone, and they all shared the same traits. They were heavy, had slow response times, some didn’t support one feature or another and they were even slower when paired with PhoneGap. The app I was going to build had a pretty unique design and all of these were a hassle to skin and custom theme.

So like any diligent pragmatist, I kept looking. I found libraries like iScroll, HammerJS, iCanHazJS and Zepto. I decided that the large mobile frameworks weren’t for me. I needed something custom to keep my app snappy, responsive and fast loading. I came up with a solution using these libraries in their own ways to make my mobile website and PhoneGap app feel just as fast as a native app.

I built the entire thing as a single page, and everything is loaded into memory during startup. Let’s go over each component.

ZeptoJs

This is a small dom manipulation library that has a jQuery compatible syntax in a much smaller size. It is made almost specifically for mobile webkit, so it was a perfect fit. You can go either way with this one. Some people would prefer VanillaJS, but in this app I decided to go with Zepto for it’s ease of use and I happen to love me some jQuery. I may dive into a VanillaJS implementation at some other time, but I will save that for another post.

iScroll 4 (lite)

iScroll is a very nice library for building touch enabled scrollable areas. It uses CSS 3D transforms to take advantage of mobile browsers hardware acceleration. It saves battery life and the CPU by not using Javascript animations. It is a standalone plugin, so it doesn’t need jQuery or Zepto to run. Using it is pretty simple too:

HTML:

<div id="scroller_wrap">
  <div class="scroller">

  </div>
</div>

Javascript:

iScroller = new iScroll('scroller_wrap', {
    vScroll: true,
    vScrollbar: true,
    hScroll: false,
    hScrollbar: false
});
iScroller.destroy();

You instantiate a new iScroll object on the parent container of the element you want to scroll. Save that into a variable for later use. I only used horizontal scroll-able areas, but there are a lot of options available. When you are done with it make sure to destroy it for later use and to free up that memory. Note: I used the lite version of iScroll. This is an alternate download and is a stripped down version with just the basic scrolling functionality and no extra bells and whistles. It’s up to you to decide if that is all you need, or if you want the extra features the full version offers.

HammerJS

This is a cool library I found that will take care of handling touch events and has several gestures built in. It was really easy to use and worked great. It even has a nice jQuery mini plugin you can use it with. I made a quick modification to this to use Zepto by just replacing the jQuery references with a $. Then you bind an event callback to your elements.

$(element).hammer({ prevent_default: true }).bind('tap', callback);

I set the ‘prevent_default’ to true so the browser won’t run it’s normal built-in event handlers and conflict with what I want to do. I use this library to handle all touch events. And, the good thing is this library is stand alone, so yet again it does not need jQuery or Zepto to work.

ICanHazJS

This is a really nice lightweight Mustache template engine for Javascript, and another stand-alone library that does not require jQuery or Zepto. It works off of script blocks embedded inside your HTML and spits out raw HTML or a Zepto object that you can do whatever you want with.

HTML:

<script id="hello" type="text/html">
    <p>Hello, {{name}}!</p>
</script>

Javascript:

var details = {
name: 'World'
};
var html = ich.hello(details);

As you can see, the script block is of type "text/html". This prevents the browser from trying to run it as javascript. You just give it an id tag, then you can call ich and pass it the values for it to inject into the html block. The html variable is now a Zepto object you can add anywhere you want on the page. You can also pass a second parameter of true and it will return raw html instead.

TouchMySlider

This is a little Zepto plugin I built for my app, but I am throwing it on GitHub for others to get some use out of. This basically lets you create touch slide-able panels not unlike the iPhone and Android home screens. It is dependent on Zepto, HammerJS, and iScroll if you decide to use that extra feature of it. It also has the option to make your slide-able panels contain pages of vertically scrolling content. This comes in handy when you want to page through some screens of long articles. Just not too many panels or too long of content because it will start to slow down. Maybe in a future version I can make it load panels on the fly.

Get more info at the TouchMySlider GitHub Repo.

Tying it together

Hopefully you can start to see how these components could be used together. There are a lot of tips and tricks that you may not give a second thought too on the desktop, but when it comes to mobile, every byte of ram and second of battery life is precious. We need to approach things from a different direction to make sure we take care of the user and protect their mobile experience. Now that you have the tools, here are some tips to get you going.

Animations

Todays mobile apps and PhoneGap HTML5 apps have the advantage of more modern browsers that support a lot of CSS3′s benefits. You want to use CSS transitions and transforms for everything. Mobile browsers are built to use GPU hardware acceleration for CSS animations instead of the CPU for javascript animations.

Markup

In a mobile browser, small lightweight markup can go a long way. Anytime a page is manipulated in anyway, the browser must redraw the screen. Sometimes many times a second. If your DOM tree is nested several layers deep all over the place, you can see how this could become a problem. Make sure to focus your markup to the minimal amount necessary.

Another reason to use CSS transforms is for this exact reason. When you manipulate the position of a DOM element via javascript for animations, the screen needs to redraw itself. Even if the element is absolutely positioned, it needs to ensure nothing else is affected and it forces a redraw. By using 3D transforms such as transform: translate3d(0px, 0px, 0px,) you can bypass this. 3D transforms don’t actually move the element. It moves the content around the screen, but as far as the DOM is concerned it is still in the same place. You can also see how this can really speed things up?

Document Scrolling

One problem I kept coming up against was my Document kept wanting to scroll around. I had a fixed sized app, but the browser kept trying to scroll horizontally. I found that I needed to capture all of the touchmove events on the document and static elements to stop this. If this happens to you, here is an easy fix. If this is not happening to you, even better.

document.addEventListener('touchmove', function(e) {
    e.preventDefault();
    return false;
}, false);

You can also apply this to your static elements like fixed headers and footers.

Retina and other Hi-Res displays

I hate the term ‘Retina’, but I use it here so people will know what I am talking about. There is no retina display, it’s just a high resolution screen for crying out loud.

Nevertheless, we need to take these high pixel density screens into account, because they are popping up more and more. Luckily, we live in the land of the modern mobile browser, so it’s nothing a CSS media query can’t handle. What I did was have a second copy of all of my image assets in a second high-res specific folder. Then I can change the image url in a media query.

@media only screen and (-webkit-min-device-pixel-ratio: 2) {

}

You want to use CSS for all of your image assets as much as possible. This makes it easy to switch them out for high-res screens in one media query. If you do happen to have a need to load in images via your javascript while your users move around your app. I came up with an easy fix that worked out pretty well.

var imgFolder = 'mobile';
if (window.devicePixelRatio >= 2) imgFolder = 'mobile_2x';

So, imgFolder is a global variable that contains the folder name of the images I need to use. Then on page load, if the devicePixelRatio is 2 or greater, just set the variable to your high-res assets. Use this variable throughout to generate your image urls.

High-res images need to be twice the size of your normal images. You then set the size of the images to render at the normal size. So, your double sized images will be shrunk in half, but the screen will take full use of all the extra pixels in the image. In CSS it looks like this.

#header h1 {
    background: url(../img/mobile_2x/logo.png) no-repeat center center;
    background-size: 50px 50px;
}

My media query is pulling in my double size logo image. But it’s also setting the background size to the normal size. This will force the image to render as a 50px square image even though it’s actually 100px in size.

Link tap highlighting

You may have noticed that when you tap on links in a mobile browser, they get surrounded by a hightlight. This is normally fine, but we don’t want this on our app because it will quickly break the illusion of a native app. Use this CSS for your links to stop that from happening:

-webkit-tap-highlight-color: rgba(0,0,0,0);
tap-highlight-color: rgba(0,0,0,0);

Text selection

Sometimes, users may have their finger sitting on the screen over some text. Normally this would let them highlight the text to do a copy-paste. We don’t want this for the same reason as above. Use this CSS on your body tag to prevent this, or on any other elements it’s happening on.

-webkit-user-select: none;
user-select: none;

Wrapup

That should just about do it. Hopefully with this information in hand, you too can get out from under those heavy mobile UI frameworks and keep your sites lightweight and snappy.

Let me know what you think in the comments!

By

Welcome to my blog thingy.

Welcome to my new blog! I have been wanting to start blogging for some time, and I finally just jumped into it. I am pretty sure no one is ever going to read this. Who reads welcome blog posts?

I plan to post as much as can. I am pretty busy, but I want to find time to share my thoughts and findings with the web. I was gonna say world, but that sounds pretty cheesy. I guess web does too.

My passion is programming, technology, technology that lets me program more, and reading about technology and programming. Sometimes I do other things. I am on a never ending quest to learn as much as possible, and I really do find it extremely fun in doing so. I also read regular books and watch movies and do other regular people things, but always seem to have my projects in the back of my mind or a cool idea for a blog post that I never write.

I work full-time as a web developer, and I do freelance work and personal projects in my spare time. I have been immersed in the .Net stack for quite a long time, but recently have been trying to move towards Linux and Mono in my effort to completely open source my life.

Well, I will stop for now. I want to start posting some of my own work soon that I have not had the chance to open source yet.