Re-using Handles in Magento Layout XML

Magento layout xml files can be really confusing. Here is a post to make them even more confusing, but really useful.
I won’t cover how to create a layout xml file here, I’ll cover that in a different post. I’m going to show you how to re-use the handles in your module.
Let’s say your module has the following layout xml. It’s just a one page module so it is simple:

<?xml version="1.0"?>
<layout version="1.0.0">
    <mymodule_default>
        <reference name="head">
            <action method="addItem">
                <type>skin_css</type>
                <name>css/mymodule.css</name>
            </action>
            <action method="addItem">
                <type>skin_js</type>
                <name>src/js/mymodule.js</name>
            </action>
        </reference>
    </mymodule_default>
    <mymodule_index_index>
        <update handle="mymodule_default" />
        <reference name="content">
            <block type="core/template" name="mymodule.main" template="mymodule/index.phtml">
                <block type="core/template" name="mymodule.child1" template="mymodule/index/childblock1.phtml"/>
                <block type="core/template" name="mymodule.child2" template="mymodule/index/childblock2.phtml"/>
            </block>
        </reference>
    </q_index_index>
</layout>

Take a look at the <update handle="mymodule_default" /> line in the <mymodule_index_index> section.What that is doing is copying everything in the <mymodule_default> section into that section.
This is really useful. You can use this same method to copy basically any block into another block.
For example, lets say you want to create a new section that includes the same templates that are in your <mymodule_index_index> section. You would add this to your xml:

<mymodule_newblock_index>
    <update handle="mymodule_index_index" />
</mymodule_newblock_index>

That section would include everything that is in the <mymodule_index_index> section.
Have fun re-using handles!

Caching Magento Blocks

class My_Custom_Block extends Mage_Catalog_Block_Product_View_Abstract {

    protected function _construct()
    {
        // the $groupId make it so each customer group will be cached separately
        $groupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
        $this->addData(array(
            'cache_lifetime' => 5600,
            'cache_tags' => array(Mage_Core_Model_Store::CACHE_TAG, Mage_Cms_Model_Block::CACHE_TAG),
            // you can add anything to the cache_key to make it cache separate versions for different customers and stores
            'cache_key' => "custom_unique_name_{$groupId}"
        ));
    }
}

Creating and Customizing Google Sitemaps with Magento

You can create an XML sitemap for you Magento store by logging into your administration panel and going to Catalog > Google Sitemap.

This interface is pretty straightforward, just be aware that each store must have its own sitemap. Also note that the the Path must be writable by the file system.

When you click “Save & Generate” a new xml sitemap will be generated. The frequency and priority are set using default settings but can be changed in System > Configuration > Catalog: Google Sitemap. This is also where you will set up your sitemaps to be automatically generated by the Magento cron job.

The Magento sitemap only includes catalog categories, products, and CMS pages by default. Lets discuss how to customize what is included in the sitemaps.

Customizing Magento’s XML Sitemap

The generateXml() function in the Mage_Sitemap_Model_Sitemap class is where all of the magic happens. We are going to overwrite this function. I’m not going to get into extending and overwriting Magento core here, if you need to learn about it you can read my post about it.

The generateXml() function has a lot going on, so to make it easier I just copy the entire function into my new class and never refer to the original function.

I recommend putting your custom code near the end of the function just after the last unset($collection); in the “Generate cms pages sitemap” section. I also recommend copying the same structure that the other sections use.

Here is what my custom code looks like with comments:

/**
 * Generate customurls sitemap
 */
// reuse same settings as the cms page section, you can create custom ones if you know how
$changefreq = (string)Mage::getStoreConfig('sitemap/page/changefreq', $storeId);
$priority   = (string)Mage::getStoreConfig('sitemap/page/priority', $storeId);

// you can do a lot of things to get these urls, this is a simplified example
$collection = array(
    'module1/page1',
    'module1/page2',
    'module2/page1'
);

// this is the most important part, it writes the data to the xml file
foreach ($collection as $item) {
    $xml = sprintf(
        '%s%s%s%.1f',
        // the core function concatenates $baseUrl with the url,
        // you can also use ->getUrl() or some other method to get the url
        htmlspecialchars($baseUrl . $item),
        $date,
        $changefreq,
        $priority
    );
    $io->streamWrite($xml);
}
unset($collection);

