Jump to content

Codex

From mediawiki.org
This page is a translated version of the page Codex and the translation is 100% complete.



Codexはウィキメディアのためのデザインシステムです。 As a system, Codex is made up of several distinct elements which may be used separately or together. These elements include: design tokens, icons, and UI components. Codex is bundled within MediaWiki, and is also available as a series of NPM packages.

The current version of Codex is 1.18.0

Codex's source code is hosted on Gerrit, and its development is tracked in Phabricator. Read the full changelog.

Basic usage

Codex provides a variety of components which skin, extension, and userscript authors can embed in their own user interfaces: buttons, checkboxes, toggle switches, dialogs, etc. Many of these components can be extensively customized.

A full list of current Codex components (along with documentation and interactive demos) can be found here.

CodexExample MediaWiki extension

The Design System Team maintains the CodexExample MediaWiki extension for demonstration purposes. This extension can be installed (it sets up a dedicated special page called `Special:CodexExample` with live demos) or you can study its source code for inspiration. See the project README page for more information.

Usage with JavaScript

Codex components are built using the Vue.js JavaScript framework. If you are developing a Vue application in MediaWiki, then it's easy to load Codex components from ResourceLoader using require(). You can load all of Codex at once, or just a limited subset of components.

Loading the entire library (recommended for use in userscripts)

"ext.myExtension.foo": {
	"dependencies": [ "@wikimedia/codex" ]
	"packageFiles": [
		"init.js",
		"MyComponent.vue"
	]
}
<!-- MyComponent.vue -->
<template>
    <cdx-button @click="doSomething">Click me!</cdx-button>
</template>

<script>
const { CdxButton } = require( '@wikimedia/codex' );

module.exports = exports = {
    name: "MyComponent",
    components: {
        CdxButton
    },
    methods: {
        doSomething() {
            //...
        }
    }
}
</script>
Loading a subset of Codex components (recommended for skins and extensions)

To only load a limited set of components, you can declare your dependencies in the following way below:

"ext.myExtension.foo": {
    "class": "MediaWiki\\ResourceLoader\\CodexModule",
	"packageFiles": [
		"init.js",
		"MyComponent.vue"
	],
    "codexComponents": [
        "CdxButton",
        "CdxCard",
        "CdxDialog"
    ]
}

This will generate a virtual file, codex.js, in your resources directory with the exports you need. You can then require the components you requested from that virtual file:

// In resources/ext.myExtension.foo/MyComponent.vue
const { CdxButton, CdxTextInput } = require( '../codex.js' );

See the CodexExample repository for more in-depth example of how to use Codex in a MediaWiki extension.

JavaScriptなしで(CSSのみのCodexコンポーネント)利用

MediaWiki バージョン:
1.42

Many Codex components also support "css-only" usage. These components should appear visually identical to their JS-enabled counterparts, but they will offer more limited behavior.

Loading component styles

You can load the styles of a limited subset of Codex CSS components in the same way as you would for JS components, above. If you only need the styles, you can add the "codexStyleOnly": "true" option when you define your module.

"ext.myExtension.foo": {
	"class": "MediaWiki\\ResourceLoader\\CodexModule",
	"styles": "ext.myExtension.foo/styles.less",
	"codexStyleOnly": "true",
	"codexComponents": [
		"CdxButton",
		"CdxCard",
		"CdxCheckbox",
		"CdxProgressBar"
	]
}
Providing component markup

To use CSS-only Codex components, just ensure that the appropriate styles are loaded and then add the necessary markup to your page. For now, you'll have to do this by hand. You can find example markup in the "CSS-only usage" section on a component's documentation page (here is the markup for the Button component).

<div>
  <button class="cdx-button cdx-button--action-default">Default button</button>
</div>

<div>
  <button class="cdx-button cdx-button--action-progressive">
    Progressive button
  </button>
</div>

<div>
  <button class="cdx-button cdx-button--action-destructive">
    Destructive button
  </button>
</div>

Using Codex in PHP

Codex PHP is still under construction and not yet available for use in MediaWiki core (phab:T379662). Expect breaking changes to be introduced until a stable version is announced.

Codex PHP is a library for building CSS-only UI components using Codex, the Wikimedia design system, please see the Codex PHP documentation.

