Главная · Ошибки · Apache. Создание алиасов и редиректов

Apache. Создание алиасов и редиректов

Типичная ситуация: HTTP-клиент запрашивает с сервера контент, который либо не существует на данном сервере, либо располагается по другому URL. Причин такому стечению обстоятельств может быть несколько. Вы, например, могли переместить контент в пределах сервера (а то и вообще за его пределы) или же вам понадобилось реорганизовать логическую структуру адресов вашего проекта. При обычных условиях запрос несуществующего контента приведёт к тому, что сервер сообщит об ошибке, однако в Apache имеется полезный модуль mod_alias , предоставляющий возможность создавать синонимы URL (aliasing — алиасинг ), а также выполнять перенаправление клиентов на другой URL (redirect — редирект ).

Псевдонимы (алиасы) позволяют серверу преобразовывать один URL в другой, таким образом перенаправляя клиентов на нужный контент, при этом без физической операции перенаправления: для клиента подобная операция совершенно прозрачна. Это очень полезная возможность, если, например, вы задумали очеловечить URL-адреса страниц вашего проекта с целью SEO-оптимизации или ещё зачем-то.

При помощи алиасов вы также можете организовать доступ к файлам, находящимся за пределами Document Root сервера, таким образом предоставив прямой доступ к любой части ФС сервера, не прибегая к использованию CGI-сценариев. Используя редирект, вы получаете возможность физически перенаправлять клиентов на нужные URL.

Директива Alias

Директива Alias позволяет незаметно для клиентов связывать запрашиваемые URL с любой частью файловой системы сервера. Например:

Директива в примере выше приведёт к тому, что Apache перед тем, как выполнять поиск контента в файловой системе, в строке запроса заменит /images/ на /ftp/public/images/ . Таким образом запрос URL http://www.example-domain.com/images/example-image.jpg заставит искать Apache файл example-image.jpg в физическом каталоге /ftp/public/images/ вместо каталога DOCUMENT_ROOT/images .

Обратите внимание на то, что завершающий слеш имеет значение. Приведённый выше пример не сработал бы, если б мы опустили завершающий слеш в первом параметре Alias . Также, алиасинг не сработал бы в случае, если бы клиент запросил URL, в котором после /images отсутствовал завершающий слеш.

Директива AliasMatch

Директива AliasMatch работает так же, как и Alias, при этом позволяя использовать регулярные выражения для определения исходных URL:

AliasMatch /images/(.*)$ /ftp/public/images/$1

В этом примере показано, как мы можете легко связать относительную часть запрашиваемого URL с частью физической файловой системы. Переменная $1 связана с первым соответствием, обнаруженным в скобках регулярного выражения, $2 — со вторым, и так далее. Таким образом, в примере выше, запрос URL http://www.example-site.com/some_dir/images/img1.jpg приведёт к получению файла /ftp/public/images/img1.jpg . Используя эту директиву вы можете, например, хранить все изображения в одном дереве каталогов, независимо от относительного положения подстроки /images/ в строке запроса.

Существенной разницей между Alias и AliasMatch является их поведение. Разница заключается в том, что Alias копирует оставшуюся часть строки запроса после вычитания из неё первого параметра директивы, в то время как AliasMatch — нет. То есть:

Alias /images/ /ftp/public/images/

совершенно не эквивалентна

AliasMatch /images/ /ftp/public/images/

поскольку вторая будет транслировать все запросы, содержащие подстроку /images/ к каталогу /ftp/public/images/ , не добавляя при перезаписи имён файлов. Чтобы получить то, что нужно, вам понадобится следующая инструкция:

AliasMatch ^/images/(.*)$ /ftp/public/images/$1

Директива ScriptAlias

Назначение этой директивы такое же, как и Alias , однако при этом Apache считает конечный каталог таким, который хранит исполняемые CGI-сценарии. То есть после трансляции запроса и определения конечного пути запрашиваемого файла, Apache попытается выполнить последний, как CGI-сценарий.

ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/