This is a very basic example. There are many ways to customize this, but this will get you started.

Go back to Catalog > Google Sitemap and click “Save & Generate” and then go to your sitemap url to see if the new urls are there.

Vim as My IDE Update 1

A few months ago I posted about usingĀ Vim as my primary IDE. Since then I’ve fallen in love with Vim and have made a few more changes to my .vimrc file. Here is my current .vimrc:

" ------------------
"       Plugins
" ------------------
call plug#begin('~/.vim/plugged')

Plug 'altercation/vim-colors-solarized'
Plug 'bronson/vim-trailing-whitespace'
Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
Plug 'Xuyuanp/nerdtree-git-plugin'
Plug 'jistr/vim-nerdtree-tabs'
Plug 'ap/vim-buftabline'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'taglist.vim'
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'
Plug 'joonty/vdebug'
Plug 'airblade/vim-gitgutter'
Plug 'tpope/vim-fugitive'
Plug 'ervandew/supertab'
Plug 'vim-scripts/SearchComplete'
Plug 'scrooloose/nerdcommenter'
Plug 'tobyS/pdv'
Plug 'StanAngeloff/php.vim'
Plug 'scrooloose/syntastic'
Plug 'joonty/vim-taggatron'
Plug 'groenewege/vim-less'

call plug#end()

" -- ctrl-p plugin conf
"set runtimepath^=~/.vim/bundle/ctrlp.vim

" -- solarized personal conf
set background=dark
try
 colorscheme luna
catch
endtry

" -- airline plugin conf
set laststatus=2
"let g:airline_powerline_fonts = 1
"if !exists('g:airline_symbols')
" let g:airline_symbols = {}
"endif
"let g:airline_symbols.space = "\ua0"

" -- vdebug plugin conf
if exists('g:vdebug_options["break_on_open"]')
 let g:vdebug_options["break_on_open"] = 0
endif

" -------------------------------
" Basic Configurations
" -------------------------------

" -- tabwidth set to 4
set tabstop=8 softtabstop=0 expandtab shiftwidth=4 smarttab

" -- show 80th and 120th column
let &colorcolumn="80,".join(range(120,999),",")
highlight ColorColumn ctermbg=0

" -- highlight search matches
set hlsearch

" -- numbered lines
set number

" -- enable mouse support
"set mouse=a

" -- set buffers to hidden
set hidden

" -- path to php.tags
set tags=/var/www/mage19/php.tags

" ---------------------
" Key Mapping
" ---------------------

" -- NERDTree
map <C-n> :NERDTreeToggle<CR>

" -- fuzzy finder
map <C-p> :FZF<CR>

" -- taglist
map <C-t> :TlistToggle<CR>

" -- highlight search matches
"map <C-f> :set hlsearch!<CR>

" -- copy file name
nmap ,cs :let @"+=expand("%")<CR>

" -- copy full file path
nmap ,cl :let @"+=expand("%:p")<CR>

Magento Redirect in Controller with Parameters

Magento controllers come built in with a _redirect() function that gives you the option to add parameters. This includes GET parameters and Magento’s path parameters.

This is the basic syntax:

$this->_redirect($url,$paramsArray);

The $url parameter is the magento url where you would like to redirect to. The $paramsArray is an array that contains the parameters you want in the URL.

Here’s an example:

$this->_redirect('module/controller/action', array('param1'=>'1','param2'=>'2'));

This would redirect to http://mysite.com/module/controller/action/param1/1/param2/2/ with param1 and param2 being Magento’s path parameters.

To change the parameters to be GET parameters, you would put the $paramsArray inside another array with '_query' being it’s key.

It would look like this:

$this->_redirect('module/controller/action', array('_query'=>array('param1'=>'1','param2'=>'2')));

This code would redirect to http://mysite.com/module/controller/action?param1=1&param2=2.

