How the multi configuration system works and discussion about improving it.
needs update for 1.5/1.6.
See also MoinMoinTodo/Release 1.3/PluggableConfig.
Contents
Multi configuration in moin 1.3
As of patch-86, it works like this:
request -> import moin_wikis -> import config file [-> import farmconfig if used]
moin_wikis file
contains wikis, a mapping of regular expression to wiki config file. multiconfig uses this mapping to match the URL of the request to one config file. You can define different config file for different hosts.
Example:
If the URL match r'^redwiki.wikicolors.org/.*$', multiconfig will import redwiki_config
Wiki config file
This is a replacement for the old moin_config.py module. There is one difference though: you define the config in a class named Config, and not by adding names to the module itself. Important: if you misspell the class name, your class will be ignored and you will get the default configuration.
Example:
By importing a default config, you can define only stuff you want to change from the default.
The default install comes with a moin_config module, and if you do not change moin_wikis module, the system fallback to use moin_config. It works just like the old version if you have just one wiki.
Farm config file
If you want to serve more than one wiki, you don't want to duplicate config files. You want to define things OnceAndOnlyOnce. So you can create your Config class based on FarmConfig class, which define the common values to all the wikis in your farm.
Example:
Then you define two wikis - both based on FarmConfig:
Problems
- We load 2-3 tiny modules for every request just for the config
- Must edit 4 different tiny files to configure a farm
- Easy to make a typo, like mispell a config file name
If the system fails to find your config - you don't get an error. In case of a standard install, your get default config, and you just wonder why the wiki works but your settings are ignored. If you have a special install, like url_prefix != '/wiki', you get the not very helpful backtrace: "No such file '/wiki/data/text'
- Look more complicated than it really is, because of multiple files
One config file proposal
In the common case of one or few wikis per server, all managed by one person, it can make sense to have one config file. This file can have:
FarmConfig class, with all options we have today in moin_config, execpt sitename
WikiConfig class, based on FarmConfig, cotaining only few options
This default config will work as is "out of the box" for the common case of one wiki per server.
Example moin_config
1 # moin config using one file
2
3 from multiconfig import DefaultConfig
4
5 class FarmConfig(DefaultConfig):
6 acl_enabled = 1
7 acl_rights_before = 'FarmHead:read,write,revert,delete,admin'
8 # Many more options here...
9
10
11 class RedWiki(FarmConfig):
12 url_regex = '^red.wikicolors.org/.*$'
13 sitename = 'Red Wiki'
14
15
16 class BlueWiki(FarmConfig):
17 url_regex = '^blue.wikicolors.org/.*$'
18 sitename = 'Blue Wiki'
Matching url to wiki class
Note that I don't have a mapping between urls and wiki config classes. Mappings are error prone, the code should do it for us. In multiconfig, we can collect the config class names and url regex, then match the url to the correct wiki config class (I already implemented similar thing in my fix branch):
1 # In multiconfig: Match url to wiki class
2
3 # Create a url_re from all config classes
4 # Do this only once in a long running process, e.g twisted
5 _url_re = ["(?P<%s>%s)" % (name, obj.url_regex)
6 for name, obj in moin_config.__dict__.items()
7 if hasattr(obj, 'url_regex') and isinstance(obj, DefaltConfig)]
8 _url_re = re.compile(r'|'.join(url_re))
9
10 def getConfig(url):
11 """ Return a config instance for url """
12 match = url_re.match(url)
13 if match and match.groups():
14 for name, value in match.groupdict().items():
15 if value: break
16 ConfigClass = getattr(moin_config, name)
17
18 # Now create an instance, just as we do today...
Benefits
- Simpler to config, everything in one file, you get the whole picture
- Less fragile, Config class name does not matter, can't make bad mapping when there is no mapping
- One module to load for each request per CGI
- Maybe its more clear that each wiki serve one url_re when the variable is near the wiki sitename
Problems
- More complicated for the common case of one wiki per server, because in that case one can ignore both moin_wikis and farmconfig.
Maybe we can have a simpler default config - without FarmConfig. It will just have a WikiConfig class with a url_re = r'.' option. In this case, We can ship default simple moin_config, and a farm_config_example.
- If one have many wikis, and each have very different configuration, then the one module might be too big to load per each CGI request, and separate wiki config files might be better.
- If every wiki is managed by different person, like a commercial wiki farm, in which you rent wiki space, each should have its own config file.
- For this situation (If there is a market for this) we can extend the system with one config file per farm, which contain a mapping between url and wiki directory, and a wiki config file in each directory - like .htaccess in Apache.
Discussion
There are two problems with both solutions:
- Not all admins know Python, and editing simple text files might be better for them
If we want to have OnTheFlyConfig, then using modules is not the way to go, because of reload issues.
-- NirSoffer 2004-08-21 00:41:26