В приведённом примере запрос http://www.example-site.com/cgi-bin/some_cgi_script приведёт к выполнению сценария, расположенного в файле /usr/local/apache2/cgi-bin/some_cgi_script . Альтернативный вариант такой конфигурации можно можно описать следующим набором инструкций:

Alias /cgi-bin/ /usr/local/apache2/cgi-bin/ SetHandler cgi-script Options +ExecCGI

Директива ScriptAliasMatch

Данная директива аналогична предыдущей, однако умеет работать с регулярными выражениями, как и AliasMatch .

Директива Redirect

mod_alias ко всему прочему позволяет явно сообщать клиентам о том, что запрошенный ими URL является некорректным, сообщая другой URL, по которому можно отыскать требуемый контент. Для управления такими перенаправлениями используется директива Redirect .

Эта директива работает подобно Alias , только вместо того, чтобы выполнять перенаправление внутри сервера, она отправляет команду перенаправления клиенту. Опциональным параметром директивы является тип перенаправления, сообщаемый клиенту кодом HTTP-статуса ответа (об этом чуть ниже).

Redirect permanent /images http://www.another-example-site.com/images

В приведённом примере запрос URL http://www.example-site.com/images/img1.gif приведёт к перенапрвлению на http://www.another-example-site.com/images/img1.gif .

Если запрашиваемый URL содержит query string , то она будет оставлена без изменений, только если это явно не определно последним параметром директивы Redirect .

Например, правило, рассмотренное выше, запрос URL http://www.example-site.com/images?img-name=1.gif перенаправит к http://www.another-example-site.com/images?img-name=1.gif . Однако, если мы перепишем правило следующим образом:

Redirect permanent /images http://www.another-example-site.com/images?q=new-value

то тот же запрос будет перенаправлен на http://www.another-example-site.com/images?q=new-value .

Теперь о типах перенаправления. Для того, чтобы сообщить клиенту о необходимости перенаправления на другой URL, сервер использует HTTP статус-коды . При помощи директивы Redirect можно определить один из четырёх HTTP-кодов перенаправления (в скобках указано символическое имя, которое можно использовать вместо номера кода).

301 (permanent) . Ресурс переехал на новый адрес. Клиенты и прокси-серверы должны обновить информацию в своих кешах (только если HTTP-заголовки Cache-Control и Expires не препятствуют этому) и в будущем всегда использовать новый адрес ресурса.

302 (temp) . Адрес ресурса временно изменён. Клиенты и прокси-серверы НЕ должны обновлять информацию в своём кеше и в будущем всегда проверять предыдущий адрес ресурса, прежде чем выполнять перенаправление (только если HTTP-заголовки Cache-Control и Expires не препятствуют этому).

303 (seeother) . Ресурс был замещён другим ресурсом и клиент должен выполнить перенаправление, используя метод GET, независимо от того, какой метод использовался для запроса оригинального ресурса.

410 (gone) . Ресурс был удалён и более недоступен.

Если статус-аргумент будет опущен, то по умолчанию будет использоваться 302-редирект. На самом деле вы можете использовать любой HTTP-статус, а не только четыре из представленных выше. Помните только, что если вы используете HTTP-статус, не попадающий в диапазон 300-399, последний аргумент директивы должен быть опущен.

Директива RedirectMatch

Эта директива, как уже все догадались, работает подобно предыдущей, но позволяет пользоваться регулярными выражениями при определении условий, предоставляя больше гибкости в настройке поведения редиректа. Ради примера давайте рассмотрим следующее правило:

RedirectMatch (.*)\.gif$ http://www.example-site.com$1.gif

Здесь все запросы адресов, оканчивающихся.gif , будут перенаправлены в корень другого сервера.

Так же, как и предыдущая директва, RedirectMatch принимает опциональный параметр HTTP статус-кода. В примере выше он не указан, и поэтому будет использоваться код 302.

Также, в семействе Redirect* есть ещё две директивы: RedirectPermanent и RedirectTemp , которые семантически эквиваленты выражениям Redirect permanent и Redirect temp соответственно.

Порядок обработки директив

