Sylwia Studzińska's blog

Magento dropdown attributes

Let's say you want to create a new attribute for a product, e.g. 'color'.
There should be a set of possible values for this attribute. So what you do is create
an attribute of 'Dropdown' type. You set all its properties, give it a title and create its options, e.g. 'black', 'white', 'red' and 'yellow'.
But there is still one surprise that you may have. When you try to obtain the color simply by:

$product->getColor()

all you get is a numeric value corresponding to an option value in the dropdown.
But you probably would like to get a color name.
Fortunately you don't need to construct database queries, as Magento already thought about it.
So to get the name of the color selected for a product you need to use a method:
$product->getAttributeText('color');

where 'color' is the text that you have set as attribute code. Remember that you cannot
change attribute code nor its type after you create it.

Magento Backoffice (Admin Panel) Options - [Part 3]

In the previous part (Magento Backoffice (Admin Panel) Options - [Part 2]) we created a module and added some code to manage the module from "Admin Panel". A new menu entry is now responsible for modifications of the module settings. But Magento allows us to use a different approach.

Every module can contain a configuration file named system.xml. In this file we can define tabs and sections which will be later placed in System->Configuration, we define their content also. Data entered in the sections is stored in core_config_data table. Handling the data between the sections and the database in done by Magento, so it's a quite handy solution if we just need to put the data inside the database.

First, we need to create system.xml in module etc directory. The file should contain following definitions: what will be the tab for our module management, what sections it will contain and what is the content of each section. Our file is quite simple. First, the tabs:

<tabs>
    <settime>
        <label>Set Time</label>
        <sort_order>100</sort_order>
    </settime>
</tabs>

Every tab has its name, label which will be displayed, and number corresponding to the order of all tabs collection. Next we define sections, which can be compared to submenus of the tab:

<sections>
    <setit>
    </setit>
</sections>

And then we put inside sections their content:

<class>separator-top</class>

Section label:

<label>Set It!</label>

Name of the tab containing the section:

<tab>settime</tab>

Data type:

<frontend_type>text</frontend_type>

Sort order - important if there is more than one section within a tab:

<sort_order>40</sort_order>

Should the section be visible when we define default configuration:

<show_in_default>1</show_in_default>

Should the section be visible when we define configuration for a website:

<show_in_website>1</show_in_website>

Should the section be visible when we define configuration for a store:

<show_in_store>1</show_in_store>

Time for section content. Groups are containers for similar data fields:

<groups>
    <settingtime>
        <label>Set Time</label>
        <frontend_type>text</frontend_type>
        <sort_order>100</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>1</show_in_store>
        <fields>
            <time_format>
                <label>Time Format</label>
                <comment>string according to PHP date() argument</comment>
                <frontend_type>text</frontend_type>
                <sort_order>1</sort_order>
                <show_in_default>1</show_in_default>
                <show_in_website>1</show_in_website>
                <show_in_store>1</show_in_store>
            </time_format>                        
        </fields>
    </settingtime>
</groups>

So now system.xml looks like that:

<config>
    <tabs>
        <settime>
            <label>Set Time</label>
            <sort_order>100</sort_order>
        </settime>
    </tabs>
    <sections>
        <setit>
            <class>separator-top</class>
            <label>Set It!</label>
            <tab>settime</tab>
            <frontend_type>text</frontend_type>
            <sort_order>40</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>0</show_in_store>
            <groups>
                <settingtime>
                    <label>Set Time</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>100</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>
                    <fields>
                        <time_format>
                            <label>Time Format</label>
                            <comment>string according to PHP date() argument</comment>
                            <frontend_type>text</frontend_type>
                            <sort_order>1</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </time_format>                        
                    </fields>
                </settingtime>
            </groups>
        </setit>
    </sections>
</config>

But we need something more to make it work - modification in config.xml. We need to add to it information about configuration resources that are related to our module.

<acl>
    <resources>
        <admin>
            <children>
                <system>
                    <children>
                        <config>
                            <children>
                                <setit>
                                    <title>Setit Section</title>
                                </setit>
                            </children>
                        </config>
                    </children>
                </system>
            </children>
        </admin>
    </resources>
</acl>

As you can see, we define path to our section. The path will be also relevant for saving or loading data from database, because it is used as an identifier. In our case data entered in field time_format wil have identifier setit/settingtime/time_format.

Magento will add the sections to permissions management in System->Permissions->Roles->Role Resources. Check this tab, our new sections should be listed there when you choose 'Custom'. If you see 'Access Denied' error when you click on 'Set It!' section, then go to System->Permissions->Roles, select Administrators and Role Resources. Change All to Custom, mark all checkboxes - be careful, because mistake in this step may cause inability to login to Admin Panel. Save, then go back and change Custom back to All and save again. Now you should have fully functional module management.

Here is a screenshot of final result in Magento back office:

Set it screenshot

Magento Backoffice (Admin Panel) Options - [Part 2]

Now, when you are a bit familiar with Magento "Admin Panel" options (see Magento Backoffice (Admin Panel) Options - [Part 1]), let's do something creative. You remember that the first part said that you can add your own menu entries? It's very useful if you want to control your module (of course the new menu entry doesn't have to manage a new module, it can be used to handle existing functionality as well). So - let's see how to do it.

First of all, you need to create a new module. Alternatively, you can download source code of a module which I created for the purpose of this article and to which I am going to refer. The module will display current time, and it's format will be set by you. The format should be a valid argument of PHP date() function.

Adding entry to menu takes place in config.xml file. What we need are the folowing lines:

<adminhtml>
    <menu>
        <example translate="title" module="adminhtml">
            <title>Set Time Format</title>
            <sort_order>60</sort_order>
            <children>
                <set_time>
                    <title>Set It!</title>
                    <action>example/index</action>
                </set_time>
            </children>
        </example>
    </menu>
</adminhtml>

This code will add entry labelled Set Time Format with subentry Set It! and it refers to module identified by example, controller index, action index. Basically, that's all that is necessary to put our new entry into the menu. Check the result in the backoffice - the new entry should appear between Catalog and Customers. If not - clear the cache.

The rest of the module are just files defining form used to enter time format and controller responsible for displaying the form or saving data. As you can see, I decided to store the data along with Magento config values. It was just a quick, dirty solution, to avoid creating more than what is essential in this short how-to.

You can also add your entry on System->Configuration page. It needs a bit diferent approach and this topic will be covered in the next part.

Magento Backoffice (Admin Panel) Options - [Part 1]

If you start your experience with Magento, you may be confused with all the options available in the backoffice (also called "Admin Panel"). What you get after a typical fresh install is: Dashboard, Sales, Catalog, Customers, Promotions, Newsletter, CMS, Reports, and System (if you do not see all these menu items, be sure that you are connected with administrator privileges). You can add more menu entries later, and we will talk about it in next parts. All of the entries, but Dashboard, contain their sub-menus. Now, let's have a closer look at some of them.

Dashboard is the admin home page. What you see there, is a summary for a selected shop - last orders from selected time range, amounts form selected time range, bestsellers, most viewed products, new customers... Basically this is what you would expect to get on your admin home page. Sales contains all management modules for orders, invoices, shipments and taxes. This is the place where you manage all the orders put by your customers. You can browse, cancel, hold or unhold, and print them. What is less intuitive, it also contains Terms and Conditions.

System entry contains some items worth to remember. Inside Tools you will find a possibility to create backup. Well, certainly a useful option. There is also Cache Management. And last, but not least - Configuration. Check Design tab. This is the place to set skin for your store, choose layout, and default theme.Magento will switch back to the default theme if the one you selected cannot be found. This is also the place to add the image that will be used as a watermark for the images in your store. And at the end - the setting used most often by me.

Check the Developer tab, still being under Configuration. Choose your store in the Current Configuration Scope field at the left. Debug section will then contain fields named 'Template Path Hints', and 'Add Block Names to Hints'. Uncheck 'Use website' and set both to Yes. Now go back to frontoffice and refresh page. Make sure you are on the same store that you selected in Configuration Scope in the admin panel. What you get are names of templates used to render displayed page, with corresponding blocks names. The dashed lines show templates borders. Trust me - this option is really worth remembering.

Translation in Magento

Translations between languages is quite simple in Magento. For an advanced developer, who has already worked with PHP frameworks, it is not a matter to discuss, but for a beginner it may need a few words of explanation. All texts on the page that should be translated, are stored in CSV files, in /app/locale/[language] directory. The [language] part of the path is build of language code, e. g. 'en_US'.

If you have a look at the files content, you will find that every file structure is the same, one line contains two texts: one in your default language, and one in the destination language. To use the files - also called dictionaries - they must be declared in module's config file (config.xml). You should put this code directly inside your frontend or admin node of the config file.

<translate>
        <modules>
                <companyname_modulename>
                        <files>
                        <default>CompanyName_ModuleName.csv</default>
                        </files>
                </companyname_modulename>
        </modules>
</translate>

That's all. Now, when you want to use a phrase that should be translated, use:

echo $this->__('text to translate');

Magento will look in you dictionary files for the phrase 'text to translate' and will return the corresponding text in the proper language.