Extension:TopicTags

Under Development

This should work if installed as directed. But seeking feedback and improvements before release.

This page is under development, and may contain errors or omissions.

=Introduction= This extension provides inline topic-tags, which are completely independent of Categories. Wiki editors can insert topic-tags inline anyplace on a wikipage.

The new, unique feature of these topic-tags, is they can be scoped to specific locations within the body of a page. They are not just page-level tags. "Related pages" links will navigate directly to the tag location in the body text, instead of just to the top of the page.

(Note this extension is unrelated to MediaWiki edit-tags)

Why Not Use Categories?

 * Category scope is limited to the page-level. TopicTags can pinpoint specific text-locations in the page. Categories can't do that.
 * Links to a tagged-page are anchored directly to the tag-location, within the body-text-- the visitor's browser scrolls directly to that location.
 * We don't want Categories to interfere with, or be interefered with by, these TopicTags. Topic-tags should never appear in CategoryTrees or category lists.
 * TopicTags are intended to provide a finer-grained taxonomy than Categories.
 * Where wiki curators may use Categories as a hierarchical organizing system, TopicTags are always non-hierarchical.

Feature-Complete
Functionally, the current implementation does just about everything i want (at least for a first-release), in terms of user-experience and behaviors.

=Appearance= Topic-tags have 2 formats:
 * Inline, where the tag is associated with a specific location on a page.
 * Page-level, where the tag is associated with an entire page.

Pages:


 * For each unique tag-name, there's a Tag Page, containing a description of the tag, and a list of all pages containing the tag.
 * Also available is a public page listing all tags used in the wiki.

Inline Tags
An inline tag appears as a very small, super-script text-link. The font is extra-small, to differentiate from other common superscript text. When clicked, reader is directed to the Tag-Page. (see image, above).

Page Tags
A page tag appears at the bottom of the page in full-size text. Also displayed are "Related Pages": a list of links to all other pages containing the same tag.

Tag Page
For each tag, there's a Tag Page, containing a description of the tag, and a list of all pages tagged with that tag-name.

Tags Page
A list of all tags used in the wiki.

=Usage=

Clicking the tag-name in a tagged article
Click a tag-link to be directed to the Tag-Page.

Clicking a related-page link
Click a related-page link to be directed to a related wiki-page:
 * Key feature: If the tag is inline on the related wiki-page, the reader will be directed to the specific tagged location in the body text. 
 * If the tag is page-level tag on the related wiki-page, the reader will be directed to the top of the tagged page.

Inserting Tags
Tagging syntax was designed to be as simple as possible. Two topic-tag formats can be used in articles. The only difference is the trailing pipe | character. A tag-name may not contain an embedded space.

Inline Tags
Use the following syntax to insert an inline tag. Displays as a small superscript in the article, with NO list of related articles. : 

Page Tags
Use the following syntax to insert a page-level tag. Intended to be inserted at bottom-of-article. Displays normal-size bold, with list of related articles: 

Creating a Tag Description
This step isn't required-- you can insert a new tag into an article, and it will immediately appear on the Tags page. If you click the tag-name in the article, you'll get a list of all pages with the same tag.

But, if you want to display a tag-description on that list, then you'll need to create a description page for the tag-name. To create a new tag-description page:
 * 1) Browse to YOUR-WIKI-URL/Form:Tag
 * 2) Enter tag-name, and click "Create tag".
 * 3) Enter tag-description, and click "Save page".

=Installation= The current version of this extension is php-free, and can be installed manually. FTP is needed to install the depended-extensions, but not needed to install any part of this extension.

Done.
 * 1) Install all
 * 2) Create the.

Dependencies

 * Extension:Page_Forms
 * Extension:UrlGetParameters
 * Extension:DynamicPageList3
 * Extension:HTML_Tags
 * Extension:Labeled Section Transclusion
 * Extension:Arrays
 * Extension:ParserFunctions

Extension Pages
To create these pages, you need only to paste in the wikitext provided at the links below:
 * /Form-CreateTag
 * /Template-Tag
 * /Template-Tag/Preload
 * /Template-TagDPL
 * /Template-TagLink
 * /Page-Tag
 * /Page-Tags
 * /Template-Pin
 * /CSS-Common.css