Если вы не хотите получить неожиданного поведения сервера при работе с редиректом и алиасингом, вы должны знать о том, что инструкции редиректа обрабатываются перед инструкциями алиасинга , если они были одновременно обнаружены в одном и том же контексте (например в пределах оного и того же контейнера или ).

Когда сервер получает запрос, подходящий под условие Redirect или RedirectMatch , то инструкции этих директив будут обработаны прежде, чем инструкции директив Alias и AliasMatch . Это означает то, что в подобных ситуациях директивы Alias* никогда не будут срабатывать, поскольку будет выпоняться редирект.

Второй момент, о котором всегда всегда помнить, это то, что директивы Alias* и Redirect* применяются в том порядке, в котором они появляются . По этой причине зачастую более разумно определять более общие правила в последнюю очередь. Например инструкции:

Alias /sub-dir1/sub-dir2 /dir3 Alias /sub-dir1 /dir4

НЕ будут работать так же, как и:

Alias /sub-dir1 /dir4 Alias /sub-dir1/sub-dir2 /dir3

поскольку Alias /sub-dir1 /dir4 будет срабатывать всегда до того, как дойдёт очередь до Alias /sub-dir1/sub-dir2 /dir3 .

Обычно URL path(URL путь) и File path(Путь в файловой системе относительно виртуального сервера) идентичны. Например, www.example.com/images/foo.gif означает(обычно), что файл находится в /home/example/www/images/foo.gif.

Однако, это может быть изменено благодаря тому, что в Apache называется алиасами(ссылками, псевдонимами). То есть алиас позволяет сослаться в другое место, отличное от физического пути. Например, Обращаясь к /images как из прошлого примера, может быть пользователю отдано содержимое каталога /var/www/images.

Алиасы бывают глобальные или привязанные к конкретному виртуальному серверу.

Для создания алиаса проделайте следующие шаги:

1. На главной странице модуля, выберите виртуальный сервер для которого вы хотите создать алиас. Или, если это будет глобальный алиас выберите Default Server(Сервер по умолчанию).

3. Заполните пустую строку в таблице Document directory aliases(Таблица алиасов). В поле From(От) введите URL путь, и реальный путь в поле To(Куда). Если вы редактируете алиасы сервера по умолчанию, то там уже будет несколько стандартных алиасов.

Существующие алиасы могут быть отредактированы, стандартным для Webmin способом - просто измените его в таблице алиасов и нажмите Save(Сохранить). Если вам нужно удалить, то просто очистите оба поля таблицы соответствующего алиаса.

Алиасы могут быть определены с помощью Perl- регулярных выражений. Но в таком случае они должны быть внесены в таблицу Regexp document directory aliases(Regexp таблица алиасов). Смысл тот же, что и у обычной таблицы алиасов, с тем отличием, что в поле From(От) вы можете ввести что-нибудь вроде ^/images/(.*)\.gif$. А в поле To(Куда) что-нибудь вроде /images/$1.jpg. Этот алиас будет перенаправлять пользователя запросившего GIF картинку, на картинку JPG с тем же именем от GIF, что запросил пользователь.

Редиректы в чем-то очень похожи на алиасы, но служат другой цели. Когда пользователь запросил определенный URL, на который настроен редирект, Apache перенаправит клиента на другой URL или даже на другой сервер. Например, вы можете сделать так, чтобы при обращении к www.example.com/webmin/ пользователя перенаправляло на www.webmin.com . Однако в отличие от алиасов, запрос к /webmin/foo.gif не перенаправит пользователя на www.webmin.com/foo.gif , он все также откроет только www.webmin.com .

Редиректы распознаются браузерами благодаря тому, что веб-сервер посылает специальны код - 302 и сообщает URL новый адрес.

Для настройки редиректа проделайте следующие шаги:

1. На главной странице модуля, выберите виртуальный сервер для которого вы хотите создать редирект. Или, если это будет глобальный редирект выберите Default Server(Сервер по умолчанию).

2. На странице настроек виртуального сервера нажмите на иконку Aliases and Redirects(Алиасы и Редиректы).

