Difference between revisions of "Bliki 3.0"

From Organic Design wiki
(Post form)
(News post form)
Line 24: Line 24:
 
== News post form ==
 
== News post form ==
 
The easiest place to start with the description of blog functionality is with the post form since that's where it all begins from a users perspective. If the wiki was running the ''Semantic Forms'' extension, then that may well be the best approach to constructing a form to create the blog posts. But in this example I'm making a custom form with raw HTML ('''Note:''' ''$wgRawHTML'' should only ever be used on wikis that don't allow public editing! if you allow untrusted users to edit, then using something like ''HTMLets'' of ''Widgets'' would be a better approach).
 
The easiest place to start with the description of blog functionality is with the post form since that's where it all begins from a users perspective. If the wiki was running the ''Semantic Forms'' extension, then that may well be the best approach to constructing a form to create the blog posts. But in this example I'm making a custom form with raw HTML ('''Note:''' ''$wgRawHTML'' should only ever be used on wikis that don't allow public editing! if you allow untrusted users to edit, then using something like ''HTMLets'' of ''Widgets'' would be a better approach).
 +
 +
Below is an example of a form created using raw HTML. The form includes a section for ''tags'' which are just articles that are members of a "Tags" category. Tags will be described in more detail below, but what we have here in this form regarding tags is an ''#ask'' query that calls a template called ''Checkbox'' for every one of the members in ''Category:Tags''. Here's the content of the form page which uses the ''#tag'' parser-function to allow us to construct the content of an ''html'' tag that contains other parser-functions and templates. The ''REQUEST'' magic word is from the ''ExtraMagic'' extension and returns the specified query-string or post variable which allows the data in the form to persist after ''preview'' is clicked.
 
{|width=100%
 
{|width=100%
 
|
 
|
Line 33: Line 35:
 
<b>Content</b>
 
<b>Content</b>
 
<textarea name="content" rows="10">{{REQUEST:content}}</textarea>
 
<textarea name="content" rows="10">{{REQUEST:content}}</textarea>
}}
 
 
<b>Tags</b>
 
<b>Tags</b>
{{#ask:[[Category:Tag pages]]|format=template|template=Checkbox|link=none}}
+
{{#ask:[[Category:Tags]]|format=template|template=Checkbox|link=none}}
<html>
 
 
<input type="submit" name="type" value="Post" />
 
<input type="submit" name="type" value="Post" />
 
<input type="submit" name="type" value="Preview" />
 
<input type="submit" name="type" value="Preview" />
 
<input type="submit" name="type" value="News preview" />
 
<input type="submit" name="type" value="News preview" />
 
<input type="hidden" name="action" value="news" />
 
<input type="hidden" name="action" value="news" />
</form></html>
+
</form>}}
 
</pre>}}
 
</pre>}}
 
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 
|valign=top|<div style="border: 1px solid #ccc;float: right;padding:5px;margin-top:15px">[[File:Blog post form.jpg|300px]]</div>
 
|valign=top|<div style="border: 1px solid #ccc;float: right;padding:5px;margin-top:15px">[[File:Blog post form.jpg|300px]]</div>
 
|}
 
|}
To make the creation of news items easier (i.e. not having to remember categorisation or template syntax), the [[Post a news item]] article has been created that contains a simple form for entering the new item's title and content. The form contains a hidden input called ''action'' which is set to ''news'' allowing the extension to create the news item article with the correct template syntax and then redirect the user to the newly created page.
 
  
The form has two preview buttons, one to preview the whole news article, and the other to preview what the item looks like as part of the [[News]] page. The version that renders as an item in the news page can be made into just a small summary by using ''<nowiki><noinclude></nowiki>'' tags in the content so that the main text only renders when viewing the page itself.
 
  
The form also has a checkbox for each of the tag categories (categories that are members of [[:Category:Tags]]). When the form is posted, the extension will add a category link for each of the tags inputs that were checked. The category links are inside ''noinlcude'' tags so that when news items are embedded in the [[News]] page it doesn't get categorised into all the tag categories used by the news items.
+
And here's the content of the ''Checkbox'' template which is called by the ''#ask'' query in the form to render a checkbox for every member of the ''Tags'' category. It first defines an ''name'' for the checkbox input that has any spaces replaced by underscores, then it builds an ''input'' element using the name and adds a ''checked'' attribute if the name exists in the post data (i.e. if the item is being previewed.
 
