Magento's Marketing Tools - Price Management

Why is Magento so great for e-commerce? Because it provides a lot of marketing tools, that make e-Commerce projects succesfull. Among them you can find promotions, newsletters, cross selling, tier prices, coupons, gift certificates, membership discounts, free shipping, etc.
If price management and promotions are important in your marketing strategy, here is a little guide what you are able to do with Magento on this field.

  • Product special price - Allows you to set special price for a product. New price will be valid between from and to dates.

Magento special prices in admin panel

Magento special price

  • Tier Prices enable you to set different prices per product depending on the amount bought by a customer.

Magento tier prices in admin panel

Tier prices

  • Catalog Promotional Pricing lets you set promotional price by percentage or fixed amount. You are able to specify complex conditions and restrict promotional prices to stores, categories or products. Very usefull tool. Rule below will aply to all blue products in category with ID 3.

Promotions

  • Coupons with ability to restrict to stores, customer groups, time period, products, and categories. Once the customer reaches the cart and gives proper coupon code discount is applied.

Others price marketing tools are available on Magento Connect...

Magento Dataflow - Default Adapters [Part 2]

"Magento DataFlow - Data Exchange Made Flexible" article introduced global concept of data exchange framework implemented in Magento. Today I would like to tell more about default adapters implemented in DataFlow module.

  1. Adapter definition

    Adapters are responsible for pluging into an external data resource and fetching requested data or saving given data into data resource. For this purpose all adapters implement interface Mage_Dataflow_Model_Convert_Adapter_Interface which contains two methods: load() and save(). Data exchange concept introduced in DataFlow module use adapters in 3 contexts:

    • to load data from resource - using load() method
    • to save data to resource - using save() method
    • to process one parsed row - when defined as adapter/method pair of variables of parser

    For first two contexts adapter's xml definition looks like that:

    <action type="dataflow/convert_adapter_io" method="load">
        ...
    </action>

    Action tag has two parameters: type and method. Type tells as which adapter class is to be used in this action. It is defined using its alias. Method tells us which method of this adapter class action should call. As mentioned before, by default there are two available methods: load and save. Children of action tag define variables which are parameters used when executing adapter's method. Variables are defined like in the example below:

    <action type="dataflow/convert_adapter_io" method="load">
        <var name="type">file</var>
        <var name="path">var/import</var>
        <var name="filename"><![CDATA[products.csv]]></var>
        <var name="format"><![CDATA[csv]]></var>
    </action>

  2. Magento DataFlow default adapters

    Magento DataFlow module contains few default adapter classes which you can find in app/code/core/Dataflow/Model/Convert/Adapter. Not all of them have yet implemented load() and save() methods.

    For common case of reading data from or saving data to local or remote file you will use dataflow/convert_adapter_io (Mage_Dataflow_Model_Convert_Adapter_Io).

    Following variables will allow you to define local/remote file as data source:

    • type - defines type of io source we want to process. Valid values: file, ftp
    • path - defines relative path to the file
    • filename - defines data source file's name
    • host - for ftp type it defines the ftp host
    • port - for ftp type it defines the ftp port; if not given, default value is 21
    • user - for ftp type it defines the ftp user, if not given default value is 'anonymous' and password then is 'anonymous@noserver.com'
    • password - for ftp type it defines the ftp user's password
    • timeout - for ftp type it defines connection timeout; default value is 90
    • file_mode - for ftp type it defines file mode; default value is FTP_BINARY
    • ssl - for ftp type if it is not empty, then ftp ssl connection is used
    • passive - for ftp type it defines connection mode; default value is false
  3. Customer and Product adapters

    For most commonly exchanged entities - customer and product - Magento provides default adapters: customer/convert_adapter_customer (Mage_Customer_Model_Convert_Adapter_Customer) and catalog/convert_adapter_product (Mage_Catalog_Model_Convert_Adapter_Product). Both inherit from Mage_Eav_Model_Convert_Adapter_Entity.

    To simply load all customers data for selected store you can use the following xml:

    <action type="customer/convert_adapter_customer" method="load">
        <var name="store">default</var>
    </action>

    Sometimes you may want to not load all customers in database. To help you with this there are following variables valid:

    • filter/firstname - to load only customers with firstname starting with value of this variable
    • filter/lastname - to load only customers with lastname starting with value of this variable
    • filter/email - to load only customers with email starting with value of this variable
    • filter/group - to load only customers from group with id equal to value of this variable
    • filter/adressType - to export only selected addressType; valid values are: both, default_billing, default_shipping
    • filter/telephone - to load only customers with telephone starting with value of this variable
    • filter/postcode - to load only customers with postcode starting with value of this variable
    • filter/country - to load only customers with country iso code equal to value of this variable
    • filter/region - to load only customers with region equal to value of this variable (for US just 2-letter state names)
    • filter/created_at/from - to load only customers created after a date defined as value of this variable
    • filter/created_at/to - to load only customers created before a date defined as value of this variable

    For example:

    <action type="customer/convert_adapter_customer" method="load">
        <var name="store"><![CDATA[0]]></var>
        <var name="filter/firstname"><![CDATA[a]]></var>
        <var name="filter/lastname"><![CDATA[a]]></var>
        <var name="filter/email"><![CDATA[a]]></var>
        <var name="filter/group"><![CDATA[1]]></var>
        <var name="filter/adressType"><![CDATA[default_billing]]></var>
        <var name="filter/telephone"><![CDATA[1]]></var>
        <var name="filter/postcode"><![CDATA[7]]></var>
        <var name="filter/country"><![CDATA[BS]]></var>
        <var name="filter/region"><![CDATA[WA]]></var>
        <var name="filter/created_at/from"><![CDATA[09/22/09]]></var>
        <var name="filter/created_at/to"><![CDATA[09/24/09]]></var>
    </action>

    Same way you can load and filter products loaded from database with following variables:

    • filter/name - to load only products with name starting with value of this variable
    • filter/sku - to load only products with sku starting with value of this variable
    • filter/type - to load only products with type defined as value of this variable; valid values are: simple, configurable, grouped, bundle, virtual, downloadable
    • filter/attribute_set - to load only products with attribute set id equal to value of this variable
    • filter/price/from - to load only products with price starting from value of this variable
    • filter/price/to - to load only products with price up to value of this variable
    • filter/qty/from - to load only products with quantity starting from value of this variable
    • filter/qty/to - to load only products with quantity up to value of this variable
    • filter/visibility - to load only products with visibility id equal to value of this variable
    • filter/status - to load only products with status id equal to value of this variable

    Example:

    <action type="catalog/convert_adapter_product" method="load">
        <var name="store"><![CDATA[0]]></var>
        <var name="filter/name"><![CDATA[a]]></var>
        <var name="filter/sku"><![CDATA[1]]></var>
        <var name="filter/type"><![CDATA[simple]]></var>
        <var name="filter/attribute_set"><![CDATA[29]]></var>
        <var name="filter/price/from"><![CDATA[1]]></var>
        <var name="filter/price/to"><![CDATA[2]]></var>
        <var name="filter/qty/from"><![CDATA[1]]></var>
        <var name="filter/qty/to"><![CDATA[2]]></var>
        <var name="filter/visibility"><![CDATA[2]]></var>
        <var name="filter/status"><![CDATA[1]]></var>
    </action>

