Jump to: navigation, search

Self-referencing, in the context of Semantic MediaWiki, describes when a query for a page's property value is made on the page itself. In code, it might look like the following:

{{#show: {{PAGENAME}} | ?SomeProperty }}

This technique effectively says, "pull from the database the value of SomeProperty for this page."

Setting property values based on a self-reference

Using a self-reference to set another property on the same page can lead to trouble. In the following example, AnotherProperty is set to the value of SomeProperty:

{{#set: AnotherProperty = {{#show: {{PAGENAME}} | ?SomeProperty }} }}

The problem with this is that the value returned for SomeProperty might be old. To explain, let's say we have a page with the following contents:

{{#set: SomeProperty = green }}
SomeProperty: {{#show: {{PAGENAME}} | ?SomeProperty }}

{{#set: AnotherProperty = {{#show: {{PAGENAME}} | ?SomeProperty }} }}
AnotherProperty: {{#show: {{PAGENAME}} | ?AnotherProperty }}

To keep things simple, let's assume both SomeProperty and AnotherProperty are of type Text.

When you first save the page, you will see the following:

SomeProperty: green


If you browse the properties for that page, you'll see that there is no set value for AnotherProperty. This is because at the time the page was saved, there was no set value for SomeProperty.

Now, if the page is revised by simply changing the word "green" to "red", you will see the following output:

SomeProperty: red

AnotherProperty: green

SomeProperty is updated to red as expected, but AnotherProperty is now "green". This is because the value of SomeProperty was still "green" at the time the page was saved.

This kind of mistake can also be made when adding subobjects or when using Semantic Forms.

Example test page

Try this out for yourself on this test page.

Avoiding self-referencing issues

Generally, it is best to avoid use of the self-referencing property definition pattern as described above. If you are using Semantic Forms, just set the property to the value for the field as in the following example:

{{#set: MyProperty = {{{MyProperty|}}} }}

Extension:Variables provides another way to avoid this issue. This extension allows you to define a variable on a page and use it later in that same page. See the documentation for its full feature list.

If we install and use this extension, the previous example can be fixed as follows:

{{#vardefine: SomeProperty | green }}{{#set: SomeProperty = {{#var: SomeProperty }} }}
SomeProperty: {{#show: {{PAGENAME}} | ?SomeProperty }}

{{#set: AnotherProperty = {{#var: SomeProperty }} }}
AnotherProperty: {{#show: {{PAGENAME}} | ?AnotherProperty }}

Note that the #vardefine function is placed before the #set function.

This will result in the following output:

SomeProperty: green

AnotherProperty: green

This same technique can also be used when generating subobjects. For example:

|Color={{#var: SomeProperty }}