Extension:Semantic Internal Objects

Semantic Internal Objects is an extension to MediaWiki, that works in conjunction with Semantic MediaWiki. It provides two parser functions, '#set_internal' and '#set_internal_recurring_event', both of which are used to define "internal objects" within the Semantic MediaWiki system. There are compound types of information, sometimes known as 'n-ary relations', that involve more than one data value associated together. Semantic Internal Objects lets you define a two-dimensional table of information on a single page, with a call to #set_internal being used to store each row.

A simple example is in a cooking recipe: a recipe may call for 1 cup of flour, and the values "1", "cup" and "flour" must be encoded together - by themselves, the values are not meaningful (the third value has meaning, though not all of the meaning it could have).

Such compound information can also be stored via SMW itself. How and whether you should, though, depends on which version of SMW you're using:
 * For versions of SMW before 1.7, the "Record" type offered the ability to store compound information in a single value. Though the Record type still exists, it has major problems in flexibility and queriability, and should simply be avoided.
 * For SMW 1.7, subobjects also exist. However, they lack the ability to be called without a name, which makes them unusable in the standard way they're called, which is as part of multiple-instance templates, via the Semantic Forms extension. Again, SIO has no real alternative.
 * For SMW 1.8 and higher, subobjects can be called without a name, which means that they can be used in a very similar manner to SIO. In fact, if you're using SMWSQLStore3, which is new in SMW 1.8, #set_internal and #set_internal_recurring_event both simply call #subobject to store their data, making SIO a sort of alias around subobjects. It could be that, in the future, SIO will simply become a wrapper around subobject in all cases, especially after support for earlier versions of SMW is dropped.

Even with SMW 1.8, and even with SMWSQLStore3, however, there are still some advantages to using Semantic Internal Objects - see below.

This extension requires version 1.5.3 or greater of Semantic MediaWiki.

Download
You can download the Semantic Internal Objects code, in .tgz format, by clicking here.

You can also download the code directly via Git from the MediaWiki source code repository. From a command line, call the following:

The code can be viewed online, with the full history for each file, here.

Installation
To install this extension, create a 'SemanticInternalObjects' directory (either by extracting a compressed file or downloading via Git), and place this directory within the main MediaWiki 'extensions' directory. Then, in the file 'LocalSettings.php', somewhere below the inclusion of Semantic MediaWiki (both the main 'include_once' line and the 'enableSemantics' line), add the following line:

Usage
The syntax of #set_internal is as follows:

It is very important to note that the first argument is a property pointing from the object, to the page, and not the other way around! This is a bit counter-intuitive, but it makes meaningful querying possible. To follow the recipe example above, the value of object_to_page_property could be 'Part of recipe', but not 'has ingredient'.

A sample call to #set_internal would be:

This call would be placed in a page for a recipe, and it would define an object that had an automatically-generated name; if it were in a page called "Carrot cake", for instance, the object would be called "Carrot cake#1". If that page had subsequent calls to #set_internal, the objects that those calls generated would be called "Carrot cake#2", "Carrot cake#3", etc.

Every one of these properties, including the first one (i.e., "Part of recipe" in the example) needs to be defined on its own property page - and the first needs to be of type "Page".

It should be noted that #set_internal does not display anything to the screen; display of the values has to be handled separately (this can be done easily if the function is called from a template).

Querying internal objects
Internal objects, once stored, can be queried as if they were wiki pages. So the following query would show a table of all the recipes that contain more than 1/2 a cup of flour, and the number of cups they contain:

Note the "mainlabel=-" parameter in the query: that hides the names of the internal objects from users, since those names are confusing and basically meaningless.

Lists of values
You can have #set_internal store a list of values for a property, instead of just one. To do that, you just need to append "#list" to the property name, and separate the values by commas. For instance, to record, in a page called "United States", the names of all presidents and their vice-presidents, you could have calls like:

Creating recurring events
The #set_recurring_event function in Semantic MediaWiki lets you set a series of date values for a single page, representing a recurring event. Unfortunately, because of the way SMW's querying works, this is sometimes not an ideal solution, because individual instances of the event can't be easily separated from one another. Instead, you can call #set_internal_recurring_event, which has a syntax that's a cross between #set_internal and #set_recurring_event, and defines a separate internal object for each instance of the event, with a different date for each. This allows for precise querying and display of only those event instances that fall within a certain date range.

