I've recently started using Magento for a client's webshop, and still need to get to grips with its systems.
The webshop should have several links to and also grab info from another domain, where the corporate website is located. I would prefer not to hardcode the domain name or URL but instead define it at some place and use that value in the phtml templates throughout the webshop. This makes it easy to adjust it when we move the site between dev, staging and production URL's.
Can anyone suggest the Magento way of doing this? Preferably we could add a field to the Store's Config GUI in the backend, similar to the way the {{base_url}} is set. Or maybe I'm thinking the wrong way?
Magento offers (relatively) easy support for custom configuration values. The best way I've found to accomplish this is to create a single magento module that holds all your custom configuration values.
Like anything Magento, there are a lot of steps, and any one being wrong could trip you (or me!) up.
Create an Empty Magento Module
First, you'll want to setup a magento module to hold all your custom configuration values. Creating a magento module involves
- Create a xml file in app/etc/modules
- Create a folder structure in app/code/local/Companyname
Companyname is a unique string that serves as a namespace, and most magento tutorials recommend you use your company name here. For the purposes of this tutorial, I'll use "Stackoverflow". Wherever you see the string Stackoverflow, replace it with your own unique string.
So, for step 1, create a file at app/etc/modules named "Stackoverflow_Customconfig.xml", and place the following inside
<?xml version="1.0"?>
<config>
<modules>
<Stackoverflow_Customconfig>
<active>true</active>
<codePool>local</codePool>
</Stackoverflow_Customconfig>
</modules>
</config>
Random Magento Tip: There are parts of the magento system that consider whitespace significant, so it's always best to include no whitespace with your attribute values (<active>true</active> vs. <active> true </active>
Next, create the following folder
mkdir app/code/local/Stackoverflow/Customconfig
mkdir app/code/local/Stackoverflow/Customconfig/etc
And create a file at
app/code/local/Stackoverflow/Customconfig/etc/config.xml
with the following contents
<?xml version="1.0"?>
<config>
<modules>
<Stackoverflow_Customconfig>
<version>0.1.0</version>
</Stackoverflow_Customconfig>
</modules>
</config>
Congratulations, you've just setup a new Magento Module. If you clear your magento cache and go to
System -> Configuration -> Advanced -> Disable Modules Output
you should see your module listed.
Add a System.xml file to your module
Next, we're going to add a system.xml file. This file is used to add a custom configuration value to magento, which you'll be able to grab anywhere you want during the magento request cycle. Add a file at
app/code/local/Stackoverflow/Customconfig/etc/system.xml
That contains the following
<config>
<sections>
<design>
<groups>
<my_or_their_group translate="label">
<label>A grouping of config values. Make your own, or us an existing group.</label>
<frontend_type>text</frontend_type>
<sort_order>50</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>0</show_in_website>
<show_in_store>0</show_in_store>
<fields>
<my_config translate="label">
<label>This will be my config's label</label>
<frontend_type>text</frontend_type>
<sort_order>50</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>0</show_in_website>
<show_in_store>0</show_in_store>
</my_config>
</fields>
</my_or_their_group>
</groups>
</design>
</sections>
</config>
<design> is the name of the section your config will be displayed in. "General, Web, Design, Currency Setup, etc." By and large, this will be a lower-case version of the title, i.e. "General" becomes "general", "Design" becomes "design". If you're not sure what this outer tag should be, search through the core magento modules. i.e., grepping for "Currency Setup" reveals a mention in
app/code/core/Mage/Directory/etc/system.xml
<currency translate="label" module="directory">
<label>Currency Setup</label>
So you'd use the tag <currency /<, and not the more intuitive <currency_setup />
<my_or_their_group translate="label"> is the name of the group your config variable will show up in. Groups are the Ajax drop downs that contain config fields. For example, the General section has a "Country options" group and a Local options" group. Again, check existing core modules if you're unsure how to place a value in an existing group.
You'll also notice a translate attribute here, along with a corresponding label tag. This allows you to use any string you want in the HTML interface as a group title, but internally keep the name a valid XML tag name. Our tag is named
<my_or_their_group />
but in the interface, the group will have the title
A grouping of config values. Make your own, or us an existing group.
Finally, <my_config translate="label"> is the name of yoru conifg value. Again, notice the translate attribute. The same rules as above apply.
The other xml structure is needed, and is (mostly) used to control what kind of HTML inputs will be used for your config. If you want a particular interface element, find an example in the core module and copy the XML structure.
This will allow you to set and lookup config values in the Magento GUI interface. You can retrieve your values using the static getStoreConfig method of the global Mage object and specifying the URI of your config value. The URI is created using the section/group/name of your config.
Mage::getStoreConfig('design/my_or_their_group/my_config');
Magento provides Custom Variables from version 1.4 onwards.
Login to Admin side, System -> Custom variables -> create a new custom variable with code "my_variable".
Enter the HTML content and Plain text for this variable
You can show the custom variable in CMS pages by putting this {{customVar code=my_variable}}
Or in .phtml
pages:
$variableHtml = Mage::getModel('core/variable')->loadByCode('my_variable')->getValue('html');
$variablePlain = Mage::getModel('core/variable')->loadByCode('my_variable')->getValue('plain');
The easiest way would be to add a node to magento's core config xml file. But that is not recommended as it will cause problems with upgrades. To set custom values wihtout editing the core .... check out this link
How to override config values
I'm too new to add a comment to Alan's answer, but here is some more information from Magento:
- XML for Admin Configurations -- "This document describes how to define fields for your module’s use in the Configuration section."
-Ed.
Alan, thanks for your answer! It was the key that unlocked the mystery for me. Even after I had been reading your excellent guide. Since I am doing my best not to mod core files, I have started making extensions for my e-commerce business. And I got one that I think is good enough to release to the people, but I wanted to be able to configure it in the admin so there was no need for editing files.
I started with your code above and saw that the "menu" added wasn't in "General", but in "General-General", or General-Web, General-Design, etc. I wanted my thing to show up in General, but I didn't want to do like everyone else and add a whole menu group for my extensions.
If the reader came here from Google just wanting to put my options somewhere easy in the Admin, then read on (and this is why I'm adding another answer). First: do what Alan says above. Get your menu to show up in General->General->Your Menu. Note: you will need to clear cache AND ALSO logout as some info is stored in the session.
In order to get your own menu to show up under "General", you have to do the same as if you're getting your own group, or even Tab at the top menu bar, you've got to give yourself ACL permission in config.xml
:
<!-- file: config.xml -->
<config>
<adminhtml>
<acl>
<resources>
<admin>
<children>
<system>
<children>
<config>
<children>
<ytf translate="title">
<title>Youtube Feed</title>
</ytf>
</children>
</config>
</children>
</system>
</children>
</admin>
</resources>
</acl>
</adminhtml>
</config>
Here's my system.xml
that corresponds to the configuration. Note that ytf
is the parent menu. I modeled this off of TniyBrick's "True Order Edit" module. Also a gotcha: ytf
and ytfeed
have subtle differences with their entries. The ytf
entry is what shows up when you go to Admin -> config and look on the left in the General group. ytfeed
is the "bar" that opens up on the center of the page when you click on "General->Youtube Feed"
<!-- file: system.xml -->
<config>
<sections>
<ytf translate="label" module="ytfeed">
<label>Youtube Feed</label>
<tab>general</tab>
<frontend_type>text</frontend_type>
<sort_order>700</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<groups>
<ytfeed translate="label" module="ytfeed">
<label>Youtube Feed</label>
<sort_order>50</sort_order>
<expanded>1</expanded>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
<fields>
<username translate="label">
<!-- Mage::getStoreConfig('ytf/ytfeed/username'); -->
<label>YouTube Username:</label>
<comment>(or YouTube channel name)</comment>
<frontend_type>text</frontend_type>
<sort_order>10</sort_order>
<show_in_default>1</show_in_default>
<show_in_website>1</show_in_website>
<show_in_store>1</show_in_store>
</username>
</fields>
</ytfeed>
</groups>
</ytf>
</sections>
</config>
Another link that helped me greatly:
http://www.scorgit.com/blog/custom-options-in-a-magento-back-end-dropdown-menu/
Update: I made an extension out of this answer.