Seems a little bit frightening if you see all those id values you have to provide for filters. Fortunatelly for these two entities - customers and products - there is wizard like profile generator that allows you to define filter with simple select boxes.

In next part I will describe use of parsers and adapters in context of parsers.

eZ Gento, an alternative CMS Module for Magento: Content translation [Part 2]

Content management as a tree structure in eZ-Gento is a big step forward, but it's just a small part of the new features made available.
One of the purposes of Magento store views is to allow you to define additional languages for your e-Store.
Indeed, Magento site can be visited by clients from other countries and we don't want to lose them. That's why, as you know, we can create additional store view and assign each of them to different language.
Magento allows you to duplicate CMS content pages or blocks in order to have one for each store view and therefore one for each language. Having many pages with the same ID can become confusing and hard to manage when you have many pages and/or many languages.

Now everything is easier with ezGento! eZ-Gento comes with automatic mapping between Magento store views and eZ Publish siteaccesses. It means, that when we access the "french" store view, a "french" eZ Publish siteaccess will be asked for content. So if requested page has french translation, it will be displayed.

Remember that there are two main ways of defining content translation in eZ Publish:

  • The first one is to add a translation to an exisiting page. This way one content tree has pages with two (or more) translations.
  • The second one is to define a separate content tree and have a different page structure in a new language. (This is useful when we don't want to limit or when we want to extend content comparing to the initial language.)

Of course it is possible to mix both methods and add only a few additional pages in new language, or just not to translate some of them.

What about friendly URLs? eZ Publish comes with powerful URL management. Different language has its content with proper URL. By default it's created from the page title, but it's also possible to define additional fields just for URL.

For more multilingual features please refer to eZ Publish documentation page.

All that is possible in eZ Publish is now available in Magento thanks to eZ-Gento!

See eZ Gento, an alternative CMS Module for Magento [Part 1] for more informations on eZ Gento.

eZ Gento

Prototype and jQuery in Magento

As we know, the Prototype JavaScript framework is included in standard magento installation. Together with script.aculo.us it is a powerful tool for programming client-side actions and effects. It also provides Ajax framework which makes any ajax requests easier then ever before. A lot of magento templates deploy Prototype functionality, e.g. to show/hide elements depending on user's choice or to display error messages with a nice 'fade' effect.

But Prototype is not the only JavaScript library to offer such an useful set of functions. One of other most popular libraries is jQuery – very lightweight (19KB minified and compressed version), simple to use and, to tell the truth, my favourite one. Created in 2006, now it has a large community and hudge set of plugins.

However, is it generally a good idea to use both libraries in one site magento? In my opinion: no, it isn't. At least in most cases. Why? There are a few main reasons:

  • They provide similar functionality so what you achieved by one of them, you can achieve by the other
  • More libraries included mean more data to download by a web browser and slower loading of page
  • They use some common structures, which may lead to conflicts

In some cases, though, you may be forced to include jQuery in your magento shop. For example, you need to use an additional JavaScript library which is created as a jQuery plugin. So how can you force Prototype and jQuery to work together without conflicts?

At first you have to download the recent jquery version (the current release is v.1.3.2) and put it in /js/jquery folder. Then you have to include it in all magento pages – the most logical way is to put the following piece of code in <block type="page/html_head"> section of /app/design/frontend/.../.../layout/page.xml:

<action method="addJs"><script>jquery/jquery-1.3.2.min.js</script></action>

Now you have to avoid conflicts with Prototype framework – they both use $ notation (in jQuery it is a shortcut for jQuery and in Prototype it is an alias for getElementById function). Fortunately, there is a mechanism in jQuery to override the $ function: jQuery.noConflict(). You can put such a construction at the end of your jquery-1.3.2.min.js file:

var $j = jQuery.noConflict();

and from now you have to use $j instead of $ function (or, if you want, you can still use jQuery). So be careful to change all instances of $ in your jquery plugins (but there are many plugins which have jQuery.noConflict() already implemented).

And it would be all, if there wasn't one web browser which still would have problems with coexisting Prototype and jQuery. And, surprisingly, it is not Internet Explorer ;) It is Firefox 2. It throws errors and refuses to execute the JavaScript. Of course currently there are newer versions of Firefox and the problem doesn't exist there, but there is still a little percent of net surfers who use Firefox 2 and they want to spend money in your shop, too;)

