Site Sections: Satchmo Main | Wiki | Demo Store |

Background

The Satchmo Configuration app is intended to make it easy and straightforward to add and use new settings for modules used by Satchmo. In the past, we did this by adding such items to the "local_settings.py" file. This is not a good way to add such items, since:

  • It requires everyone watch the "local_settings_customize.py" file manually merge in changes as developers add or change base settings in that file.
  • It gave no way to set defaults, or to manage
  • It made store owners dependent upon developers to modify many settings for their shop. Settings that rightfully should be updatable by the store admins.
  • It is ugly and confusing to have settings only used if you are using optional module "X".

For these reasons, if you can avoid it, do not add any settings to the local_settings.py file. Instead, use the configuration app. Also, do not put any settings managed by the configuration system into the shop context processor. It is automatically available from shop.options.GROUP.KEY.

Introducing the configuration app

The configuration app allows developers to register configuration settings, and then to use the configuration settings anywhere they please in the modules. It is even safe to use the settings in models, views or urls, as long as you specify a default value for the setting.

Creating configuration settings is done by building configuration groups and "Values" and then registering them with the configuration manager.

Registered settings are then managed by admins at the site settings management page, located at SHOP_URL/settings/

Definitions

  • Configuration Group: A section of settings. There is one default group. "SHOP"
  • Value: The base class for Configuration setting objects. A Value may or may not have a Setting
  • Setting: A user-specified setting for a Value.

Features

  • Flexible defaults. Specifying a default is optional, but if given then that value is used when no there is no Setting for the Value.Interestingly and importantly, if the user updates a Value to a Setting which equals the default value, then the Setting is deleted from the database. This is an intentional design decision, allowing for much easier updates/upgrades. Only settings different from the default are saved to the database.
  • Many configuration Value types. At the moment there are Values defined for Boolean, Decimal, Duration, Integer, Percent, PositiveInteger, String, MultipleString and Module.
  • Values may be hidden. If so, then they will not show up on the settings admin page.
  • Values may be given lists of choices, and if they are then they will show as select boxes in the admin page.
  • Values may have dependencies. If they do, then they will only show on the admin page if the dependency is met.
  • Safe for use in Views, Urls, or Models if a default is given. It will not explode during syncdb.

Example - Creating a new configuration setting

Say for example you are building a new app, "GoogleBase." By convention, you would add a new file, GoogleBase.config, and then "import config" in GoogleBase.models.

In GoogleBase.config, you might want a few settings. I'm making this up, so I'm not sure what that system might need, but lets say it needs login id, a key, and a switch to turn it on and off.

from satchmo.configuration import config_register, BooleanValue, StringValue, SHOP_GROUP, ConfigurationGroup
from django.utils.translation import ugettext_lazy as _

# Add an enable switch to the base Shop group.  We're assigning it
# to a variable so that we can use it as a "requires" dependency
# below
GOOGLEBASE_ANALYTICS = config_register(
    BooleanValue(SHOP_GROUP, 
        'GOOGLEBASE', 
        description= _("Enable GoogleBase"), 
        default=False))

# Set up a group to appear in the settings page when GoogleBase is enabled
GOOGLEBASE_GROUP = ConfigurationGroup('GOOGLEBASE', 'Google Settings')
        
# register a list of settings to show only if GOOGLEBASE_ANALYTICS is True
config_register([
    StringValue(GOOGLEBASE_GROUP, 
        'ID', 
        description= _("User ID"), 
        default = "",
        requires = GOOGLEBASE_ANALYTICS)),

    StringValue(GOOGLEBASE_GROUP, 
        'KEY', 
        description= _("Login Key"), 
        default = "",
        requires = GOOGLEBASE_ANALYTICS))
])

Then, to use it in a view, you would do like so:

from satchmo.configuration import config_value
[...]

def myview(request):
    [...]
    base_id = config_value('GOOGLEBASE','ID')
    base_key = config_value('GOOGLEBASE','KEY')

Since there is a hook to the configuration app in the config model, access to configuration variables in a template is dead easy:

Here is my login_key, which I probably shouldn't show you:  {{ shop.options.GOOGLEBASE.KEY }}

Learning More

Look at the config modules in the Satchmo codebase. The most complex one is in the Payment app, the easiest to understand would be Shipping or Newsletter.

External modules

In local_settings.py, I've made several new entries, named CUSTOM_XXX_MODULES. To have configuration options loaded for your module, even if there is no models.py file in it, just add to this list. Since configs can add options to previously registered Values, external modules can plug right into the system without any hacking.

My thought is that this is the way to easily handle adding client-specific new shipping modules, payment systems and the like.