Difference between revisions of "Extension:ArticleProperties"

From Organic Design wiki
(update to current usage method)
m (Determining which class a page should instantiate as)
Line 52: Line 52:
 
The extension provides a hook called "ArticlePropertiesClassFromTitle" which allows its sub-classes to easily define rules by which they should become the class used for a MediaWiki page, for example a specified namespace could use a specific ''ArticleProperties'' sub-class instead of the standard Article. In this example, the ''LocationExample'' class defined above will be used if the article is in the ''NS_FOO'' namespace:
 
The extension provides a hook called "ArticlePropertiesClassFromTitle" which allows its sub-classes to easily define rules by which they should become the class used for a MediaWiki page, for example a specified namespace could use a specific ''ArticleProperties'' sub-class instead of the standard Article. In this example, the ''LocationExample'' class defined above will be used if the article is in the ''NS_FOO'' namespace:
 
{{code|<php>
 
{{code|<php>
$wgHooks['ArticlePropertiesClassFromTitle'][] = 'wfUseFoo';
+
$wgHooks['ArticlePropertiesClassFromTitle'][] = 'wfUseLocationExampleClass';
function wfUseFoo( $title, &$class ) {
+
function wfUseLocationExampleClass( $title, &$class ) {
 
if( $title->getNamespace() == NS_FOO ) $class = 'LocationExample';
 
if( $title->getNamespace() == NS_FOO ) $class = 'LocationExample';
 
return true;
 
return true;
 
}
 
}
 
</php>}}
 
</php>}}
 
  
 
== Overriding default MediaWiki actions ==
 
== Overriding default MediaWiki actions ==

Revision as of 00:48, 31 May 2012

This extension was created in early 2012 and is available from our extensions repository here. The extension which creates a new ArticleProperties class that is a sub-class of Article. As the name indicates, the extensions main idea was to provide a mechanism by which different classes of articles could be created that each have their own collection of persistent properties.

The ArticleProperties class is an abstract class (one that's designed to be sub-classed, and not to be instantiated directly). It provides the common functionality allowing all its sub-classes to declare the names and types of properties that should be associated with each article if that type. This common class also offers a simple means by which the page can render its MediaWiki actions in their own specific ways.

Each ArticleProperties sub-class has three static variables, table which is the name of the database table the class will store it's instances data in, columns which determine the property names and their database data-types, and an option prefix to use for column names so they don't conflict with column names of other tables.

A special page called Special:ArticleProperties allows the creation of the tables for the sub-classes or to add new columns to them.

Simple example

Here's a basic example ArticleProperties sub-class definition.

{{{1}}}


A column called "page" is automatically added which will contain the page ID of the MediaWiki article that the properties apply to. There is only a single row for any given page. Here's the "locations" table created by the ArticleProperties class for the sub-class shown above.

+------------------+-------------+------+-----+---------+-------+
| Field            | Type        | Null | Key | Default | Extra |
+------------------+-------------+------+-----+---------+-------+
| example_page     | int(11)     | NO   |     | NULL    |       |
| example_lat      | float       | YES  |     | NULL    |       |
| example_lon      | float       | YES  |     | NULL    |       |
| example_streetno | varchar(8)  | YES  |     | NULL    |       |
| example_street   | varchar(32) | YES  |     | NULL    |       |
| example_city     | varchar(32) | YES  |     | NULL    |       |
| example_postal   | varchar(16) | YES  |     | NULL    |       |
| example_country  | varchar(32) | YES  |     | NULL    |       |
| example_notes    | text        | YES  |     | NULL    |       |
+------------------+-------------+------+-----+---------+-------+


Determining which class a page should instantiate as

The extension provides a hook called "ArticlePropertiesClassFromTitle" which allows its sub-classes to easily define rules by which they should become the class used for a MediaWiki page, for example a specified namespace could use a specific ArticleProperties sub-class instead of the standard Article. In this example, the LocationExample class defined above will be used if the article is in the NS_FOO namespace:

{{{1}}}

Overriding default MediaWiki actions

Not only does the ArticleProperties class allow its sub-classes to have persistent properties, but it also allows the default rendering, editing and saving actions to be overridden so that they can incorporate their properties appropriately. A number of other methods are provided for making interaction with the properties easier which are described in more detail below.

The sub-classes can use view(), edit() and save() methods to override the default article functionality. The edit method allows new form fields to be added to the edit form, and the save method allows these to be processed and written into the page_props table. To continue the example above, here's an edit and save method added to integrate the page with one of the persistent properties (the Notes property).

{{{1}}}

The input and label methods are supplied by the ArticleProperties class (along with a number of other useful methods for constructing forms and dealing with page properties). It creates an input named wpNotes and a label for it using an i18n message. The save method then writes this value into the page properties. Any existing value will automatically be shown in the input field.

The ArticleProperties class also provides a query method which allows conditions and options to be sent in the same format used by the SQL Database::select method, and it returns a list of Title objects for matching articles.

And it also provides a table method that allows a list of titles to be rendered as an HTML table. The method takes three parameters, the second two are optional. The first is the title-list, the second an array of HTML attributes such as class and id that the resulting table should have. And the third parameter is an array of columns that the table should use. If the columns are not provided, they will be extracted from the properties of the first article from the title list.

Passive and non-passive instantiations

Another aspect that has been found to be required is a way for the sub-classes constructors to differentiate between a "passive" instantiation used for example to call methods on ArticleProperties instances in a search result, and "non-passive" instantiation which occurs when the instance represents a wiki article being currently viewed. The constructor needs to know because the class may make adjustments to the skin or other global elements of the system in the latter case, but should leave them alone for passive instantiations.

When the ArticleProperties class creates one of the sub-classes via the ArticleFromTitle hook it calls the constructor along with the extra $passive parameter set to false. The following example demonstrates how a sub-class defines its constructor to make adjustments to the skin in the non-passive case.

{{{1}}}

JavaScript integration

Often ArticleProperties sub-classes have JavaScript aspects to their view and edit methods and these client-side code needs to have access to some of the instances properties. The ArticleProperties class provides a simple solution to this which is to add an array to the sub-class that defines the object properties which should be made available to the client side. These will be placed into a JavaScript object of the same name as the ArticleProperties sub-class. Here's an example continuing with the "ExampleLocation" class defined above.

{{{1}}}

This makes two of the persistent properties available to the JavaScript as window.LocationExample.Lat and window.LocationExample.Lon.

TemplateProperties extension

Another extension which is still in development called TemplateProperties then extends the ArticleProperties concept by tying in to the events of a specified list of templates (similar to the concept of "record" articles in RecordAdmin). It adds events so that the named parameters in these specified templates are synchronised with the article's properties.

The extension also adds three parser-functions to allow access to the property information from within article text. The three parser-functions allow for the retrieval of a single property, a query resulting in a simple list, and a query resulting in a sortable table respectively.

These queries retrieve their data from the article properties so that no text parsing is necessary. But if any value being requested doesn't exist in the page_props database table, then it is extracted from the text (if it exists in the text) and added to the table before being returned.

When the template values are changed by an article's text being edited, the new values are extracted (or possibly obtained by hooking in to the parser's information on the current values, and the page_prop table updated.

It would also make sense for this extension replace RecordAdmin by making it add fields to the edit form for editing the article properties and removing the template syntax from the article.

See also