Fortunately there is an easy way to solve this problem. You have to include jQuery file before including Prototype. So you have to do the following in page.xml:

<action method="addJs"><script>jquery/jquery-1.3.2.min.js</script></action>
<action method="addJs"><script>prototype/prototype.js</script></action>

And now you can forget about the conflicts and enjoy those two magnificent libraries working together.

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.

Developing module for Magento Tutorial - Where to Begin [Part 1]

Have you ever tried to read the complete list of features Magento comes with? Gosh, it's huge. And it's even more impressive when you look at Magento Connect and all the extensions available there. However, if you are reading this blog entry you are probably looking for something which is not available yet. Or maybe you are a developer who just loves to play with the code. Either way, for serious business reasons or just because of your hack-ish nature, developing a Magento module is fun.

Let's create something really really simple. The module. You might wonder what that nifty module will be doing. Well in this fist part it will does nothing but being declared in Magento!

Where to begin?

Take a loot at the directories structure of your Magento installation. In app > code > local, create a directory, which will be a kind of container for your modules, in Magento it's usually called code pool. If you wonder how to name it, I can say that company name you're working for is probably a good one. It is in my case ;)

So let's create it

$ cd app/code/local/
$ mkdir Baobaz

Then, in this container we should create the module. For the purpose of this blog let's call it "Reader" (in next few parts the reason of using this name should clarify, if not... well.. it's still sounds good ;) )

$ cd Baobaz
$ mkdir Reader

So far, so good. The next step is a little bit more complex, but still simple. Let's change current directory...