Installation

Install the Codex PHP library via Composer:

composer require wikimedia/codex

Example Usage

Here’s an example of creating an Accordion component in PHP:

$accordion = $codex
            ->accordion()
            ->setTitle( "Accordion Example" )
            ->setDescription( "This is an example of an accordion." )
            ->setContentHtml(
                $codex
                    ->htmlSnippet()
                    ->setContent( "<p>This is the content of the accordion.</p>" )
                    ->build()
            )
            ->setOpen( false )
            ->setAttributes( [
                "class" => "foo",
                "bar" => "baz",
            ] )
            ->build()
            ->getHtml();

echo $accordion;

Usage in MediaWiki

Below is an example of using Codex components in MediaWiki:

<?php

use MediaWiki\SpecialPage\SpecialPage;
use Wikimedia\Codex\Adapter\WebRequestAdapter;
use Wikimedia\Codex\Utility\Codex;
use Wikimedia\Codex\Utility\WebRequestCallbacks;

class SomeSpecial extends SpecialPage {

    public function __construct() {
        parent::__construct( "SomeSpecial" );
    }

    public function execute( $subPage ) {
        $codex = new Codex();
        $requestAdapter = new WebRequestAdapter( $this->getRequest() );
        $callbacks = new WebRequestCallbacks( $requestAdapter );

        $tab1 = $codex
                ->Tab()
                ->setName( "tab1" )
                ->setLabel( "Tab 1" )
                ->setContentHtml(
                    $codex
                    ->htmlSnippet()
                    ->setContent( "<p>Content 1.</p>" )
                    ->build()
                )
                ->setSelected( true )
                ->build();

        $tabs = $codex
                ->Tabs()
                ->setCallbacks( $callbacks )
                ->setTab( [ $tab1 ] )
                ->build()
                ->getHtml();

        $this->getOutput()->addHTML( $tabs );
    }
}

Advanced usage

Using a limited subset of components

The @wikimedia/codex ResourceLoader module provides the entire Codex library – all components, styles, etc. If you are developing a skin or an extension and you care about performance, you should consider using Codex's code-splitting feature. ResourceLoader allows you to specify a list of Codex components and load only the JS/CSS for those components plus their dependencies.

To use this feature, define a custom ResourceLoader module (this is typically done in skin.json or extension.json) and specify a list of codexComponents:

"ext.myExtension.blockform": {
    "class": "MediaWiki\\ResourceLoader\\CodexModule",
    "codexComponents": [
        "CdxButton",
        "CdxCard",
        "CdxDialog",
        "CdxIcon",
        "CdxRadio",
        "CdxTextInput",
        "useModelWrapper"
    ],
    "packageFiles": [
        "init.js",
        "BlockForm.vue"
    ],
    "messages": [
		"block-target",
		"ipb-submit"
	]
}

This will generate a virtual file, codex.js, in your resources directory with the exports you need. その仮想ファイルから必要なコンポーネントやコンポーザブルを要求できます:

// In resources/ext.myExtension/BlockForm.vue
const { CdxButton, CdxTextInput } = require( '../codex.js' );

If you only need CSS-only components and don't wish to load the component JavaScript, you can add "codexStyleOnly": true to the module definition.

Similarly, if you only need the JavaScript files and not styles, you can add "codexScriptOnly": "true". You should only do this if you're putting the styles in another, style-only module as described above.

Codexのアイコンの利用

パフォーマンス上の理由からCodexの全アイコンが入っているResourceLoaderモジュールcodex-iconsはありません。 このようなモジュールは、多くの利用者が200以上のアイコンのうちの一握りしか使用しないのにもかかわらず、巨大かつ冗長になります。 代わりに、上記のコード分割法と同様に、ResourceLoaderを通してモジュールで必要なアイコンを読み込めるようになります。

{
    "name": "icons.json",
    "callback": "MediaWiki\\ResourceLoader\\CodexModule::getIcons",
    "callbackParam": [
        // モジュールに必要なアイコンをここでリストします:
        "cdxIconArrowNext",
        "cdxIconBold",
        "cdxIconTrash"
    ]
}

直接デザイントークンを利用

