What kinds of mods are there?
At present there are two kinds of mods: built-in and local. Local mods are, as the name implies, specific to a given installation. Most folks creating / using Wagn mods will be working with local ones.
There are two built-in mods:
- core defines model methods and events (and a good bit more). Without "core" Wagn won't correctly store content, track references, handle formatting, or really do much of use. This functionality is implemented as a mod to be consistent in our API usage and to support low-level tinkering for the wonderfully foolhardy.
- standard too comes shipped with every Wagn, but its components could more easily be removed / substituted. The standard mod defines, among other things, all the built-in views.
Where do mods go?
Core and standard mods are found in the pack (soon to be renamed to mod) subdirectory of Wagn's root directory. (For brevity, this doc will assume that you are already in Wagn's root directory and begin all file paths with a ".". In those terms, core and standard mods are in ./pack)
By default, local mods are kept in ./local/packs. However you can configure Wagn to use different or additional directories in your ./config/wagn.yml file using the pack_dirs directive.
Each subdirectory of the packs directory is the name of a different mod. For example, if I were to create a mod for podcasting and called it "mypodcast", then I would start by adding a ./local/packs/mypodcast directory.
How are mods organized?
A mod can contain any of the following subdirectories: sets, formats, files, lib, set_patterns, and chunks.
- sets: sets are the centerpiece of the mods API. Almost all mods will contain a sets directory, in which you can define model methods, views, and events: the three components of the MoVE architecture.
- formats: these directories define format classes (eg HTML, RSS, JSON, text, etc), which are organized in a tradition ruby class hierarchy. Most local mods will not need this directory unless they are introducing a new format or very deeply altering a format's core behavior. Formats can be modified within sets, and in most cases this is the more appropriate mechanism
- files: simple static files that are loaded explicitly by custom code, typically in the sets directory. In most cases this is better achieved by putting the file content into a card's content, but this directory can be used for hard-coding where necessary.
- lib: custom ruby classes / modules, usually for use by sets.
- set_patterns: set patterns define what kinds of sets are possible. For example, the "type" set pattern makes it possible to define sets based on a card's type. These are seldom used in local mods but have in the past been used, for example, to create a "type plus type" set pattern
- chunks: are for defining content chunk patterns that are recognized by Wagn's content processor (eg, inclusions, links, uris, etc). To date no local mods have used this directory, and it should be considered an untested component of the mods API.
How are set modules organized?
As mentioned above, set modules are the heart of mods. They are located in ./[pack dir]/[modname]/sets. In the podcast example, the directory would be ./local/packs/mypodcast/sets.
To understand the directory structure for sets, you'll need to understand a bit about how sets work. Sets are explained in more detail on the set card, but in short they're groups of cards to which rules may be attached. From a Wagneer's perspective, rules involve "settings" (like *create, *structure, *table of contents, etc.) Set modules are used to create different kinds of rules, namely model methods, views, and events.
A set can be as broad as "all cards" and as narrow as a single one. Every set is represented by a card. For example, the set of all cards is represented by "*all", and the set of the card "Menu" is represented by "Menu+*self". The naming pattern is:
[ anchor + ] set pattern
*all and *self are set patterns. Menu is an anchor. Every set has a pattern, but not every set has an anchor.
To create a local mod for a given set, you need to use the following directory structure:
./[mods dir]/[mod name]/sets/[set pattern]/[anchor or module name].rb
To see this in action, let's look into the sets directory for the built-in "standard" mod. Here are all the modules for sets with the set pattern "self":
$ ls pack/standard/sets/self account_links.rb recent.rb alerts.rb search.rb foot.rb style_functional.rb head.rb style_jquery_ui_smoothness.rb navbox.rb style_standard.rb now.rb version.rb
There you see all the set modules for "singleton sets" (sets that have just one member) that have a module attached to them. So, for example, in navbox.rb there is code related to the *navbox+*self set.
A few important observations:
- most set modules have no explicit references that identify the set within the module; the set can be identified entirely by the directory structure.
- the names used for both set patterns and anchors are "codenames" – special names stored in the cards table that do not get changed even if the card's name is changed. This means that you can't break the sets just by renaming the card.
- sets that do not have anchors (like *all and *star) follow a very similar pattern, but the names of the modules themselves are not used in identifying the sets
- you can reopen the same sets in different mods. in this case the load order becomes significant, as the later-loaded mods override the early ones.