Skip to content

ccxtwf/VocaloidLyricsWikiInterfaceCode

Repository files navigation

About

Inspired by Miraheze Dev Scripts and MoegirlPediaInterfaceCodes, this is a repository that aims to enable development of wiki userscripts and styles on Vocaloid Lyrics Wiki.

One main goal of this repository is to facilitate faster & easier feature development, from the development stage on an IDE to debugging on a MediaWiki instance.

License

The code & configuration for setting up the Vite environment (i.e. everything excluding code listed in the src/ directory) is hereby licensed under the BSD 3-Clause License.

Code listed in the src/ directory consists of userscripts and stylesheets that are used on the Vocaloid Lyrics Wiki and are licensed under the Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA 4.0) license.

How to use

Installation

Use Node.js 20.19+ or 22.12+ (Node.js v24 is recommended).

Run npm install in the directory to install the npm packages.

Basic Configuration

Create your own .env file by following the format shown on .env.example.

# Can also be replaced with your own Git repo
GIT_REPOSITORY_URL=https://github.com/ccxtwf/VocaloidLyricsWikiInterfaceCode
# The autogenerated banner on each file of the build output will point to this Git branch
GIT_REPOSITORY_BRANCH=main

# The api.php path of the MediaWiki instance to sync with
WIKI_API_URL=https://vocaloidlyrics.miraheze.org/w/api.php
# These are set using Special:BotPassword
BOT_USERNAME=<username>@<botname>
BOT_PASSWORD=pass
# Set this to authenticate using OAuth
BOT_OAUTH_ACCESS_TOKEN=
# Custom user agent to send with your HTTP requests
BOT_USERAGENT=your user agent

If testing on a local wiki without an SSL certificate, then set the following environment variable:

# Do not reject requests made over insecure HTTP
ENV_REJECT_UNAUTHORIZED=0

Do not do this on a production environment.

Setting up multiple .env files for multiple wiki instances

If using this repository to deploy changes to multiple wikis, e.g. to a production live wiki and to a locally hosted development/mirror wiki, then you can also set up multiple .env files, e.g. .env.dev and .env.prod.

Note that only one .env file will be loaded at a time. To control which .env file will be loaded during development/deployment, you can set the variable NODE_PROJECT_PROFILE in your shell. Alternatively, you can run the utility script:

# Load .env.prod
. set-profile.sh prod

# Load .env
. set-profile.sh

Development

This repository allows you to write your MediaWiki userscripts in TypeScript and LESS, in addition to standard JS and CSS.

Running npm run watch will start up Vite in Build Mode. Vite will not terminate after the build process is finished. Instead, Vite will watch for any changes made to the code, rebuilding each time it detects such changes.

While npm run watch is running, run npm run preview on another process to get Vite to serve your userscripts on localhost. When your scripts are ready, Vite will automatically open the page http://localhost:4173/load.js on your web browser. This is the entrypoint from which you can run your userscripts on your MediaWiki instance. To use this load.js file, add the following line of code in your User:<Username>/common.js on your local (non-prod) MediaWiki instance:

mw.loader.load('http://localhost:4173/load.js');

You can check if your gadgets have been loaded onto MediaWiki instance by running console.log(mw.loader.getState("ext.gadget.<Name of gadget>")); on the Developer Console.

Once set up, you will only need to reload the webpage on your MediaWiki instance to instantly see the changes made on your code in the IDE, no extra steps required.

Unit Tests - Jest

To run unit tests (Jest), execute:

npm run tests

Build & deploy

Running npm run build will start up Vite in Build mode and terminate after build is finished. Files are saved onto the dist/ folder after the build process is finished.

To sync the latest state of the project with the code running on the wiki, run npm run sync. This will start a bot run (powered by Mwn), with edit logs saved onto the folder logs/ on the project directory.

Note: Make sure that the account whose credentials you're using has either been assigned the interface-admin user group, or the user rights editsitecss and editsitejs. When first creating your bot password/OAuth token, make sure that the options "Edit the MediaWiki namespace and sitewide/user JSON" and "Edit sitewide and user CSS/JS" were checked.

Transpiling of userscripts written in Typescript into Javascript is configured in vite.config.ts (build options). This repository targets Javascript ES2018.

Deploying to multiple wikis

See the section on setting up multiple .env files for multiple wiki instances.

Code Definition

Interface Code

The source code to the wiki's interface code (i.e. MediaWiki:Common.css, MediaWiki:Common.js, MediaWiki:Vector-2022.css, etc.) is stored in src/mediawiki.

Gadgets

The source code to the wiki's gadgets is stored in src/gadgets. The directory is further divided into several gadget sections.

The file src/gadgets/gadgets-definition.yaml defines the gadgets to be built & loaded on a MediaWiki instance. The format of src/gadgets/gadgets-definition.yaml is as follows:

workspace:
  # Set as true if you want to load all the gadgets defined in gadgets-definition.yaml
  enable_all: true
  # This setting excludes the following gadgets from being loaded when enable_all = true
  disable: ["section/foo", "section/bar"]

  # Alternatively, these options enable only the specified gadgets
  # enable_all: false
  # enable: ["section/foo", "section/bar"]