Design tokens can be imported into LESS stylesheets as variables. This may be useful if you are developing your own components or styles and want them to integrate with Codex.

Codex design tokens should be imported from the mediawiki.skin.variables.less file.

@import 'mediawiki.skin.variables.less';

.my-feature {
    color: @color-base;
    background-color: @background-color-base;
}

For a full list of Codex's design tokens, broken down by category, see here.

Codex LESS mixin

一部のCodexの機能はLessのmixinを使って実装されています。 例えば、リンクコンポーネントはVueのコンポーネントではなくLessのmixinであり、CSSのみのコンポーネントでアイコンを使用する際はLessのmixinを使用します(下記のCSSのみでコンポーネントを使用するも参照)。

MediaWikiや拡張機能内でのCodexのLess向けmixinはデザイントークンと同様に動作します:'mediawiki.skin.variables.less'をインポートするだけでデザイントークンに加え全てのCodex mixinを利用できます。

@import 'mediawiki.skin.variables.less';

.my-feature {
    a {
        .cdx-mixin-link-base();
    }
}

Using Codex in userscripts

It is possible to use Codex in userscripts. However, there are some limitations that will require certain workarounds. Here are a few considerations to keep in mind when using Vue and Codex in userscripts:

  • No .vue single-file component support; you must define components in plain JS files
  • Everything needs to live in one file; userscripts don't provide a good way to load custom modules
  • Define component templates using ES6 template literals
  • Prefer global component registration for Codex components

Loading Vue/Codex

You'll need to load Vue and Codex from ResourceLoader. The best way to do this is via mw.loader.using; the rest of your userscript code should live in a callback or promise chain.

mw.loader.using( '@wikimedia/codex' ).then( function( require ) {
    const Vue = require( 'vue' );
    const Codex = require( '@wikimedia/codex' );
} );

Use Vue.createMwApp

Once you've loaded Vue and Codex, you must define a Vue app and mount it somewhere on the page. The exact location will vary depending on what you are trying to do. You can use MediaWiki's custom createMwApp method for this.

mw.loader.using( '@wikimedia/codex' ).then( function( require ) {
    //... require Vue and Codex as above
    // create an element to mount the Vue app
    const mountPoint = document.body.appendChild( document.createElement( 'div' ) );
    // create a Vue app and mount it to the target element
    Vue.createMwApp( {
        // data, computed props, methods, etc. go here
    } ).mount( mountPoint );
} );

Real examples

The link below shows a complete example of a userscript which adds a portlet link to all Wiki pages that triggers a custom Codex Dialog component to launch when clicked. Feel free to copy this script to your own user page to use as a starting point.

https://en.wikipedia.org/wiki/User:EGardner_(WMF)/codex-hello-world.js

Here is another script using Codex :

https://en.wikipedia.org/wiki/User:JSherman_(WMF)/revertrisk.js

Release cycle

A new version of Codex is released every other Tuesday. When a new release is created, a patch is also submitted to MediaWiki core to use that new release. Since this is done on Tuesdays, the update to core will be deployed the following week (the next time the deployment train runs).

Using a custom version of Codex for development or testing

MediaWiki uses the latest release of Codex. If you need to use a different version for development or testing purposes, for example to test how an unmerged patch in Codex interacts with MediaWiki, you can point MediaWiki to your own version of Codex as follows:

  1. Clone the Codex repository (if you haven't already), and check out the change you want to test.
  2. Run npm install and npm run build-all in the root directory of the Codex repository.
  3. Point $wgCodexDevelopmentDir to the root directory of the Codex repository. For example, if you cloned the Codex repository in the parent directory of the MediaWiki directory, add $wgCodexDevelopmentDir = MW_INSTALL_PATH . '../codex'; to LocalSettings.php
  4. Test that it works by running mw.loader.load( '@wikimedia/codex' ) in the browser console. This should trigger a warning saying "You are using a local development version of Codex", and should not trigger any errors.

Once you have this set up, you can make additional changes to your Codex clone, but you have to run npm run build-all each time to make those changes take effect in MediaWiki.

To disable development mode and go back to using the latest release of Codex, comment out the line in LocalSettings.php that sets $wgCodexDevelopmentDir.