=Implementation=

Simple, Yet Complicated
This extension does something pretty simple. I think it's features ought to be handled by MW core. But due to limitations of MediaWiki, the implementation is more complicated than i would like. To achieve it's simple goals requires some funky workarounds, and depends on at least six different extensions.

Still, it's pretty simple. There's no php (yet), and very little wiki-text. It's not at all large (not counting the needed extensions). I try to separate functional blocks into different pages, for clearer understanding and easier maintenance/upgrades.

Secret Sauce: Anchors
The secret sauce is anchors. Inline tags render as an HTML-anchor-- that makes it possible to link directly to the tag-location in the body of the wiki-page.

Inline tags will render HTML like this: Template:Pin simplifies creation of anchors.

Template:Tag
Through Transclusion, Template:Tag renders clickable HTML-links in tagged host-pages.

Inserted Topic-Tags are transclusions. When a host wiki-page contains the tag-code for Tag:Purple, it passes the tag-name, as a wiki-parameter, by nested transclusion, to Template:Tag. This enables Template:Tag to return HTML to be rendered on the host page.

For example, this inline tag-code on a wiki-page:  creates an HTML anchor on the host page. The rendered HTML looks like: CommonGround This page-level tag-code, with trailing pipe,  produces a list of related pages. That enables the user to jump directly to any related page: Tag:CommonGround   Portal:Welcome</a></li> <li> Openers</a></li> <li> Draft:blame guns.</a></li> <li> homicide rate.</a></li> </ul>

Notice the string "#Tag:" in each related-page link. That causes the link to go directly to the anchor-location in the body-text where the tag appears.

Visible Tag Page
When a tag-name is clicked in a tagged wiki-page, user is directed to visible page "Tag". Tag displays the tag-description and list of related pages.

There's only one visible Tag page, which serves all tag-names. A Url parameter is used to pass the tag-name into page Tag. That's the purpose of Extension:UrlGetParameters.

It would be better, more MediaWiki-ish, if MediaWiki supported page-parameters. Then we could do everything in wikitext, instead of mingling wikitext with HTML. But that was rejected by admins.

Static Tag Pages
Individual tag-pages exist for each tag-name, but the reader never sees them.

Individual tag-pages have one function:
 * to store the tag-descriptions. When visible page Tag is viewed for a particular tag, the tag-description is pulled from the static tag-page.

They are created by the form CreateTag. Tag-name is hardcoded into these pages. Static pages are preloaded with /Template-Tag/Preload. That's done by the /Form-CreateTag.

DPL Format
The DPL3 format syntax is: | format=Startall,Start,End,Endall

In our DPL statement, the commas are placeholders for each format-section (Startall,Start,End,Endall).

In this extension, only one format-section has formatting: the Start section. Start represents the beginning of each article in the list.

The star resolves to a bullet in the output.

https://help.gamepedia.com/DPL:Parameters:_Controlling_Output_Format#format

