Magento Development

Refs: Magento for Developers

modules

when you want to extend Magento, put your code at
app/code/local/Package/Modulename

and create an XML file at
app/etc/modules

theme basics

Magento Theme Development: An Introduction

translation

ref: Magento translation hierarchy

Translation packages are located at `app/locale/', such as:

app/locale/zh_CN

each module got its own translation file:

Mage_Adminhtml.csv
Mage_AdminNotification.csv
Mage_AmazonPayments.csv
...

these translations can be overriden with 'app/design/frontend///locale/zh_CN/translate.csv', such as use following line to replace the Your Language: translation in Mage_Page.csv

"Mage_Page::Your Language:","测试,你好,您的语言:"

pages and static blocks should be translated in 'CMS' section

quick code to get strings for translation:

grep -o "__('[^']*')" * | sed -r "s/__\('(.*)'\)/\"\1\",\"\"/"  | sort -u

cms and blocks

it's cumbersome to add translated cms and block through admin UI, we can add cms and block through SQL:

add a new store view

migrate an installation

command line tools

install a package

./mage install community Mage_Locale_zh_CN

Routing / Dispatching / URL

http://example.com/catalog/category/view/id/25

Model loading

Magento uses static factory methods to instantiate Models, Helpers and Blocks

Mage::getModel('catalog/product');
Mage::helper('catalog/product');

all model classes inherit from Varien_Object, use magic __call method to implement getters and setters

getter/setter example:

$model = Mage::getModel('catalog/product')->load(27);
$price = $model->getPrice();
$price += 5;
$model->setPrice($price)->setSku('SK83293432');
$model->save();

collection example:

$products_collection = Mage::getModel('catalog/product')
    ->getCollection()
    ->addAttributeToSelect('*')
    ->addFieldToFilter('price','5.00');

foreach($products_collection as $product)
{
    echo $product->getName();
}

Layout

typical controller code, load and render layout:

/**
 * View product gallery action
 */
public function galleryAction()
{
    if (!$this->_initProduct()) {
        if (isset($_GET['store']) && !$this->getResponse()->isRedirect()) {
            $this->_redirect('');
        } elseif (!$this->getResponse()->isRedirect()) {
            $this->_forward('noRoute');
        }
        return;
    }
    $this->loadLayout();
    $this->renderLayout();
}

Layout XML file example:

<catalog_category_default>
    <reference name="left">
        <block type="catalog/navigation" name="catalog.leftnav" after="currency" template="catalog/navigation/left.phtml">
            <block type="core/template" name="foobar" template="foo/baz/bar.phtml"/>
        </block>
    </reference>
</catalog_category_default>

this works on catalog Module, category Controller and the default Action, add a block into the left structure block

blocks can be nested

in parent block's template file, you can call $this->getChildHtml('foobar') to load the child block

Observer

settings in config.xml

<events>
    <customer_login>
        <observers>
            <unique_name>
                <type>singleton</type>
                <class>mymodule/observer</class>
                <method>iSpyWithMyLittleEye</method>
            </unique_name>
        </observers>
    </customer_login>
</events>

do somthing:

class Packagename_Mymodule_Model_Observer
{
    public function iSpyWithMyLittleEye($observer)
    {
        $data = $observer->getData();
        //code to check observer data for our user,
        //and take some action goes here
    }
}

class overrides

settings in config.xml:

<models>
    <!-- does the override for catalog/product-->
    <catalog>
        <rewrite>
            <product>Packagename_Modulename_Model_Foobazproduct</product>
        </rewrite>
    </catalog>
</models>