The Yii framework was designed to be easily extendable. Additional features can be added to your project and then reused, either by yourself on other projects or by sharing your work as a formal Yii extension.
To be consistent with core Yii conventions, your extensions ought to adhere to certain coding styles:
- Use the core framework code style.
- Document classes, methods and properties using phpdoc. - Extension classes should not be prefixed. Do not use the format
TbNavBar
,EMyWidget
, etc.
Note that you can use Markdown within your code for documentation purposes. With Markdown, you can link to properties and methods using the following syntax:
[[name()]]
,[[namespace\MyClass::name()]]
.
Yii 2 relies upon namespaces to organize code. (Namespace support was added to PHP in version 5.3.) If you want to use namespaces within your extension,
- Do not use
yiisoft
anywhere in your namespaces. - Do not use
\yii
,\yii2
or\yiisoft
as root namespaces. - Namespaces should use the syntax
vendorName\uniqueName
.
Choosing a unique namespace is important to prevent name collisions, and also results in faster autoloading of classes. Examples of unique, consistent namepacing are:
samdark\wiki
samdark\debugger
samdark\googlemap
Beyond the code itself, the entire extension distribution ought to have certain things.
There should be a readme.md
file, written in English. This file should clearly describe what the extension does, its requirements, how to install it,
and to use it. The README should be written using Markdown. If you want to provide translated README files, name them as readme_ru.md
where ru
is your language code (in this case, Russian).
It is a good idea to include some screenshots as part of the documentation, especially if your extension provides a widget.
It is recommended to host your extensions at Github.
Extensions should also be registered at Packagist in order to be installable via Composer.
Choose your extension's package name wisely, as you shouldn't change the package name later on. (Changing the name leads to losing the Composer stats, and makes it impossible for people to install the package by the old name.)
If your extension was made specifically for Yii2 (i.e. cannot be used as a standalone PHP library) it is recommended to name it like the following:
yii2-my-extension-name-type
Where:
yii2-
is a prefix.- The extension name is in all lowercase letters, with words separated by
-
. - The
-type
postfix may bewidget
,behavior
,module
etc.
Some extensions you develop may have their own dependencies, such as relying upon other extensions or third-party libraries. When dependencies exist, you should require them in your extension's composer.json
file. Be certain to also use appropriate version constraints, eg. 1.*
, @stable
for requirements.
Finally, when your extension is released in a stable version, double-check that its requirements do not include dev
packages that do not have a stable
release. In other words, the stable release of your extension should only rely upon stable dependencies.
As you maintain and upgrading your extension,
- Use the rules of semantic versioning.
- Use a consistent format for your repository tags, as they are treated as version strings by composer, eg.
0.2.4
,0.2.5
,0.3.0
,1.0.0
.
Yii2 uses Composer for installation, and extensions for Yii2 should as well. Towards that end,
- Use the type
yii2-extension
incomposer.json
file if your extension is Yii-specific. - Do not use
yii
oryii2
as the Composer vendor name. - Do not use
yiisoft
in the Composer package name or the Composer vendor name.
If your extension classes reside directly in the repository root directory, you can use the PSR-4 autoloader in the following way in your composer.json
file:
{
"name": "myname/mywidget",
"description": "My widget is a cool widget that does everything",
"keywords": ["yii", "extension", "widget", "cool"],
"homepage": "https://github.com/myname/yii2-mywidget-widget",
"type": "yii2-extension",
"license": "BSD-3-Clause",
"authors": [
{
"name": "John Doe",
"email": "[email protected]"
}
],
"require": {
"yiisoft/yii2": "*"
},
"autoload": {
"psr-4": {
"myname\\mywidget\\": ""
}
}
}
In the above, myname/mywidget
is the package name that will be registered
at Packagist. It is common for the package name to match your Github repository name.
In the above, the psr-4
autoloader is specified, mapping the myname\mywidget
namespace to the root directory where the classes reside.
More details on this syntax can be found in the Composer documentation.
Extensions sometimes have to use their own database tables. In such situations,
- If the extension creates or modifies the database schema, always use Yii migrations instead of SQL files or custom scripts.
- Migrations should be applicable to as many data storages as possible.
- Do not use Active Record models in your migrations.
- Register assets through bundles.
TBD
- If extension outputs messages intended for end user these should be wrapped into
Yii::t()
in order to be translatable. - Exceptions and other developer-oriented message should not be translated.
- Consider proving
config.php
foryii message
command to simplify translation.
- Consider adding unit tests for PHPUnit.