3. Заполните пустую строку в таблице URL redirects(Таблица редиректов). В поле From(От) введите URL путь, например /webmin, и URL путь куда перенаправить клиента в поле поле To(Куда), например www.webmin.com. Поле Status(Код статуса) необязательный параметр. Он необходим если вы хотите изменить HTTP код статуса, который будет отдаваться веб-сервером вместо кода по умолчанию(302). Вы можете изменить его на 301 или 303, в зависимости от того, что вам нужно.

Чтобы добавить более одного редиректа вам нужно переоткрыть страницу.

Редиректы могут быть определены с помощью Perl- регулярных выражений. Но в таком случае они должны быть внесены в таблицу Regexp URL redirects(Regexp таблица редиректов). Смысл тот же, что и у обычной таблицы редиректов, с тем отличием, что в поле From(От) вы можете ввести что-нибудь вроде ^/webmin/(.*)$. А в поле To(Куда) что-нибудь вроде http://www.webmin.com/$1. Этот редирект будет перенаправлять пользователя запросившего страницу от /webmin на такую же страницу(с тем же именем) на сайте www.webmin.com.

Если Apache скомпилирован с поддержкой прокси модуля, то вы можете использовать его в качестве прокси-сервера. Это позволит вам организовать в сети как бы один большой веб-сайт в котором - целый Интернет. Ваши пользователи будут обращаться к вашему веб-серверу, а он будет перенаправлять запросы во внешний мир. Да, Apache как прокси-сервер не так гибок как Squid, но может вам и не нужна та гибкость.

Это будет в некотором смысле редирект, но без редиректа как такового. Поэтому существуют еще таблицы Map locale to remote URLs(Маппинг локальных URL к удаленным URL) и Map remote Location: headers to local(Обратный маппинг), которые также размещены на странице Aliases and Redirects(Алиасы и Редиректы).

Для настройки URL маппинга проделайте следующие шаги:

1. На главной странице модуля, выберите виртуальный сервер для которого вы хотите создать маппинг. Или, если это будет глобальный маппинг выберите Default Server(Сервер по умолчанию).

2. На странице настроек виртуального сервера нажмите на иконку Aliases and Redirects(Алиасы и Редиректы).

