Manual:Modeling pages

Historically, the cocepts of pages, titles, and links have not been modeled clearly in MediaWiki. Several efforts have been made to improve and clarify the modeling, but these efforts are incomplete as of MW 1.41 (July 2023). This page provides an overview of the classes and interfaces that can be used to represent pages, titles, and links in MediaWiki.

The Title class has historically be used to represent both pages on the local wiki, and any kind of target a link may reference. For this reason, calling code cannot be sure what operations are well defined on a given Title object without performing additional checks or imposing additional assumptions and requirements. Titles may represent:


 * A regular editabel wiki page on the local wiki, existing or non-existing.
 * A link to a section on an editable page. Methods intended for use on editable pages have undefined/misleading behavior.
 * A special page on the local wiki. Methods intended for use on editable pages have undefined/misleading behavior.
 * An interwiki (or inter-language) link. Methods intended for use on editable pages have undefined/misleading behavior.
 * A relative subpage link. Methods operating pn the page title and namespace may have undefined/misleading behavior.
 * A relative section jump on the current page. Methods intended for use on editable pages have undefined/misleading behavior.
 * An invalid link target. Most methods have undefined/misleading behavior.

The WikiPage class has historically be used for interacting with the content of editable wiki pages. It used to contain the logic for updating the page table, which has mostly been extracted into other classes like PageStore and PageUpdater.

For this reason, the use of the Title and WikiPage classes have been discouraged since MW 1.36 (2021). Several narrow interfaces have been extracted for the use cases described above:


 * The LinkTarget interface (since MW 1.27) can represent anything a wiki-link can refer to. It is implemented by the TitleValue class.
 * The PageReference interface (since MW 1.37) represents a viewable page, like a wiki page or a special page. It is a WikiAwareEntity, so it may belong to the local wiki or another wiki that can be accessed directly on the database level. It is implemented by the PageReferenceValue class.
 * The PageIdentity interface (since MW 1.36) represents an editable wiki page which may or may not exist. It PageIdentity extends the PageReference interface, and is thus also a WikiAwareEntity. It is implemented by the PageIdentityValue class which extends PageReferenceValue.
 * The PageRecord interface (since MW 1.36) represents an existing editable wiki page, and provides access to the page's meta data.It extends the PageIdentity interface, and is thus also a PageReference and a WikiAwareEntity. It is implemented by the PageRecordValue class which extends PageIdentityValue.

In order to retain backwards compatibility, the Title implement the LinkTarget and PageReference interfaces. Similarly, WikiPage implements PageRecord. However, the intended semantics of these interfaces doesn't hold for all possible instances of Title and WikiPage:


 * Not all Title objects represent editable wiki pages, so not all PageIdentity objects are actually editable wiki pages. The ProperPageIdentity was introduced to allow code to require the guarantee that a PageIdentity is actually an editable wiki page. PageIdentityValue implements ProperPageIdentity, and instances can be optained from Title::toPageIdentity. Once the Title class has been removed, ProperPageIdentity will become an alias for PageIdentity, which will then be guaranteed to represent an editable wiki page.
 * Not all WikiPage objects represent existing wiki pages, so not all PageRecord objects are actually existing wiki pages. The ExistingPageRecord was introduced to allow code to require the guarantee that a Pagerecord is actually an existing wiki page. PageRecordValue implements ExistingPageIdentity, and instances can be optained from WikiPage::toPagerecord. Once the WikiPage class has been removed, ExistingPageRecord will become an alias for PageRecord, which will then be guaranteed to represent an existing wiki page.

TBD: why LinkTarget and PageReference are incompatible. And why we use union types for now.