Magento reads these different types of parameters the same way so functionally it makes no difference which one you use. However, you want to only use Magento’s when the parameter is a unique ID that will be used to create a unique page for that ID only. Every other situation should use GET parameters.

Have fun playing with Magento redirects!

JavaScript Event for Input Change

If anyone had ever tried using the “change” event on a text input they know that the event doesn’t fire until the user leaves the input. This can get really frustrating when you want to fire some JavaScript while the user is entering data into the input.

But there is an answer to this dismal situation! That answer would be “input propertychange”. Using this combination of events will allow you to run your code as soon as the user changes whatever is in the text input without having to wait for them to leave the input.

Here is an example using jQuery that toggles an element based on some criteria that will run any time the user changes the input:

$('.text-input').on('input propertychange', function () {
    if (someCondition) {
        $('.element').toggle();
    }
});

I’ve already used this several times and I love it. Enjoy!

Using Vim as my primary IDE

I recently decided to make the switch to VIM as my primary IDE. Any serious developer that uses Linux as their primary OS should be using VIM to edit their code, right? I mean, why not?

The IDE you use is really just a matter of preference. If you want to try out VIM as your IDE then maybe this post will help you, I’ll try to keep it short.

VIM Plugin Management

You will want to find VIM plugins that make developing on VIM easier. But first you need to decide what plugin manager you want to use for VIM. I decided to use vim-plug by junegunn because it was the most highly recomended. There are many other options so do your own research before you decide.

Vim-plug is easy to use, once you have it installed you just need to these two lines in your ~/.vimrc file:

call plug#begin('~/vim/plugged') " -- this is the location where vim-plug should be installed

call plug#end()

Installing plugins with vim-plug is straightforward. You just need to put the github URL of the plugin in between the two lines above prepended by Plug. It would look like this:

call plug#begin('~/vim/plugged') " -- this is the location where vim-plug should be installed

Plug 'scrooloose/nerdtree'       " -- I will explain these plugins in a minute
Plug 'vim-airline/vim-airline'      

call plug#end()

Once you have the lines added then you need to open a new instance of VIM and run :PlugInstall. That will check if there are new plugins in the ~/.vimrc file and install them.

Which Plugins to Use

This is 100% a matter of preference. If you want to go as barebones as possible then you technically don’t need any plugins. I prefer my IDE to have certain functionality such as buffer tabs and xdebug support.

Here are the plugins I am currently using:

More VIM Configurations

There is a multitude of ways to customize VIM to function any way you want. Instead of going into all of the details, I’ll just show you all of the customizations I use.

This is not by any means the best configuration and I will try to post updates as I make changes. Without further ado, here is my ~/.vimrc file:

" ------------------
"       Plugins
" ------------------
call plug#begin('~/.vim/plugged')

Plug 'altercation/vim-colors-solarized'
Plug 'bronson/vim-trailing-whitespace'
Plug 'scrooloose/nerdtree', { 'on':  'NERDTreeToggle' }
Plug 'Xuyuanp/nerdtree-git-plugin'
Plug 'ap/vim-buftabline'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'taglist.vim'
Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
Plug 'junegunn/fzf.vim'
Plug 'joonty/vdebug'
Plug 'airblade/vim-gitgutter'

call plug#end()

" -- solarized personal conf
set background=dark
try
    colorscheme luna
catch
endtry

" -------------------------------
"       Basic Configurations
" -------------------------------

" -- tabwidth set to 4
set tabstop=8 softtabstop=0 expandtab shiftwidth=4 smarttab

" -- highlight 80th column
set colorcolumn=80
highlight ColorColumn ctermbg=0

" -- show line numbers
set number

" -- enable mouse support
set mouse=a

" -- set buffers to hidden for use with tabline
set hidden

" ---------------------
"      Key Mapping
" ---------------------

" -- NERDTree
map <C-n> :NERDTreeToggle<CR>

" -- fuzzy finder
map <C-p> :FZF<CR>

" -- taglist
map <C-t> :TlistToggle<CR>

" -- highlight search matches
map <C-f> :set hlsearch!<CR>

Using Magento config to run cron jobs