+
{{code|<pre>
When the item is previewed the post form is rendered again below the preview with all the data still filled in. This is done using the ''REQUEST'' parser-function from the ''ExtraMagic'' extension to fill in the values of the inputs. The checkbox states are preserved by rendering them with an SMW query on the tags category that renders the checkbox through [[Template:Checkbox]].
+
{{#vardefine:name|tag{{#replace:{{{1}}}| |_}}}}{{#tag:html|<div class="news-tags-input"><input type="checkbox" name="{{#var:name}}" {{#if:{{REQUEST:{{#var:id}}}}|checked}} />&nbsp;{{{1}}}</div>}}
 
+
</pre>}}
When the item is posted, the new article is created, and the summary and content fields placed into the first and second parameters of a call to [[Template:News]]. The tags are all created as category links following the template call along with category links to categorise the new item into [[:Category:News]] and the user's "Posts by USERNAME" cateogory. The category links are all wrapped within a ''&lt;noinclude&gt;'' section so that any pages including the items via news queries won't also get categorised (which is what happens when using DPL since it ignores these ''&lt;noinclude&gt;'' sections!).
 
 
 
==== News template ====
 
News item articles are created with all the content passed within the [[Template:News|News template]] which adds the author, tags and post date above the item with a link back to the main news page, and adds the DISQUS comments below the item. Note that the template returns just the plain summary of the news item if the current page is not the actual post item so that queries on posts can decide on their own formatting and don't have all the DISQUS and main content for every post.
 
 
 
[[Template:News]] determines whether the current page is the actual news item rather than a page querying news items by checking if the current article is a member of [[:Category:News]] since only news items are categorised into this category.
 
 
 
==== News query template ====
 
Use [[Template:NewsQuery]] to render news items in the format seen on the [[News]] page, the [[:Category:Tag pages|tag pages]] and [[Special:ListUsers|users pages]]. A category name can be supplied as a parameter to this template which will filter the results to only members of that category. The query is done using the [http://semantic-mediawiki.org/wiki/Help:Template_format SMW template format] to render the results through [[Template:SMWNews]].
 
 
 
The parameters recognised by [[Template:NewsQuery]] are '''category''' which if supplied will filter the posts to only members of the supplied category, and '''count''' which limits the number of posts displayed to the specified amount with a default of 20.
 
 
 
==== Tags ====
 
Blog posts can have a list of tags associated with them so they can easily be searched by tag. The post form uses an SMW query and [[Template:Checkbox]] to render checkboxes for adding tags to newly created news items.
 
 
 
A list of tags the item belongs to is added to the news item using [[Template:TagList]] which takes the article title as it's only parameter. This template does an SMW ''#ask'' query to list all the tag-categories, and then for each of these [[Template:TagLink]] is called which uses the SMW ''#show'' parser-function to test whether the article belongs to the passed tag-category and renders a link to it if so. Here's an example of the output of the ''TagList'' template when passed the title [[Another Test]]:
 
<center>{{TagList|All categories}}</center>
 
 
 
Every tag in the wiki has both a category page and a description page which is an article of the same name in the Main namespace. The tag categories all have <tt><nowiki>{{tag}}</nowiki></tt> at the start which uses [[Template:Tag]] to display a message about tag categories and to categorise the tag into [[:Category:Tags]]. Likewise, each tag page has <tt><nowiki>{{tagpage}}</nowiki></tt> at the start which uses [[Template:Tagpage]] to display a message about tag pages and to categorise the tag page into [[:Category:Tag pages]].
 
 
 
'''Note:''' It's very important that every tag has both of these entries in the wiki because SMW uses these categories to properly filter news query results, and it also uses the [[:Category:Tag pages|Tag pages category]] by queries such as [[Template:TagList]] and the checkbox rendering in [[Post a news item]]. This is because SMW only returns article-members of category queries and not sub-categories.
 
 
 
==== News feeds ====
 
The news items are available via RSS and Atom by utilising MediaWiki's existing feed capabilities which are tied to the recent changes mechanism. Since we only want changes related to news items, I've added a handler in the extension to the [http://www.mediawiki.org/wiki/Manual:Hooks/SpecialRecentChangesQuery SpecialRecentChangesQuery hook] which filters the changes to only items in [[:Category:News]] if a query-string item ''news=1'' exists. This allows us to simply use the existing feed URL's but with ''news=1'' added to get our news feeds. You can see this filter working by adding the query-string item to a normal recent changes URL, e.g. {{SERVER}}/Special:RecentChanges?news=1.
 

Revision as of 22:37, 25 July 2013

I recently worked on a job that required a blog-like functionality to be done in the wiki. I started off basing the system on my Bliki 1.0 method, but started to run into problems implementing a tagging solution (having a tags category of categories, and having each tag page contain a blog-roll query for items of that tag. I got the system to work, but it was messy because the DynamicPageList (DPL) extension that the Bliki functionality is based on ignores includeonly tags and therefore caused all the pages containing blog-roll queries to become categorised into all the tag categories. These query pages could be filtered out of the query results, but it wasn't elegant.

The site I was implementing this functionality on uses Semantic MediaWiki (SMW) for a lot of its other functionality, so I decided to see if I could implement the Bliki functionality with SMW as well and drop DPL all together. This worked out very well and didn't have any messy categorisation problems and was overall a lot more efficient as well. This article describes the process of how to implement a similar system.

Environment

The method required a few extension other than just SMW (and Validator that SMW depends on).

The following configuration in LocalSettings.php are needed as well (this is in addition to the inclusion of the extensions and their default configuration options).

$wgRawHtml = true;
$wgPFEnableStringFunctions = true;
$smwgQSubcategoryDepth = 0;
$smwgPageSpecialProperties = array( '_CDAT', '_LEDT' );
  • Note1: the $wgRawHtml global has been set so that it's easier to add forms, specialised links and JavaScript functionality to articles such as the post a news item page. This is perfectly safe since public signup and editing has been disabled.
  • Note2: $smwgQSubcategoryDepth being set to zero is of particular importance in our installation since the blog functionality must only return direct category members.
  • Note3: $smwgPageSpecialProperties is added to include the creation and last editor information in an article's semantic properties.

News post form

The easiest place to start with the description of blog functionality is with the post form since that's where it all begins from a users perspective. If the wiki was running the Semantic Forms extension, then that may well be the best approach to constructing a form to create the blog posts. But in this example I'm making a custom form with raw HTML (Note: $wgRawHTML should only ever be used on wikis that don't allow public editing! if you allow untrusted users to edit, then using something like HTMLets of Widgets would be a better approach).

Below is an example of a form created using raw HTML. The form includes a section for tags which are just articles that are members of a "Tags" category. Tags will be described in more detail below, but what we have here in this form regarding tags is an #ask query that calls a template called Checkbox for every one of the members in Category:Tags. Here's the content of the form page which uses the #tag parser-function to allow us to construct the content of an html tag that contains other parser-functions and templates. The REQUEST magic word is from the ExtraMagic extension and returns the specified query-string or post variable which allows the data in the form to persist after preview is clicked.

{{#tag:html|<form class="blog" method="POST">
<b>Title: </b><input name="newtitle" size="50" value="{{REQUEST:newtitle}}" />
<b>Summary</b>
<textarea name="summary" rows="3">{{REQUEST:summary}}</textarea>
<b>Content</b>
<textarea name="content" rows="10">{{REQUEST:content}}</textarea>
<b>Tags</b>
{{#ask:[[Category:Tags]]|format=template|template=Checkbox|link=none}}
<input type="submit" name="type" value="Post" />
<input type="submit" name="type" value="Preview" />
<input type="submit" name="type" value="News preview" />
<input type="hidden" name="action" value="news" />
</form>}}
       
Blog post form.jpg


And here's the content of the Checkbox template which is called by the #ask query in the form to render a checkbox for every member of the Tags category. It first defines an name for the checkbox input that has any spaces replaced by underscores, then it builds an input element using the name and adds a checked attribute if the name exists in the post data (i.e. if the item is being previewed.

{{#vardefine:name|tag{{#replace:{{{1}}}| |_}}}}{{#tag:html|<div class="news-tags-input"><input type="checkbox" name="{{#var:name}}" {{#if:{{REQUEST:{{#var:id}}}}|checked}} /> {{{1}}}</div>}}