To ensure links in the list go to those inline anchors, DPL must include pound-anchor in the links it outputs for found pages. Must output wikitext syntax for anchors: display_as (actually, i think we're currently doing it with html "a" tag and url-params. Should change to wikitext style, if possible).

https://meta.wikimedia.org/wiki/Help:Anchors

DPL format is newline + found-page name linked to tag-anchor on found-page | format  = ,\n* %PAGE%,,

Note, if users use same tag in multiple locations on the page, then DPL anchor-links will go to the FIRST tag on the page.

=Release Version= Must-haves before publishing this extension:
 * Resolve  issue, so that we can eliminate static tag pages.
 * Resolve one high-risk, high-impact issue.

Benefits

 * Centralized editing of all tag-descriptions.
 * Eliminate the 'clutter' of per-tag pages.
 * Eliminating hard-coding is a programming best-practice.


 * Eliminating hard-coded tag-pages may allow us to eliminate the Page_Forms and Labeled Section Transclusion dependencies.
 * Code re-use is simply a programming best-practice. It means improvements can be made in one place, and everything that uses it gets the improved version.

Progress
We're partway there. Template:Tag and page Tag help. Through the use of parameters, these two pages serve all named-tags. They generate:
 * Related-page lists
 * HTML for tagged host pages
 * Display of tag description

Blockers
To eliminate hard-coded tag-pages, 1 issue must be solved:
 * Data-storage: No way yet implemented to store tag descriptions in a single table or page. But some likely options found, below.

Storing Descriptions
The only current purpose for tag-pages is to store tag-descriptions. To eliminate individual tag pages, we must find a way to store all tag-descriptions in a db table or a single wikipage. It must be easy to add new ones and edit existing ones.

How to save a list of tag-descriptions in a single table or wiki-page? Some possible and rejected solutions:

Likely Solutions

 * No descriptions: A simple solution would be to eliminate tag-descriptions. That would get us closer to eliminating individual tag-pages. For a first release, i'm fine with that. (However, in long-run, descriptions seem an essential feature for Topic-Tags.)
 * Extension:Page_Forms/Defining_forms: Page_Forms can add/edit sections in a page. Current most promising solution.
 * Nice feature: Can be used to add new description, or edit existing one. Page_Forms creates a new section if doesn't already exist, or will edit the existing section.
 * This solution would require that Form pages can receive wikitext or url paramaters, as we would need to pass the tagname into the form. That will enable form to create a section for a specific, arbitrary tagname.
 * Want to embed the form in Template:Tag.
 * Don't want to redirect user to full tag-descriptions list after submitting. Ideally, want to stay on Template:Tag page. Or, get redirected back to Template:Tag after description is saved.
 * Want to avoid user having to click "Save" after submitting the form.
 * MediaWiki Url API: Promising solution. No direct db-access (i believe), but could store tag descriptions as sections on a wikipage. A section-name would be the tag-name, and the section content would be the tag's description.
 * Can use Edit action to append a new record.
 * To retrieve a single description by tag-name, must retrieve the page section-content by section-title:
 * Extension:Labeled_Section_Transclusion, which we're currently using to get descriptions from static tag-pages.
 * Can't use API easily to retrieve tag-description, because Parse action can only retrieve a section by number, not name.
 * Curators can edit the list directly to revise/remove tags.

Unlikely Solutions

 * Extension:Cargo: Rejected: Cargo is not appropriate for arbitrarily storing individual records in a list. Can only store the entire list at once.
 * Extension:Semantic_MediaWiki: Avoided, because so large. Also, like Cargo, may be page-centric. On the other hand, Semantic might be able to replace more than one of our current dependencies, so worth investigating.
 * Extension:ExternalData: Could be used to retrieve descriptions, but does not seem to offer a way to store individual records in a table or list. SemantcWiki is suggested
 * Extension:DataTable2: Unknown if feasible, but seems unlikely. Entire table has to be saved together, so adding a single record requires re-saving the entire list. More importantly, can't easily append a single record to end of list, because the table requires a non-data closing tag.
 * https://www.mediawiki.org/wiki/Topic:Udh53bn9qmovy1xd
 * https://www.mediawiki.org/wiki/Topic:Ud1kiswqh0cc1zsy
 * Custom PHP. Most powerful solution, of course, but most time-consuming and labor-intensive to develop, and loses our "php-free" goal. Essentially, php for database access would make sense as a separate, general purpose data-storage extension, separate from TopicTags.
 * Extension:WikiLexicalData

Solve
Solve all high-risk, high-impact issues.

Reduce dependencies

 * That would simplify installation and reduce footprint. But might not be possible, without writing some custom PHP.
 * Maybe we can bundle the dependencies into one installer.
 * Personal opinion: i believe everything this extension does should be doable without any extensions. I feel all behaviors are things that should be part of the MW core-- this extension isn't really doing anything groundbreaking. It all seems very consistent with core MW features. But there are holes in MediaWiki core.
 * Extension:UrlGetParameters: Could be eliminated if MW supported page-parameters. But, feature rejected: https://phabricator.wikimedia.org/T194571

=Known Issues= "Risk" as used here means "likelihood of occurring."

"Impact" as used here means "how bad is it, if it happens."

Top-priority should be given to items which are both high-risk and high-impact.

(Priority shall not be based on whether or not someone volunteered to work on it. In software dev, that's an invalid definition of "Priority".)

Caching causes delays in updating related pages list displayed in transcludes.
Risk: high

Impact: high

As with some other extensions (eg Extension:CategoryTree), caching can muck things up. Still haven't found a solution for this. This only affects the related-pages list displayed on page-level tags, on the tagged page. Does not affect the list displayed in Template:Tag. Possible solutions:
 * Added __NOCACHE__ to all extension templates. That seems to have improved things somewhat. Extension:MagicNoCache
 * Hmm-- how to prevent a transclusion from getting cached, even while the page that hosts it does get cached?
 * Or-- how to force a transclusion to refresh on page-load?
 * Or-- does MediaWiki support partial-page caching?
 * Or partial-page refreshes?
 * Find wikitext or extension to purge page by name or ID. Then, in Template:Tag, put wikitext to purge all related pages.
 * Problem: May purge every time new page is displayed, not just when tagged.

I believe some extensions (maybe even core) do some ajaxy stuff. If MW can't do this, it should :)

Inline tags break if included in an unrelated DPL
Risk: low

Impact: high

If some unrelated page contains a DPL list, which in-turn includes text which contains a topic-tag, when clicked that topic-tag will not correctly link to Template:Tag.

(need to confirm, might be working now)

=Future Enhancements=

Stats
Would be cool to display usage stats, click stats, and other info about the tag on the Tag page.

Region-tagging
'''IMPLEMENTED. MUST UPDATE THIS DOC.'''

Enables editor to apply a topic-tag to a  region  of text.

What this fixes
Currently, a pin-point article-location gets tagged-- not a group of words. *Pin-point article-location addressing is better for extensions which insert text at a location in-between other words

With TopicTags, the editor really means a region of text. Problem is, the reader doesn't know which region of text is being tagged.

IMO, both addressable regions and pin-points should be considered core MW concept. Where Semantic Wiki datafies at the page-level, i'm proposing datafication at the level of text and character-position.

WikiText
Nested tags would be allowed, same as HTML. Something like: <Cars ></Cars>It was a roadster. <Pie ></Pie>There were three pies in the trunk. <Cake ></Cake>The purple roadster had cakes in it's trunk.

Implementation: Template:Span
Instead of Template:Pin, tagging will use Template:Span. Like, and  will render HTML on the host-page.

Rendered HTML
Current plan is: span around the tagged-text. HTML-ID for anchor, HTML-Class for hover-CSS, CSS for highlight on hover. On hover any inline-tagname, all regions of same tagname will light up.

MediaWiki:TopicTags.css
/* :not(:hover) prevents hover action on child element https://stackoverflow.com/a/14792594/209942 */ .tag-label:hover > .tag-region:not(:hover) { background-color:#ffe999; /* to make background fill full line-height. May fail with certain font-sizes or fonts */ padding-top:.3em; padding-bottom:.3em; }

Rendered HTML
Cake It is recommended that, when starting out with cakes, drink brandy. nested... There was an apple pie, a blueberry pie, and an onion pie. The blueberry pie had whipped-cream. The pies were melting in the trunk of the car. Fortunately, there was no banana pie.

Datafication
Depending on how the wikipage is stored in the db, it might be possible to easily query tagged regions throughout the entire wiki, to dynamically render snippets of all text from all pages with same tag-name.

=PHP-Free Experiment= This project is an exploration into the feasibility of php-free extensions, which could be created by non-php programmers, using only wikitext.

Tentatively called "PHP-Free Extensions". A shorter name would be preferrable. Maybe "miniExt", "freelette", "pluglette", etc.

To facilitate non-programmer publishing of php-free extensions, there could be a generic installer, which registers the extension and creates needed pages.. Creation of extension pages could be automated with an API Import action.

Or, even better, the extension pages could themselves transclude model-pages from an external server, enabling extension developers to instantly roll-out improvements to any wiki which uses this extension.

Topic:Ucx3870iubclp1i7