Friday, April 29, 2016

Using Ghost Columns to Fix 3 Coulmn Problems in Outlook

Outlook is a notorious problem-child for email developers. One of the most commonly seen problems is that Outlook just can't handle exact widths very well. Responsive templates that are designed with two or three side-by-side columns (which stack on mobile devices) often end up stacking on Outlook as well. But with no responsive behavior, the columns don't become full width or stack directly on top of each other. Instead, they still align left and right, as they are coded to.

This problem affects Outlook 2007, Outlook 2010, Outlook 2013 and Outlook 2016 for Windows. Fortunately, there is an easy way to solve this.
We can use the "hybrid" part of fluid hybrid design to constrain these columns so they appear as intended. Hybrid tables are also sometimes called ghost tables, because they are invisible to clients other than Outlook for desktop. By creating a ghost table with two or three columns, or TDs, we can force Outlook to display the columns side-by-side no matter what. Because other clients can't "see" this code, it won't interfere with responsive behavior.

Coding ghost columns for Outlook
I have added some classes and conditional code to these elements so that you can see the main container, as well as the left and right column tables.
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Ghost Column Example</title>
  <style>

 @media only screen and (max-width: 479px) {
   .right_column, .left_column {
    width:100% !important;
    text-align: center;
    margin:0 auto !important;
   }
   .deviceWidth {
    width:300px !important;
    padding:0;
   }
  }
  </style>
  
</head>

<body>
  <table width="600" border="0" cellpadding="0" cellspacing="0" align="center" style="margin:0 auto;" class="deviceWidth">
    <tr>
      <td class="main_container">
        <!--[if (gte mso 9)|(IE)]>
           <table width="600" align="center">
            <tr>
             <td width="250">
             <![endif]-->
        <table border="0" cellpadding="0" cellspacing="0" width="250" align="left" class="left_column">
          <tr>
            <td style="padding:0px;border: 1px solid black;">
              Left Column Content
            </td>
          </tr>
        </table>
        <!--[if (gte mso 9)|(IE)]>
             </td>
             <td width="160">
             <![endif]-->
        <table border="0" cellpadding="0" cellspacing="0" width="160" align="left" class="left_column">
          <tr>
            <td style="padding:0px;border: 1px solid black;">
              Middle left Column Content
            </td>
          </tr>
        </table>
       <!--[if (gte mso 9)|(IE)]>
             </td>
             <td width="190">
             <![endif]-->
        <table border="0" cellpadding="0" cellspacing="0" width="190" align="right" class="right_column">
          <tr>
            <td style="padding:0px;border: 1px solid black;">
              Right Column Content
            </td>
          </tr>
        </table>
        <!--[if (gte mso 9)|(IE)]>
             </td>
            </tr>
           </table>
           <![endif]-->
      </td>
    </tr>
  </table>
</body>

</html>
That's it! You should now have three tables that line up perfectly in Outlook.
Source : https://www.emailonacid.com/blog/article/email-development/using-ghost-columns-to-fix-alignment-problems-in-outlook

Tuesday, April 5, 2016

Custom Alice Fixture Processor Using Symfony

Fixtures, those nice little bits of data that you can put into your database so that when you’re developing locally you actually have something to look at: like products or users or whatever else you want to play with.
I am using https://github.com/hautelook/AliceBundle, a Symfony bundle to manage fixtures with Alice and Faker.
I’ll create the DataFixtures/ORM directory inside UserBundle. And I’ll create a file called UserFixtures. Copy the contents in there and don’t forget to update your namespace and rename the class:
<?php

// src/UserBundle/DataFixtures/ORM/UserFixtures.php
namespace UserBundle\DataFixtures\ORM;

use Hautelook\AliceBundle\Doctrine\DataFixtures\AbstractLoader;
use Nelmio\Alice\Fixtures;

class UserFixtures extends AbstractLoader
{
    /**
    * {@inheritDoc}
    */
    public function getFixtures()
    {
        return  array(
                __DIR__ . '/users.yml',
        );
    }
}
The fixtures class is special because it’s already wired up to load yml files. Let’s call ours users.yml and then go ahead and create that file:

# src/UserBundle/DataFixtures/ORM/users.yml
UserBundle\Entity\user:
    user_1:
        name: Anup Shakya
        email_address: anup.shakya@example.com
        password: testing
 
Loading your Fixtures
This is a wrapper around the Doctrine fixtures library so we use the same doctrine command php app/console hautelook_alice:doctrine:fixtures:load to load fixtures.

Creating the Processor
Whenever you need to do something other than just setting simple data, you'll use a Processor, which is like a hook that's called before and after each object is saved. For example, We need to encode the password using Symfony security password encoder. This is where Processors come in.

Step 1. Create a new class. It doesn't matter where it goes, so put it inside ORM/Processor/ and call it UserProcessor. The only rule of a processor is that it needs to implement ProcessorInterface. And that means we have to have two methods: postProcess() and preProcess().

Each is passed whatever object is being saved right now, so let's just dump the class of the object:
<?php
// src/UserBundle/DataFixtures/ORM/Processor/UserProcessor.php
namespace UserBundle\DataFixtures\Processor;

use Nelmio\Alice\ProcessorInterface;
use UserBundle\Entity\User;

class UserProcessor implements ProcessorInterface
{
    protected $encoder;

    public function __construct($encoder)
    {
        $this->encoder = $encoder;
    }

    public function preProcess($object)
    {
        if (!$object instanceof User) {
            return;
        }

        $password = $this->encoder->encodePassword($object, $object->getPassword());
        $object->setPassword($password);
    }

    public function postProcess($object)
    {

    }
}
Given you declared a processor UserBundle\DataFixtures\Processor\UserProcessor, you have to declare it as a service with the tag hautelook_alice.alice.processor to register it:
# app/config/services.yml
services:
    alice.processor.user:
        class: UserBundle\DataFixtures\Processor\UserProcessor
        arguments: ["@security.password_encoder"]
        tags: [ { name: hautelook_alice.alice.processor } ]
Let's reload the fixtures to see what happens!
php app/console hautelook_alice:doctrine:fixtures:load
Cool! It calls preProcessor for every object. And password is encoded.

I just wanted to share this, even if some already knows about alice processors. Ref: https://knpuniversity.com/screencast/alice-fixtures