$ cd ../../../etc/modules/

Hm... where are we?

$ pwd /Your/favorite/place/for/web/projects/magento/app/etc/modules/

Now, you must tell Magento about the module. To do this you must create an xml file. Take your favorite editor and create a file called Baobaz_Reader.xml (as you probably guessed the name consists of <container_name>_<module_name>.xml

$ vi Baobaz_Reader.xml

Now put this into your file

<?xml version="1.0"?>
<config>
    <modules>
        <Baobaz_Reader>
            <active>true</active>
            <codePool>local</codePool>
        </Baobaz_Reader>
    </modules>
</config>

Save file. And.... Voilà! That's one small step for a man, one giant leap for man...gento. :-)

To be sure that Magento knows about our new module let's login to admin panel. Navigate to System > Configuration, choose Advanced, from Advances section (yes, it's on the left).

You should see Baobaz_Reader at the top (or somewhere there) of the "Disable modules output" list.

OK, OK, OK... I admit that our nifty module makes nothing so far but be patience, in a few next parts we will add some more useful features.

To be continued...

e-Shop must-haves – Magento has them all!

There are not many things so convenient like shopping in the net. All you have to do is get a coffee in your hand, go through products in the store, pay and just wait for a delivery :-). No long hours walking in the stores, no heavy lifting, no queues at all ;-).

But haven't you ever thought that there is something wrong with the online shop you visited? For sure you did... Can't find your product? Too small images? Having to log in to see everything?

Not every online store thinks about customers convenience.

But Magento does it for sure:

  • Problem #1. Can not find product you need?

    Thousands of products in the category? No problem. With layered navigation in Magento you can filter category products how you want to. Still can't find it? :-) You have a search engine there!

  • Problem #2 .Too small images?

    You want to buy jewellery or clothes, but images in the store are small and poor quality?  In that case you can never be sure what you exactly buy. With Magento you get the full size product image Zoom. You can check every detail of your product .

  • Problem #3. Do you really have to log in?!?

    When you have chosen your products and want to place order, you are forced to register in the store. Account is a good thing when you make orders frequently. But for some people this is irritating. With Magento, customers can place orders as guests without forcing them to create accounts. Nice, isn't it?

  • Any other problem you encountered with online stores?

    Try Magento, you might be surprised how easily it solves it!

Understanding Magento Default Templates

Magento template system allows you to easily create custom html/css code according to design requirements. However, in some cases it would be a good idea to use some of the default magento templates. It may save some time spent on integrating new html structure with magento functionality.

For example, let's take a look at this location in standard magento structure: app\design\frontend\default\default\template\page. Here we have templates describing a basic structure of a page: 1column.phtml, 2colums-left.phtml, 2colums-right.phtml or 3colums.phtml. They all contain the same structure of the page (let's focus on the inside of 'body' section):

<div class="wrapper">

<!-- start header -->
        <div class="header">
            ...
        </div>
<!-- end header -->

<!-- start middle -->
        <div class="middle-container">
            ...
        </div>
<!-- end middle -->

<!-- start footer -->
        <div class="footer-container">
                <div class="footer">
                    ...
                </div>
        </div>
<!-- end footer -->

</div>

They differ only in part inside <div class=”middle-container”>, where a html code for specified layout is defined. As you can see, they present the most common way of building the pages – header, middle part, footer. So in most cases you can use those templates without any change in html and create only your own skin css, which will adapt the look of your page to your needs.

Of course, the more detailed a template is, the less chance that it can be used without change, but you can still start working on a default magento template and just modify the parts you need.

eZ Gento, an alternative CMS Module for Magento [Part 1]

Magento is a great software platform for web shops. It gives huge possibilities of products management, sales, promos, etc. Although some of customers demand also more advanced CMS feature. Plain pages structure is enough for sites with a few pages (like homepage, credits, legal mentions). But this might no be sufficient if you want to add more than 50 pages in different languages.
Of course it would be possible to develop additional modules, functions and blocks that will allow to group pages and store in tree structure, but that would be a very expensive part of the developement.
Therefore Baobaz has created a connection between Magento and eZ Publish Enterprise CMS. This solution allows to display eZ Publish pages directly in Magento front end

What is eZ Publish?
eZ Publish has many common points with Magento.

  • Like Magento is one of the best (if not the best) open source e-Commerce solution, eZ Publish is one of the best open source Enterprise CMS.
  • Like Magento, it is a great AMP platform for new extensions development.
  • Like Magento, it has a great community of contributors.
  • Like Magento, it has a lot of references
  • Like Magento with Varien, it was developed by eZ Systems, a strong for-profit company.
  • ...checkout http://ez.no/ for more details !