The days of using crontab to run cron jobs for your Magento installation are long over. Since Magento Community Edition 1.8 (Enterprise Edition 1.13) cron jobs can now be configured using the Magento configuration.

Initial Setup

Before you can schedule your cron jobs, you have to set up Magento’s cron.php or cron.sh using crontab. This will be the only time you will ever have to use crontab.
Using cron.php:

* * * * * /bin/php /var/www/magento/cron.php

Using cron.sh:

* * * * * /bin/sh /var/www/magento/cron.sh

These examples are setup to continuously check for scheduled cron jobs. You can change how often Magento checks for scheduled cron jobs, just make sure you know what you are doing first.

Scheduling a Cron Job

Now that the Magento cron job is setup, you can start scheduling custom cron jobs. You do this by adding a crontab block to the end of the config.xml file of your module:

<config>
...
...
    <crontab>
        <jobs>
            <my_cron_job>
                <schedule>
                    <cron_expr>0 1 * * *</cron_expr>
                </schedule>
                <run>
                    <model>mymodule/observer::myFunctionName</model>
                </run>
            </my_cron_job>
        </jobs>
    </crontab>
<config>

This particular example will run the myFunctionName() function in the observer.php of the “mymodule” module every morning at 1:00am.

That’s it!

New Bootstrap WordPress Theme for TheSamAllen.com

Why the change?

It has been a while since I updated the look of this site so I decided to give it a face lift. And let’s face it, the old theme was really bad.

The New Theme: _tk by themekraft

From my experience with WordPress themes and general Web Development I knew I wanted to go simple. However, I didn’t want to go too simple because I like having the ability to customize my themes should I feel the urge.

I have plenty of experience using Bootstrap and love the simple but attractive designs so I decided to try and find a theme that came with the most recent Bootstrap libraries included.

With these goals in mind I went searching and came across several different options. But the one I liked the most was a simple starter theme by themekraft called _tk.

I was turned on by _tk because it is a very basic theme that does a very good job of integrating Bootstrap into Automattic’s underscores theme without any extra fluff. Since it uses Bootstrap then that means that it is also very responsive and therefore mobile friendly with no effort.

You can check out themekraft’s website and the github page for the _tk theme to learn more.

The New and Improved TheSamAllen.com!

With a new clean theme I am now free of the unnecessary noise that seem to be on too many of the themes that are available. I feel like this has made TheSamAllen.com much more appealing to myself and anyone who happens upon this humble blog.

Saving and displaying dates in Magento

There are a few things to be aware of when saving dates in Magento. Magento comes built in with a lot of tools that allow you to work with dates, learning to use these tools will help you improve the consistency and quality of your Magento code as well as increasing your Magento skills. In this post we will only focus on saving dates in the database and then displaying them in a template.

Saving datetime in database

We are going to assume that you already know how to create a new model and database table for the model. Core Magento is programmed to save all datetimes in the database in GMT time, so that is what we are going to do. Here is an easy way to do that correctly:

First, you need to make sure all of the dates are converted to Magento’s internal format as specified in

Varien_Date::DATETIME_INTERNAL_FORMAT

An easy way to do that is to use the

_filterDateTime()

function in the

Mage_Core_Controller_Varien_Action

class (the class should already be inherited by your controller so you can use “$this”). Here is an example using dates submitted by a form:

$params = $this->getRequest()->getParams();

$params = $this->_filterDateTime($params, array('date','date2','date3'));

Once you have formated the datetime, you will need to convert it to GMT like this:

$date = Mage::getModel('core/date')->gmtDate('Y-m-d H:i:s',$params['date'])

Now that it is properly converted to GMT you can save it in your model:

$model->setDate($date)->save()

Showing datetime in template

Here is how you would use Magento’s built in tools to display a datetime that is saved in GMT:

$this->formatDate($date, Mage_Core_Model_Locale::FORMAT_TYPE_SHORT, true)

The formatDate() function will automatically convert the datetime to whichever timezone the user is in. The code above will output the date followed by the time like this:

01/19/2016 10:42 am

If you don’t need to show the time, then just remove the “true” parameter from the formatDate() function.

There you go! Enjoy Magento’s datetime tools!