gadgets:
  # This informs the name of the gadget section under which the gadget will be registered 
  # in MediaWiki:Gadgets-definition, as well as the name of the subdirectory of the gadget. 
  GadgetSectionName:

    # This tells the repository to look for code files from the directory 
    # /gadgets/GadgetSectionName/HelloWorld
    # The name that the gadget will be registered under is also the same as the subdirectory 
    HelloWorld:
      description: "A simple gadget configuration"
      code:
        # The filename of each code file corresponds to the page title of the MediaWiki interface code
        # For example, the contents of hello-world.js will be synced with the page 
        # MediaWiki:Gadget-hello-world.js when npm run sync is run
        - hello-world.js    # .ts files are also supported
        - hello-world.css   # LESS files are also supported
  
    # gadgets-definition.yaml also enables userscripts to be loaded conditionally, like userscripts 
    # that are defined using Extension:Gadgets
    LoadMeConditionally:
      description: "A gadget that is loaded only on Main article pages, on action=view"
      code:
        - load-me.js
      resourceLoader:
        actions:
          - view
        namespaces: "0"

The full schema of a gadget object on gadgets-definition.yaml is as follows:

gadgets:
  # The name of the gadget section and the key of the gadget object is the
  # same as the name of the gadget, which is also the same as the gadget 
  # subdirectory.
  # In other words, the repository will look for code files in the folder
  # gadgets/GadgetSectionName/GadgetName
  GadgetSectionName:
    GadgetName:     # Can also be in camelCase, kebab-case, or snake_case
      
      # The following are optional metadata properties
      description: "Some description"
      authors:
        - John Doe
      links: 
        - https://some/link/to/the/userscripts/homepage
      version: "1.0.0"

      # The "requires" property is optional
      # This property tells the repository to load the gadgets only after 
      # the userscripts listed under it have been registered first
      # Only applicable when loading the scripts from load.js
      requires:
        - Dependency1
        - Dependency2

      # The files to be loaded
      code:
        # It is important to set unique names for each of the code files, since the name of each 
        # code file corresponds to the page title of the MediaWiki interface code
        # For example, the contents of dist/GadgetSectionName/GadgetName/some-filename.js will be 
        # saved to MediaWiki:Gadget-some-filename.js
        - some-filename.ts      # .ts files are resolved to .js files in the build output
        - some-filename.less    # .less files are resolved to .css files in the build output
      i18n:
        - i18n.json

      # You can disable the gadget using this property
      # disabled: true
    
      # This property sets the conditions that must be met to load & register the module
      # Used to write MediaWiki:Gadgets-definition on the live wiki
      resourceLoader:
        # Optional property. 
        # Setting this to true will load the gadget as a default gadget to all users.
        default:

        # Optional property.
        # Setting this to true will hide the gadget from Special:Preferences.
        hidden:

        # Optional parameter. Set to "styles" for CSS stylesheets, or 
        # "general" for scripts
        type:

        # For each of the properties below, you can add them in one of the following ways:
        # In list form:
        #   dependencies:
        #    - ooui-js
        #    - mediawiki.util
        # In array form:
        #   dependencies: ["ooui-js", "mediawiki.util"]
        # Or in string form:
        #   dependencies: "ooui-js,mediawiki.util"

        # Loads the modules listed under it before loading the gadget.
        # Under the hood, this implements mw.loader.using
        dependencies:

        # Only users with the specified user rights may load the gadget.
        rights:

        # Only load the gadget on specific skins
        skins:

        # Only load the gadget on specific page actions, e.g. action=edit
        actions:

        # Only load the gadget on specified categories, e.g. "Archived"
        categories:

        # Only load the gadget on specified namespaces, e.g. "0,1" -> Main & Talk
        namespaces:

        # Only load the gadget on specific content models, e.g. wikitext
        contentModels:

Advanced

Additional Environment Configuration

# By default gadgets loaded using load.js will be loaded under the module namespace ext.gadget
# You can avoid module naming conflicts in MediaWiki by setting this to a different namespace, 
# e.g. ext.gadget.store
GADGET_NAMESPACE=ext.gadget.store

# Change this if setting Vite to serve your code bundle through a different port / a custom domain.
SERVER_PREVIEW_ORIGIN=http://localhost:4173

All Commands

Command Description
npm run build Builds a code bundle from source code written in the src/ directory.
  • Code is not minified.
  • Disabled gadgets are skipped.
npm run watch Like npm run build, but a rebuild is initiated when a change to the source code is detected.
npm run rollup Builds a minified code bundle from source code written in the src/ directory and creates a gadget-impl.js file for each gadget. This gadget-impl.js comprises the rolled-up gadget implementation that can be run on any live wiki either by loading the code through a CDN or by running the code on your browser.
  • Unlike npm run build, the build output is minified.
  • Disabled gadgets are skipped.
npm run preview Starts up a server to serve the built code bundles over localhost (and/or a local network).
npm run build-show Builds the code bundle and immediately starts up a server. Synonymous to running npm run build and then npm run preview.
npm run tests Execute Jest unit tests.
npm run sync Syncs the interface code written in the wiki with the latest built bundle.

Run npm run sync -- --update-all to force the script to update all pages.

About

MediaWiki Interface Code & Gadgets for the Vocaloid Lyrics Wiki

Resources

License

Stars

Watchers

Forks

Contributors