What we gain with eZ Publish?
A lot:

  • Content tree structure
  • Multilingual pages
  • Content versioning
  • Approval workflow
  • Multimedia direct insert
  • and much more...

Imagine that you can browse tree of content located next to products catalog, pages are in different languages depending on selected store view. It's also possible to define many little trees and put them in different product categories and don't have to take care about proper links placed in many templates. Everything is generated automatically each time new page has been published or exiting modified.

All above was possible thanks to merged Magento and eZ Publish called eZ-Gento. Both installations are placed side by side and contain little extensions responsible for direct communication. Each time user access any content page, Magento module passes part of url to eZ Publish and retrieves generated html content. Such html can be displayed directly on homepage, subpage or as a cms block next to product or as a product description.

So, first step done. If you want to read something more about eZ-Gento possibilities, stay tuned!

Magento DataFlow - Data Exchange Made Flexible [Part 1]

One of major features of e-commerce websites is the possibility to share data with offline sale management systems. Magento made data exchange flexible and quite easy with DataFlow module.

Magento DataFlow is a data exchange framework that use four types of components: adapter, parser, maper and validator. At current state of developement validators are not implemented, but are reserved for future use.

Dataflow of data exchange process is defined as XML structure and called profile. Magento provides simple wizard-like tool for generation of some basic import/export profiles operating on products or customers entities. Advanced profiles manager is also provided for advanced users able to create XML defining profile without wizard tool and with need to use more custom dataflow operations related also to other entities.

Adapters are responsible for pluging into an external data resource and fetching requested and filtered data. It can be used for example to get data from: local or remote file, web services, database and more.

For example to load data from csv file you can put in XML profile the following code:

<action type="dataflow/convert_adapter_io" method="load">
    <var name="type">file</var>
    <var name="path">var/import</var>
    <var name="filename"><![CDATA[products.csv]]></var>
    <var name="format"><![CDATA[csv]]></var>
</action>

To load data from remote FTP server you can use same adapter, but with these parameters:

<action type="dataflow/convert_adapter_io" method="load">
    <var name="type">ftp</var>
    <var name="host"><![CDATA[ftp.server.com]]></var>
    <var name="passive">true</var>
    <var name="user"><![CDATA[user]]></var>
    <var name="password"><![CDATA[password]]></var>
    <var name="path">var/import</var>
    <var name="filename"><![CDATA[products.csv]]></var>
    <var name="format"><![CDATA[csv]]></var>
</action>

Parsers are responsible for transforming one data format to another. It can be used for example to convert CSV file content to two-dimmensional array, or opposite.

To parse CSV file content into database product entities you can use this code in your profile:

<action type="dataflow/convert_parser_csv" method="parse">
    <var name="delimiter"><![CDATA[,]]></var>
    <var name="enclose"><![CDATA["]]></var>
    <var name="fieldnames">true</var>
    <var name="store"><![CDATA[0]]></var>
    <var name="number_of_records">1</var>
    <var name="decimal_separator"><![CDATA[.]]></var>
    <var name="adapter">catalog/convert_adapter_product</var>
    <var name="method">parse</var>
</action>

Adapter defined within parser variables as <var name="adapter"> and adapter's method <var name="method"> are responsible for parsing loaded data. In this particular case parser converts data from CSV file content to two-dimmensional array and calls the adapter's method "parse" to process it.

The simplest way of import customization is creating own adapter given as variable within parser definition. In most cases you will need to overwrite one of existing adapters and modify or write your own parsing method (in most cases it will be overwrited saveRow() method)

Mappers are responsible for altering data values from one to another. These are useful for maping one field to another.

In example below source's 'reference' column is mapped into 'sku' column and variable '_only_specified' is set to true, so imported/exported will be only listed columns:

<action type="dataflow/convert_mapper_column" method="map">
    <var name="map">
        <map name="sku"><![CDATA[reference]]></map>
        <map name="name"><![CDATA[name]]></map>
        <map name="price"><![CDATA[price]]></map>
        <map name="qty"><![CDATA[qty]]></map>
    </var>
    <var name="_only_specified">true</var>
</action>

This is just the tip of the iceberg of possibilities Magento DataFlow module offers. Come back later to read more.