Good, easy to use, ticketing systems are few and far between. Most cost a lot of money; others are free, but lack features; some are free but have way too many features that are all poorly implemented. This article will explain how to create a simple ticketing system with supporters, supporter groups, customizable fields, and emailing capability.
Notice that this ticketing system’s functionality will mostly be based on the functionality of OneOrZero Helpdesk (now AIMS). This isn’t a endorsement of the OOZ software. In fact, I went through the trouble of implementing a system like this specifically to move away from OOZ. OOZ is quasi-open source, and is switching to a CMS model, which defeats the purpose of its simple helpdesk nature.
- Get the software
- Create the structure
- Create properties
- Create templates
- Create the Ticket template
- Create the User template
- Create the Supporter group template
- Create forms
- Create the Ticket form
- Create the User form
- Create the Supporter group form
- Create the Supporter groups
- Create your navigation
- Create basic sidebar navigation
- Create sidebar navigation based on groups
- Create sidebar navigation based on categories
- Add statistics
- Optional configuration
- Missing features
- Gotchas and workarounds
- Exporting the system from my prototype
- TODO
- Comments (31)
Get the software
The following software and extensions will be used for this:
Follow the installation instructions provided by MediaWiki and each extension.
Create the structure
Note that before we get too deep into this, that I have an implementation of this already ready to test, and easily export. So, if you don’t want to go through the pain of creating all of the properties, templates, and forms, just get them from my prototype wiki. I’ll have instructions to do so at the end of this article.
Create properties
This will define the basics of your ticket. What information do you want to gather from the end-user? Use Special:CreateProperty for this (“Create a property” on Special:SpecialPages). Here’s a quick list to start you off:
- Supporter group – String
- Supporter – Page
- Priority – String; add a list of priorities here, I recommend:
- Critical
- High
- Medium
- Low
- Status – String; add a list of statuses here, I recommend:
- Unassigned
- Open
- In progress
- Waiting for response
- Closed
- First name – String
- Last name – String
- Username – String
- Building – String
- Room – String
- Phone number – String
- Short description – String
- Long description – Text
- Attachment – Page
Adding more properties, and modifying them later isn’t difficult, so don’t worry too much if you don’t get everything you need at first.
Create templates
Now that you have properties defined, you’ll want a way to programatically fill them with values, and to display them. Semantic Forms has a special page to create a template from a list of properties. We should use this to create the templates. Go to Special:CreateTemplate, which can be found in special pages as “Create a template”.
Create the Ticket template
- Enter “Ticket” for the template name (without the quotes)
- Enter “Tickets” for the category name (without the quotes)
- Add your fields from the properties previously created
- I recommend making the “Field name” and the “Display name” of each property the same as the property itself. So, for “First name”, “Field name” would be “First name”, and “Display name” would also be “First name”. Make sure to select “This field can hold a list of values, separated by commas” for fields that should be allowed to have multiple values. In this example, we are going to ensure “Supporter group”, “Supporter”, and “Username” allow multiple values, at minimum
- Use “Standard” as the output format, and click “Save”; you can tweak the output format heavily later
- Edit the template, and change the following portions, to add ST support:
- Change the “Supporter group” arraymap to: {{#arraymap:{{{Supporter group|}}}|,|x|[[Supporter group::x]] [[Assigned to group::x| ]]}}
- Change the “Supporter” arraymap to: {{#arraymap:{{{Supporter|}}}|,|x|[[Supporter::User:x|x]] [[Assigned to::User:x| ]]}} {{#if:{{{Supporter|}}}|([[Special:EmailUser/{{{Supporter|}}}|email]])|}}
- Change the “Username” arraymap to: {{#arraymap:{{{User name|}}}|,|x|[[Username::User:x|x]] {{#if:x|([[Special:EmailUser/x|email]])|}} [[Carbon copy::User:x| ]]}}
Create the User template
In this helpdesk system, we want users to be able to mark themselves as supporters, and provide some information about themselves. Since this is a wiki, we are assuming it is fairly open. If you want this to be locked down, you’ll have to find another method to go about this; notice, that this is possible, I just won’t go into it.
- Enter “User” for the template name (without the quotes)
- Leave the category name blank
- Add fields for first name, last name, phone number, building, and room
- Use “Standard” as the output format, and click “Save”; you can tweak the output format later (I like using actual infoboxes here)
- Edit the template; at the end of your template, add: {{#ifeq:{{{Supporter|}}}|Yes|[[Category:Supporters]]|}}
- This will allow us to conditionally add people to the Supporters category
Create the Supporter group template
Unfortunately, SMW doesn’t allow you to query user pages based on MediaWiki user groups. So, we’ll make supporter groups based on SMW properties. We’ll want to have support groups that can hold a list of supporters.
- Enter “Supporter group” for the template name (without the quotes)
- Enter “Supporter groups” for the category name (without the quotes)
- Add the Supporter property; make sure to select “This field can hold a list of values, separated by commas”, as groups should be allowed to have multiple supporters
- Use “Standard” as the output format, and click “Save”. It really doesn’t matter what these look like; this is only used to add/remove supporters to/from groups
Create forms
Now that we have a way to programatically fill SMW values, and display them, we’ll want to make something for users to easily enter tickets. SF has a special page to create forms, based off of templates. To create the Ticket form, visit Special:CreateForm, which can be found in special pages as “Create a template”.
Create the Ticket form
- Type “Ticket” for the Form name (without the quotes)
- Select “Ticket” from the Add template drop down; click “Add”
- Select Mandatory for whichever fields should be mandatory, and click “Save page”
Create the User form
- Type “User” for the Form name (without the quotes)
- Select “User” from the Add template drop down; click “Add”
- Select Mandatory for whichever fields should be mandatory, and click “Save page”
- Make sure the Input type for the Supporter field is set as checkbox; we aren’t setting a supporter here, but instead a true/false value that will decide if they are in the supporters category or not
Create the Supporter group form
- Type “Supporter group” for the Form name (without the quotes)
- Select “Supporter group” from the Add template drop down; click “Add”
- Select Mandatory for the Supporter field, and click “Save page”
- Edit the form, and change the supporter field to: {{{field|Supporter|input type=checkboxes|values from category=Supporters}}}
Create the Supporter groups
Creating supporter groups allows you to send ticket creation emails to entire groups of users, and allows users to get a view of only the tickets that pertain to their role. To create a supporter group:
- Visit Form:Supporter group
- Type the name of the group you wish to add into the inputbox, and click “Create or edit”
- Select the users you wish to add, and click “Save page”
Create your navigation
Obviously, to test any navigation, you’ll want to add some test tickets first. So, do that before starting this.
Create basic sidebar navigation
For the basic sidebar navigation, you’ll want anonymous users to be able to view all open tickets, and all recently closed tickets. To add the basic navigation do the following:
- Visit Special:Ask
- Create your query using your own username in the query, and test it
- Hide the query
- Copy the URL
- Add the link to MediaWiki:Sidebar
Create sidebar navigation based on groups
Logged-in users need to be able to create tickets, view/edit their open tickets, and view/edit their recently closed tickets. It is easy enough to query per user for tickets in Special:Ask; the problem is that MediaWiki has no way, except via Javascript, to have content display differently per user. To add the group based navigation do the following:
- Visit Special:Ask
- Create your query using your own username in the query, and test it
- Hide the query
- Copy the URL
- Add the link to MediaWiki:Sidebar/Group:user. Make sure you add a new section, and add the link under that section. Also, make sure that “user” in “Group:user” is lowercase. “User” won’t work.
- Modify the link to change your username to USERNAME
- Add Javascript to MediaWiki:Common.js to change USERNAME to wgUsername
Create sidebar navigation based on categories
Users who add themselves to the supporters category, and support groups, will need to be able to view/edit their groups’ open and recently closed tickets. Like the user group sidebar, we’ll also need to change USERNAME to wgUsername, but the already created Javascript should handle that. Something extra we’ll need in this query, is a list of supporter groups to which the user belongs. We’ll need to use this list inside of our query. Thankfully, since we added supporter group pages, that have supporters as properties, we can get this list using a subquery. To add the category based navigation, do the following:
- Visit Special:Ask
- Create your query using your own username in the query, and test it
- Your query should look somewhat like this: [[Category:Tickets]][[Supporter group::<q>[[Supporter::Ryan Lane]][[Category::Supporter groups]]</q>]][[Status::!Closed]]
- Hide the query
- Copy the URL
- Create your query using your own username in the query, and test it
- Add the link to MediaWiki:Sidebar/Category:Supporters; make sure you add a new section, and add the link under that section
- Modify the link to change your username to USERNAME
Add statistics
I won’t go into too much detail here, since everyone has their own idea of what their statistics need to be. I have an example stats page to check out. You can use this as a base to get started. Notice that the example statistics page would be very inefficient for a large amount of tickets. I’ve tested it with 35,000 tickets, and it took nearly a minute and a half to load. I recommend breaking the page up, and possibly doing it more efficiently than I am.
Statistics look better with charts. I don’t have plotting support added in this prototype, yet; however, I plan on using my Plotters extension to take care of that. If you’d like to help out with the Plotters extension with Javascript, or PHP coding, I’d be more than appreciative.
Optional configuration
Optionally, you can move tickets into their own namespace, if you want them to be separate from the rest of your content. This is likely a good idea if you use your wiki as a documentation system. Remember, though, if you do this, to add the namespace to $smwgNamespacesWithSemanticLinks.
Missing features
- No supporter only comments.
- No separate forms for supporters and end-users; though, with a little extra effort, this is doable with some Javascript and/or multiple ticket forms.
- The long description field is not searchable via the advanced search form, or via ask queries, as text properties can’t be searched via ask.
Gotchas and workarounds
- Fields accept wiki text, and not all wiki-text will work in your fields. In fact, some of it will cause that field not to display, and will cause it to be ignored by SMW.
- A workaround is to add the text to the page twice; once as a pre tag, that displays the text, and another, adds the property via a {{#set:<property>=<value>}} call. For example: {{#set:Long description={{{Long description|}}}}} {{#tag:pre|{{{Long description|}}}|style=”white-space: pre-wrap; white-space: -moz-pre-wrap; word-wrap: break-word; border-style: none; background-color: white; padding: 0px; white-space: normal;”}}
- This workaround doesn’t solve the problem for SMW. Some tickets simply won’t have values for bad text.
- Ask queries are case sensitive. For properties that have a list of values, this isn’t too much of an issue, but for fields like “Short description”, this makes searches difficult.
- A workaround for this is to lowercase values in properties, like: [[Short description::{{lc:{{{Short description|}}}}}]]
- Semantic Forms currently has a bug (verified in 1.9 and below) that will not read text that has been entered, and will cause properties to appear empty. Known problematic characters are {, | and }
- A workaround for this is to add Javascript that will encode {, | and } characters on form save, and decode them on form load – this will cause problems inside of pre blocks.
- The Semantic Forms author is aware of the bug. We’ve discussed possible solutions, but no code changes have occurred.
Exporting the system from my prototype
As mentioned at the beginning of this article, you can export the system I already have implemented, to save some work. Export the following categories and pages to get the system:
- Category:Ticket properties
- Category:Helpdesk interface
- MediaWiki:Sidebar
- MediaWiki:Sidebar/Category:Supporters
- MediaWiki:Sidebar/Group:user
- Template:Infobox
You will also want to manually copy the Javascript I’m using from MediaWiki:Common.js, and add it to your Javascript in MediaWiki:Common.js. Notice that you don’t necessarily want to export the category pages, but instead you want to export the pages in the categories. Special:Export has a field to do this. Also, my prototype wiki has tickets kept in a separate namespace. You’ll need to make some minor changes to the exported pages after importing them, if you don’t want tickets in a separate namespace. When exporting, ensure you have “” checked.
TODO
This is mostly a first-take at a system like this; the following things could be done to improve it:
- Auto-populate the fields in the ticket with information from the user’s properties when creating tickets
- Make the sidebar Javascript more generic
- Update ST to have email templates, so that users don’t have to see confusing wiki-text in task assigned/created and diff emails
- Update SMW to add properties to user pages for MediaWiki groups
- Update SMW to allow Text fields to be searchable via ask
- Update SMW to allow case insensitive searches in ask
- Update LiquidThreads to allow transcludable discussions, so that they can be shown below ticket information on the ticket page
If you’d like to help, I’ll give you access to modify the prototype wiki. Coordination on changes ahead of time is preferred.