The (abridged) syntax for #set_internal_recurring_event is:

Here is an example of such a call, on a page that defines a recurring event:

You could then display a table of all the events that happened in a certain week, along with their date, with the following call:

Known issues

 * Having more than one call to #set_internal_recurring_event in the same page sometimes causes duplicate objects to be stored.
 * It appears that, at least in some circumstances, all property names are required to have their first letter capitalized in the #set_internal call, for it to work correctly. (Though this is recommended practice anyway.)
 * In previous versions of Semantic Internal Objects, calls to #set_internal sometimes also led to objects being stored, and displayed, twice. This problem tended to occur after a template containing a call to #set_internal was resaved, or after a full SMW data refresh was called. This bug has been (mostly) fixed - if you still experience this problem, please contact the author at yaron57 -at- gmail.com, or write on the talk page.

Differences from #subobject
Since version 1.7, Semantic MediaWiki has contained its own, separate functionality for storing internal/compound data - subobjects, which are defined using the parser function #subobject. This functionality is similar to #set_internal, including similar syntax, though there are some important differences:
 * In SMW version 1.7, the name of each subobject has to be specified, instead of manually assigned, which makes subobjects difficult to use within a common usage of SIO, multiple-instance templates in Semantic Forms.
 * In #subobject, you have to manually specify the "main" property (pointing from the "object" to the page), by adding something like "|Is part of= ".
 * There is not yet an equivalent to #set_internal_recurring_event for subobjects.
 * There is not yet an equivalent to #store_external_table, which uses SIO, as defined in the extension External Data.

Bugs and feature requests
You can use the Semantic MediaWiki mailing list, semediawiki-user, for questions, suggestions or bug reports about Semantic Internal Objects. If possible, please add "[SIO]" at the beginning of the subject line, to clarify the subject matter. The extension can also be discussed via IRC at irc://irc.freenode.net/#semantic-mediawiki

You can also send specific code patches to Yaron Koren, at yaron57 -at- gmail.com.

Authors
Semantic Internal Objects was written by Yaron Koren, reachable at yaron57 -at- gmail.com. Important contributions were made by Jamey Wood.

Semantic Internal Objects was initially funded by STAR Software (Shanghai) Co., Ltd., a member of the STAR Group.

Version history
Semantic Internal Objects is currently at version 0.7.

The version history is:
 * 0.1 - August 19, 2009 - Initial version
 * 0.2 - January 1, 2010 - Database calls turned into a single transaction; support for many languages added
 * 0.3 - February 10, 2010 - Support added for SMW 1.5 and properties of type 'Text'
 * 0.4 - March 2, 2010 - Better handling for automated SMW updating; handling of lists of values added, via '#list'; support for values containing '='
 * 0.4.1 - May 13, 2010 - Support added for SMW 1.5.1; possible fix for some data-refresh issues
 * 0.5 - June 4, 2010 - RDF export added; handling added for new coordinates representation in Semantic Maps 0.6
 * 0.6 - July 16, 2010 - Fix for "duplicate rows" bug; fix for when Semantic Maps is not installed; improvements to RDF export
 * 0.6.1 - September 26, 2010 - Fix for duplicate rows for *actual page*, occurring with SMW 1.5.2 and higher; #set_internal_recurring_event added
 * 0.6.2 - November 5, 2010 - Restored handling for deletion of pages, accidentally removed in previous version; added handling for moving of pages
 * 0.6.3 - November 29, 2010 - Fix for #set_internal_recurring_event for SMW 1.5.3 and higher
 * 0.6.4 - June 7, 2011 - Support added for SMW 1.6; support removed for SMW < 1.5.2
 * 0.6.5 - July 22, 2011 - Further handling added for SMW 1.6
 * 0.6.6 - August 3, 2011 - Another fix for SMW 1.6
 * 0.6.7 - October 18, 2011 - Support added for the Page Schemas extension
 * 0.6.8 - January 20, 2012 - Support removed for MediaWiki < 1.16
 * 0.6.9 - July 10, 2012 - Handling fixed for extra spaces in #set_internal and #set_internal_recurring_event
 * 0.7 - November 21, 2012 - #subobject is called when using SMWSQLStore3 (for SMW 1.8+); fix for lowercased main property name; support removed for SMW 1.5.2