3. Заполните пустую строку в таблице Map locale to remote URLs(Маппинг локальных URL к удаленным URL). Введите URL путь на вашем веб-сервере(например, /webmin) в первое поле и полный URL куда перенаправлять запросы во второе поле(например, http://www.webmin.com).

4. Заполните пустую строку в таблице Map remote Location: headers to local(Обратный маппинг). Введите полный URL путь на удаленном веб-сервере(например, http://www.webmin.com) в первое поле и URL путь на вашем веб-сервере(например, /webmin) куда перенаправлять запросы во второе поле(например, http://www.webmin.com). Обратный маппинг должен быть обязательно настроен. Иначе ответы не будут доходит до клиентов.

При настройках маппинга, помните, что проксирование это не основная функция веб-сервера. Некоторые функции могут работать не так, как вы думаете, как вы привыкли.

Для того чтобы создать псевдоним (алиас) пути используется метод Yii::setAlias() :

// псевдоним пути к папке Yii::setAlias("@myalias", "/path/to/myfolder");
// псевдоним пути к папке на основе другого псевдонима Yii::setAlias("@img", "@myalias/path/to/img");
// псевдоним URL Yii::setAlias("@mysite", "http://mysite.com");

Псевдонимы путей в yii2 можно задать в файле конфигураций приложения с помощью свойства aliases , пример:

Return [ // ... "aliases" => [ "@myalias" => "/path/to/myfolder", "@mysite" => "http://mysite.com" ], ];

Как получить псевдоним (алиас) пути в Yii 2

Для того чтобы получить псевдоним пути в yii2 используеться метод Yii::getAlias() :

Echo Yii::getAlias("@myalias"); // вернет: /path/to/myfolder echo Yii::getAlias("@mysite"); // вернет: http://mysite.com echo Yii::getAlias("@myalias/other/folder/index.php"); // вернет: /path/to/myfolder/other/folder/index.php

Дополнительно о псевдонимах путей в Yii 2

Имя псевдонима

Имя псевдонима может содержать /, при этом метод Yii::getAlias() определит какая часть является именем псевдонима, а какая добавочным путем, например:

Yii::setAlias("@test", "/path/to/test"); Yii::setAlias("@test/val", "/path/to/val"); Yii::getAlias("@test/folder/index.php"); // вернет: /path/to/test/folder/index.php Yii::getAlias("@test/val/index.php"); // вернет: /path/to/val/index.php

Если бы в строке 2 небыл определен алиас @test/val , то строка 4 вернула бы /path/to/test/val/index.php

Псевдонимы расширений

При установке расширения с помощью composer, для него автоматически задается псевдоним (путь к корневой директории расширения). Например при установке imperavi redactor (vova07/yii2-imperavi-widget), вам будет доступен псевдоним пути @vova07/imperavi (@vendor/vova07/yii2-imperavi-widget/src)

Псевдонимы (алиасы) путей в Yii 2 basic приложении

Список основных, заранее заданных псевдонимов (алиасов) путей в yii2 basic:

  • @web: Базовый URL приложения
  • @webroot: Webroot приложения

Псевдонимы (алиасы) путей в Yii 2 advanced приложении

Список основных, заранее заданных псевдонимов (алиасов) путей в yii2 advanced:

  • @app: Корневой каталог приложения
  • @vendor: Папка vendor, под @app
  • @runtime: Путь к временным файлам приложения runtime/cache
  • @web: Базовый URL приложения
  • @webroot: Каталог с тестами приложения
  • @tests: Каталог с тестами приложения
  • @common: Псевдоним (алиас) для common (общей) директории под @app
  • @frontend: Псевдоним (алиас) для frontend директории, под @app
  • @backend: Псевдоним (алиас) для backend директории, под @app
  • @console: Псевдоним (алиас) для console директории, под @app

(PHP 5 >= 5.3.0)

The ability to refer to an external fully qualified name with an alias, or importing, is an important feature of namespaces. This is similar to the ability of unix-based filesystems to create symbolic links to a file or to a directory.

PHP namespaces support three kinds of aliasing or importing: aliasing a class name, aliasing an interface name, and aliasing a namespace name. Note that importing a function or constant is not supported.

In PHP, aliasing is accomplished with the use operator. Here is an example showing all 3 kinds of importing:

Example #1 importing/aliasing with the use operator

namespace foo ;
use My \ Full \ Classname as Another ;

// this is the same as use My\Full\NSname as NSname
use My \ Full \ NSname ;

// importing a global class
use ArrayObject ;

$obj = new namespace\ Another ; // instantiates object of class foo\Another
$obj = new Another ; NSname \ subns \ func (); $a = new ArrayObject (array(1 )); // instantiates object of class ArrayObject
// without the "use ArrayObject" we would instantiate an object of class foo\ArrayObject
?>

Note that for namespaced names (fully qualified namespace names containing namespace separator, such as Foo\Bar as opposed to global names that do not, such as FooBar ), the leading backslash is unnecessary and not recommended, as import names must be fully qualified, and are not processed relative to the current namespace.

PHP additionally supports a convenience shortcut to place multiple use statements on the same line

Example #2 importing/aliasing with the use operator, multiple use statements combined

$obj = new Another ; // instantiates object of class My\Full\Classname
NSname \ subns \ func (); // calls function My\Full\NSname\subns\func
?>

Importing is performed at compile-time, and so does not affect dynamic class, function or constant names.

Example #3 Importing and dynamic names

use My \ Full \ Classname as Another , My \ Full \ NSname ;

$obj = new Another ; // instantiates object of class My\Full\Classname
$a = "Another" ;
$obj = new $a ; ?>

In addition, importing only affects unqualified and qualified names. Fully qualified names are absolute, and unaffected by imports.

Example #4 Importing and fully qualified names

use My \ Full \ Classname as Another , My \ Full \ NSname ;

$obj = new Another ; // instantiates object of class My\Full\Classname
$obj = new \ Another ; // instantiates object of class Another
$obj = new Another \ thing ; // instantiates object of class My\Full\Classname\thing
$obj = new \ Another \ thing ; // instantiates object of class Another\thing
?>

Scoping rules for importing

The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations. This is because the importing is done at compile time and not runtime, so it cannot be block scoped. The following example will show an illegal use of the use keyword:

Example #5 Illegal importing rule

namespace Languages ;

class Greenlandic
{
use Languages \ Danish ;

...
}
?>

Importing rules are per file basis, meaning included files will NOT inherit the parent file"s importing rules.

Вы помещаете конфигурационные данные в файл extension.json или skin.json в корневой директории вашего расширения или темы оформления, и MediaWiki использует его, что бы зарегистрировать расширение или тему оформления.

До MediaWiki 1.25, конфигурация для расширений и тем оформления находилась в PHP файле с именем расширения или темы оформления, например MyExtension.php или MySkin.php .

require_once " $IP /extensions/Hello/Hello.php" ; require_once " $IP /extensions/FooBar/FooBar.php" ; $wgFooBarEnable = true ; require_once " $IP /skins/Baz/Baz.php" ;

Сейчас можно преобразовать в:

wfLoadExtensions ( array ( "Hello" , "FooBar" ) ); $wgFooBarEnable = true ; wfLoadSkin ( "Baz" );

Если вы храните расширение не в $IP/extensions , вам нужно переопределить $wgExtensionDirectory . Если вы храните стиль оформления не в $IP/skins , вам нужно переопределить плохо названную $wgStyleDirectory . Это должно быть сделано до того, как вы загрузите расширение или стиль оформления.

$wgExtensionDirectory = "/some/path" ; wfLoadExtension ( "FooBar" ); // Looks for /some/path/FooBar/extension.json $wgStyleDirectory = "/my/skins" ; wfLoadSkins ( array ( "BarBaz" , "BazBar" ) ); // Looks for /my/skins/BarBaz/skin.json and /my/skins/BazBar/skin.json

Since MW 1.30, namespace IDs defined in extension.json can be overwritten locally, by defining the respective constant in LocalSettings.php before loading the extension. Consider for instance the following namespace declaration in a extension.json file:

"namespaces" : [ { "id" : 1212 , "constant" : "NS_FOO" , "name" : "Foo" }, { "id" : 1213 , "constant" : "NS_FOO_TALK" , "name" : "Foo_Talk" } ]

This would per default cause the constant NS_FOO to be defined to have the value 1212. However, this can be overwritten by defining the respective constant in LocalSettings.php:

define ( "NS_FOO" , 6688 ); define ( "NS_FOO_TALK" , 6689 ); wfLoadExtension ( "Foo" );

This would cause the "Foo" namespace to be registered with the ID 6688 instead of 1212. When overriding namespace IDs, don"t forget that all talk namespaces must have odd IDs, and the ID of the talk namespace must always be the subject namespace"s ID plus one.

Contents

Миграция для разработчиков расширений

See also the extension registration wall of sadness (now superpowers) .

Скрипт maintenance/convertExtensionToRegistration.php поможет вам мигрировать с PHP точек входа(?) на файл метеданных JSON. Если ваше расширение поддерживает старые версии MediaWiki, вы должны оставить вашу точку входа FooBar/FooBar .php пока не перестанете поддерживать старые версии.

Пример запуска команды:

$ cd core $ php maintenance/convertExtensionToRegistration.php extensions/MassMessage/MassMessage.php $ php maintenance/convertExtensionToRegistration.php skins/MonoBook/MonoBook.php --skin

Возможно вам надо деинсталлировать ваше расширение из LocalSettings.php , если вы получаете ошибки о том, что константы или функции не могут быть переопределены.

Вы должны заменить вашу PHP точку входа (файл FooBar.php) на что-то наподобие следующего, что бы не сломать wiki в процессе апгрейда.

"Deprecated PHP entry point used for the FooBar extension. " . "Please use wfLoadExtension instead, " "This version of the FooBar extension requires MediaWiki 1.29+" ); }

Или стили:

// Keep i18n globals so mergeMessageFileList.php doesn"t break $wgMessagesDirs [ "FooBar" ] = __DIR__ . "/i18n" ; $wgExtensionMessagesFiles [ "FooBarAlias" ] = __DIR__ . "/FooBar.alias.php" ; wfWarn ( "Deprecated PHP entry point used for the FooBar skin. Please use wfLoadSkin instead, " . "see https://www.." ); return ; } else { die ( "This version of the FooBar skin requires MediaWiki 1.25+" ); }

Вспомогательная документация

PHP точки входа обычно имеют документацию настроек конфигурации, которая полезна и не должна потеряться. К сожалению JSON не поддерживает комментариев. Рекомендуется переместить документацию конфигурации в файл README репозитория расширения. Вы также должны задокументировать конфигурацию в вики на странице вашего расширения Extension:MyExtension . Возможно также добавить некоторую документацию напрямую в extension.json . Регистрация расширения игнорирует любые ключи в extension.json , начинающиеся с " @ " в корне структуры или под config , так что вы можете поместить комментарии в этих местах. Например:

{ "@note" : "This file must be kept in sync with LocalisationUpdate.php" , "@name" : ...

Version 1 of the extension.json format also allowed @note in config section, but this is no longer recommended or supported in version 2. description field of the config variable should be used instead.

Это должно использоваться только для кратких пометок и комментариев.

Возможности

Если вы загружаете большое количество расширений, регистрация расширений может быть ускорена, если у вас установлен APC (или APCu). Расширения, которые загружаются вместе с wfLoadExtensions (с множественными -s) будут кэшироваться вместе.

Атрибуты

Повторяющаяся проблема - как "зарегистрировать" что-то с другим расширением. Обычно это означает, что вы хотите загрузить одно расширение перед другим. Например VisualEditor имеет $wgVisualEditorPluginModules , который позволяет расширениям загружать их модули. Тем не менее в точке входа VisualEditor"а имеется:

$wgVisualEditorPluginModules = array ();

Это означает, что если расширение добавляется в массив до VisualEditor"а, VE сотрет эту запись в массиве. Некоторые расширения зависели от определенного порядка загрузки, другие взламывали это при помощи $wgExtensionFunctions . Регистрация расширений решает эту проблему при помощи "атрибутов". В расширении Math его extension.json имеет что-то следующее

{ "VisualEditorPluginModules" : [ "ext.math.visualEditor" ] }

Starting with manifest version 2, the attributes need to be defined in the separate section section attributes .

The attributes node needs to be an object with the extension name as key and an object of attribute/value pairs as the value. Be aware that the key in the subobject must not contain the extension name!

{ "attributes" : { "VisualEditor" : { "PluginModules" : [ "ext.math.visualEditor" ] } }, "manifest_version" : 2 }

Когда VisualEditor хочет получить доступ к атрибуту, он использует:

ExtensionRegistry :: getInstance () -> getAttribute ( "VisualEditorPluginModules" );

Требования (зависимости)

Extension registration has a requires section, which acts similar to Composer "s require section. It allows an extension developer to specify several requirements for the extension, such as a specific MediaWiki version (or greater/less than) or another extension/skin. For example, to add a dependency on a MediaWiki version that is greater than 1.26.0, you can add the following code to extension.json:

{ "requires" : { "MediaWiki" : ">= 1.26.0" } }

The key of the requires object is the name of the dependency (prior to MediaWiki 1.29.0 only MediaWiki was supported), the value is a valid version constraint (the format has to match the one used by composer).

In MediaWiki 1.29.0 and above you can also add dependencies on skins and other extensions like so:

{ "requires" : { "MediaWiki" : ">= 1.25.0" , "extensions" : { "FakeExtension" : "*" }, "skins" : { "FakeSkin" : "*" } } }

Check, if an extension is loaded without actually requiring it

Many extensions may provide features that work only if another extension is loaded too, without really needing this feature for the core extension function to work. As an example: If extension B is loaded, extension A can provide a real WYSIWYG editor, otherwise it will use a simple textarea. Extension A can profit from extension B (if it is loaded), but doesn"t require it to be loaded to work properly. For this, you generally check, if the extension is loaded, rather than adding it as a hard dependency.

To implement a standardized way of checking, if an extension is loaded or not (without the need of extra work in an extension that is a soft-dependency in another one), extension registration can be used. It implements an isLoaded method, which returns a simple boolean, if the extension is loaded or not (the extension needs to be loaded with extension registration for this to work). Example:

if ( ExtensionRegistry :: getInstance () -> isLoaded ( "ExtensionB" ) ) { }

Since MediaWiki 1.32 it"s also possible to check if an extension is loaded and satisfies a given composer version constraint:

if ( ExtensionRegistry :: getInstance () -> isLoaded ( "ExtensionB" , ">=1.2" ) ) { // do things only, if extension B is loaded and has a version of 1.2 or greater. }

If you would like to check if a specific version of an extension is loaded in earlier versions of MediaWiki, information like that can be extracted with the getAllThings method, which returns credit information for all loaded extensions. Example:

$bVersion = ExtensionRegistry :: getInstance () -> getAllThings ()[ "ExtensionB" ][ "version" ] ?? null ; if ( $bVersion !== null && version_compare ( $bVersion , "2.1.0" , ">=" ) ) { // do things only, if extension B is loaded and has a version number greater than or equal to 2.1.0 if ( defined ( "ExtensionBVersion" ) ) { // You could also check for a version, if the constant holds the version // do things only, if extension B is loaded }

A more brittle way, that should be avoided is to check if a specific class of extension B exists or not, e.g. using this code:

if ( class_exists ( "ExtensionBHooks" ) ) { // do things only, if extension B its classes exist }

This might break if the extension exists in the file system but is not loaded, e.g. if composer was used for autoloading. If the class was renamed or ceases to exist (e.g. because it is not package public) this will also break.

In general it is preferred to share code via composer components instead of extensions. If the classes of an extension only need to exist, but the extension does not need to be configured nor loaded, for what you want to do, that is a strong indicator that that code should be split off into a composer component you should depend on instead.

Конфиги (настройки вашего расширения/стиля)

By default, extension.json assumes that your config settings start with a "wg" prefix.

If that"s not the case, you can override the prefix by using a special key:

{ "config" : { "_prefix" : "eg" , "MyExtSetting" : true } }

That would use a prefix of "eg", and set the global variable $egMyExtSetting to true.

Starting with manifest version 2, the configuration section of extension registration provides a lot more features and allows you to describe your configuration options much more detailed. Instead of having a single key -> value store for your configuration options, you can also add the following information.

The general structure of the config changes slightly to the following, more object-oriented version:

{ "config_prefix" : "eg" , "config" : { "MyExtSetting" : { "value" : true , "path" : false , "description" : "The description for the configuration" , "descriptionmsg" : "myextension-config-myextsetting" , "public" : true } }, "manifest_version" : 2 }

Value

The value of the configuration moved to this place. This is the only required key for a configuration object.

Path

The boolean value of the path key identifies, if the value of the configuration option should be interpreted as a filesystem path, relative to the extension directory root. E.g., if the value of the configuration is myFile.png and the path is true, the actual value will be /path/to/the/wiki/extensions/MyExtension/myFile.png .

Description

The description key for a configuration option can hold a non-localized string, which can be used to explain the configuration option to other developers or the users (system administrators) of your extension. The value of the description key is usually not exposed to the frontend of the wiki, however, take a look to the outlook for more information how this feature could be used in the future!

There"s also the possibility to add a message key of MediaWiki"s internal localisation system as a description (descriptionmsg), which, in the future, will be used to expose the description in the frontend of the MediaWiki installation.

public / private

This option is a boolean, which defaults to false, which means, that the configuration option and the value is marked as "private". This value is not used anywhere at the moment, take a look to the outlook to find out more about this option.