Magento Expert Forum - Improve your Magento experience

Results 1 to 3 of 3

Source, frontend and backend models in Magento system settings

  1. #1
    Moderator speed2x's Avatar
    Join Date
    Mar 2013
    Location
    Hollywood, Florida, United States
    Posts
    91
    Thanks
    9
    Thanked 7 Times in 6 Posts

    Cool Source, frontend and backend models in Magento system settings

    Source Model – a model class that serves to get existing values (stored in the db or somewhere else) for further displaying inside the setting’s field.

    Frontend Model – as a rule, it’s a block’s class. Methods of this class return html of setting’s field. To be more specific, the block had to have method _getElementHtml() described inside the class which returns the raw html of setting’s field.

    Backend Model – a class which allows to operate with configuration data on the different stages (save, load). It contains three major methods respectively for each event: _afterLoad(), _beforeSave() and _afterSave().

    If you are interested in, you can always find the working examples of each of them in the Magento core itself. But firstly, let’s try to look on some custom examples of these models. The following part describes how to create a drop down menu with the custom values:

    Init setting’s field in your system.xml:


    HTML Code:
    <color>
        <label>Color</label>
        <frontend_type>select</frontend_type>
        <source_model>Atwix_Shoppingbar_Model_Adminhtml_System_Config_Source_Color</source_model>
        <sort_order>2</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>1</show_in_store>
    </color>

    Then, create the source model that was specified above:


    PHP Code:
    class Atwix_Shoppingbar_Model_Adminhtml_System_Config_Source_Color
    {
       public function 
    toOptionArray()
       {
           
    $themes = array(
               array(
    'value' => 'green''label' => 'Green'),
               array(
    'value' => 'blue''label' => 'Blue'),
               array(
    'value' => 'beige''label' => 'Beige'),
           );
     
           return 
    $themes;
       }


    As you can see, there’s only one method toOptionArray(). It returns an array with the items (value -> label) for the drop down menu. Nothing difficult is here
    Let’s look onto another example to find out how to use frontend and source models. The best point is to review editable items list setting since it has both. The setting described below operates with the text items. It allows to add/remove email addresses:


    HTML Code:
    <addresses>
        <label>Blocked Email Addresses</label>
        <frontend_model>atwix_emailblocker/adminhtml_addresses</frontend_model>
        <backend_model>adminhtml/system_config_backend_serialized</backend_model>
        <sort_order>2</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>0</show_in_website>
        <show_in_store>0</show_in_store>
        <can_be_empty>1</can_be_empty>
    </addresses>

    Frontend model is a block:


    PHP Code:
    class Atwix_Emailblocker_Block_Adminhtml_Addresses extends Mage_Adminhtml_Block_System_Config_Form_Field
    {
       protected 
    $_addRowButtonHtml = array();
       protected 
    $_removeRowButtonHtml = array();
     
       
    /**
        * Returns html part of the setting
        *
        * @param Varien_Data_Form_Element_Abstract $element
        * @return string
        */
       
    protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
       {
           
    $this->setElement($element);
     
           
    $html '<div id="emailblocker_addresses_template" style="display:none">';
           
    $html .= $this->_getRowTemplateHtml();
           
    $html .= '</div>';
     
           
    $html .= '<ul id="emailblocker_addresses_container">';
           if (
    $this->_getValue('addresses')) {
               foreach (
    $this->_getValue('addresses') as $i => $f) {
                   if (
    $i) {
                       
    $html .= $this->_getRowTemplateHtml($i);
                   }
               }
           }
           
    $html .= '</ul>';
           
    $html .= $this->_getAddRowButtonHtml('emailblocker_addresses_container',
               
    'emailblocker_addresses_template'$this->__('Add New Email'));
     
           return 
    $html;
       }
     
       
    /**
        * Retrieve html template for setting
        *
        * @param int $rowIndex
        * @return string
        */
       
    protected function _getRowTemplateHtml($rowIndex 0)
       {
           
    $html '<li>';
     
           
    $html .= '<div style="margin:5px 0 10px;">';
           
    $html .= '<input style="width:100px;" name="'
               
    $this->getElement()->getName() . '[addresses][]" value="'
               
    $this->_getValue('addresses/' $rowIndex) . '" ' $this->_getDisabled() . '/> ';
     
           
    $html .= $this->_getRemoveRowButtonHtml();
           
    $html .= '</div>';
           
    $html .= '</li>';
     
           return 
    $html;
       }
     
       protected function 
    _getDisabled()
       {
           return 
    $this->getElement()->getDisabled() ? ' disabled' '';
       }
     
       protected function 
    _getValue($key)
       {
           return 
    $this->getElement()->getData('value/' $key);
       }
     
       protected function 
    _getSelected($key$value)
       {
           return 
    $this->getElement()->getData('value/' $key) == $value 'selected="selected"' '';
       }
     
       protected function 
    _getAddRowButtonHtml($container$template$title='Add')
       {
           if (!isset(
    $this->_addRowButtonHtml[$container])) {
               
    $this->_addRowButtonHtml[$container] = $this->getLayout()->createBlock('adminhtml/widget_button')
                   ->
    setType('button')
                   ->
    setClass('add ' $this->_getDisabled())
                   ->
    setLabel($this->__($title))
                   ->
    setOnClick("Element.insert($('" $container "'), {bottom: $('" $template "').innerHTML})")
                   ->
    setDisabled($this->_getDisabled())
                   ->
    toHtml();
           }
           return 
    $this->_addRowButtonHtml[$container];
       }
     
       protected function 
    _getRemoveRowButtonHtml($selector 'li'$title 'Delete')
       {
           if (!
    $this->_removeRowButtonHtml) {
               
    $this->_removeRowButtonHtml $this->getLayout()->createBlock('adminhtml/widget_button')
                   ->
    setType('button')
                   ->
    setClass('delete v-middle ' $this->_getDisabled())
                   ->
    setLabel($this->__($title))
                   ->
    setOnClick("Element.remove($(this).up('" $selector "'))")
                   ->
    setDisabled($this->_getDisabled())
                   ->
    toHtml();
           }
           return 
    $this->_removeRowButtonHtml;
       }


    It’s pretty huge. We have described the full version to show what’s going on there. You can simple extend your block from Mage_GoogleCheckout_Block_Adminhtml_Shipping_Merch ant and override the necessary methods.
    Backend model, in this case, it’s a standard Magento model:


    PHP Code:
    class Mage_Adminhtml_Model_System_Config_Backend_Serialized extends Mage_Core_Model_Config_Data
    {
        protected function 
    _afterLoad()
        {
            if (!
    is_array($this->getValue())) {
                
    $value $this->getValue();
                
    $this->setValue(empty($value) ? false unserialize($value));
            }
        }
     
        protected function 
    _beforeSave()
        {
            if (
    is_array($this->getValue())) {
                
    $this->setValue(serialize($this->getValue()));
            }
        }



    As you can see, it simply unserializes/serializes field’s values before load/save respectively. That’s all. You are always able to improvise with the models described below to get the best result. If you want non-trivial form element – use your own fronted model. To get available values for settings you should use the source model. And if you need to save/load data in your format or make some other actions on these events – feel free to use the backend model.
    Good luck and graceful solutions

    View more threads in the same category:


  2. #2
    Junior Member golddev's Avatar
    Join Date
    Mar 2013
    Posts
    45
    Thanks
    1
    Thanked 6 Times in 2 Posts

    Default

    Very useful source tips for me. Thanks

  3. #3
    Administrator david's Avatar
    Join Date
    Nov 2012
    Posts
    260
    Thanks
    23
    Thanked 40 Times in 33 Posts

    Default

    Nice to know. Thanks

Similar Threads

  1. Backend Tour Part 2 (Video)
    By ccvv in forum Webmaster & Administrator
    Replies: 4
    Last Post: 01-08-2013, 02:07 PM
  2. Magento Module Development - Part 3 - Models
    By rocker in forum Programming & Development
    Replies: 0
    Last Post: 22-04-2013, 08:37 AM
  3. Magento system settings overview
    By david in forum Programming & Development
    Replies: 0
    Last Post: 03-04-2013, 07:41 AM
  4. Magento system settings overview
    By david in forum Webmaster & Administrator
    Replies: 0
    Last Post: 03-04-2013, 07:41 AM
  5. Frontend Tour (Video)
    By ccvv in forum Webmaster & Administrator
    Replies: 0
    Last Post: 22-03-2013, 04:20 AM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •