Commit 9c4d4715 by Qiang Xue

guide WIP [skip ci]

parent 8f7c4672
......@@ -317,7 +317,7 @@ as early as possible. The followings are the recommended practices:
* If you are the developer of an application, you can register dependencies in your
application's [entry script](structure-entry-scripts.md) or in a script that is included by the entry script.
* If you are the developer of a redistributable [extension](structure-extensions.md), you can register dependencies
in the bootstrap class of the extension.
in the bootstrapping class of the extension.
Summary <a name="summary"></a>
......
......@@ -117,46 +117,6 @@ Also, the `psr-4` autoloader is specified in the above, which maps the `myname\m
More details on this syntax can be found in the [Composer documentation](http://getcomposer.org/doc/04-schema.md#autoload).
### Bootstrap with extension
Sometimes, you may want your extension to execute some code during the bootstrap stage of an application.
For example, your extension may want to respond to the application's `beginRequest` event. You can ask the extension user
to explicitly attach your event handler in the extension to the application's event. A better way, however, is to
do all these automatically.
To achieve this goal, you can create a bootstrap class by implementing [[yii\base\BootstrapInterface]].
```php
namespace myname\mywidget;
use yii\base\BootstrapInterface;
use yii\base\Application;
class MyBootstrapClass implements BootstrapInterface
{
public function bootstrap($app)
{
$app->on(Application::EVENT_BEFORE_REQUEST, function () {
// do something here
});
}
}
```
You then list this bootstrap class in `composer.json` as follows,
```json
{
"extra": {
"bootstrap": "myname\\mywidget\\MyBootstrapClass"
}
}
```
When the extension is installed in an application, Yii will automatically hook up the bootstrap class
and call its `bootstrap()` while initializing the application for every request.
Working with database
---------------------
......
......@@ -136,7 +136,7 @@ implements [[yii\base\BootstrapInterface]], its [[yii\base\BootstrapInterface::b
will be also be called.
Another practical example is in the application configuration for the [Basic Application Template](start-installation.md),
where the `debug` and `gii` modules are configured as bootstrap components when the application is running
where the `debug` and `gii` modules are configured as bootstrapping components when the application is running
in development environment,
```php
......@@ -151,7 +151,7 @@ if (YII_ENV_DEV) {
```
> Note: Putting too many components in `bootstrap` will degrade the performance of your application because
for each request, the same set of components need to be run. So use bootstrap components judiciously.
for each request, the same set of components need to be run. So use bootstrapping components judiciously.
#### [[yii\web\Application::catchAll|catchAll]] <a name="catchAll"></a>
......@@ -412,7 +412,7 @@ In the special case when you want to maintain extensions manually, you may confi
As you can see, the property takes an array of extension specifications. Each extension is specified with an array
consisting of `name` and `version` elements. If an extension needs to run during the [bootstrap](runtime-bootstrapping.md)
process, a `bootstrap` element may be specified with a bootstrap class name or a [configuration](concept-configurations.md)
process, a `bootstrap` element may be specified with a bootstrapping class name or a [configuration](concept-configurations.md)
array. An extension may also define a few [aliases](concept-aliases.md).
......@@ -581,7 +581,7 @@ an application will undergo the following lifecycle:
* Register the [[yii\base\Application::errorHandler|error handler]].
* Configure application properties.
* [[yii\base\Application::init()|init()]] is called which further calls
[[yii\base\Application::bootstrap()|bootstrap()]] to run bootstrap components.
[[yii\base\Application::bootstrap()|bootstrap()]] to run bootstrapping components.
3. The entry script calls [[yii\base\Application::run()]] to run the application:
* Trigger the [[yii\base\Application::EVENT_BEFORE_REQUEST|EVENT_BEFORE_REQUEST]] event.
* Handle the request: resolve the request into a [route](runtime-routing.md) and the associated parameters;
......
Extensions
==========
> Note: This section is under development.
Extensions are redistributable software packages specifically designed to be used in Yii applications and provide
ready-to-use features. For example, the [yiisoft/yii2-debug](tool-debugger.md) extension adds a handy debug toolbar
at the bottom of every page in your application to help you more easily grasp how the pages are generated. You can
......@@ -10,13 +8,13 @@ use extensions to accelerate your development process. You can also package your
other people your great work.
> Info: We use the term "extension" to refer to Yii-specific software packages. For general purpose software packages
that can be used without Yii, we will refer to them using the term "package".
that can be used without Yii, we will refer to them using the term "package" or "library".
## Using Extensions
To use an extension, you need to install it first. Most extensions are distributed as [Composer](https://getcomposer.org/)
packages, and you can take the following two simple steps to install such an extension:
packages which can be installed by taking the following two simple steps:
1. modify the `composer.json` file of your application and specify which extensions (Composer packages) you want to install.
2. run `php composer.phar install` to install the specified extensions.
......@@ -24,12 +22,12 @@ packages, and you can take the following two simple steps to install such an ext
You may need to install [Composer](https://getcomposer.org/) if you do not have it. Composer is a dependency
manager. This means when installing a package, it will install all its dependent packages automatically.
> Info: By default, Composer installs packages registered on [Packagist](https://packagist.org/) - the biggest repository
for open source Composer packages. You may also [create your own repository](https://getcomposer.org/doc/05-repositories.md#repository)
and configure Composer to use it. This is useful if you are developing closed open extensions and want to share
within your projects.
By default, Composer installs packages registered on [Packagist](https://packagist.org/) - the biggest repository
for open source Composer packages. You can look for extensions on Packagist. You may also
[create your own repository](https://getcomposer.org/doc/05-repositories.md#repository) and configure Composer
to use it. This is useful if you are developing closed open extensions and want to share within your projects.
Extensions installed by Composer are stored under the `BasePath/vendor` directory, where `BasePath` refers to the
Extensions installed by Composer are stored in the `BasePath/vendor` directory, where `BasePath` refers to the
application's [base path](structure-applications.md#basePath).
For example, to install the `yiisoft/yii2-imagine` extension, modify your `composer.json` like the following:
......@@ -65,69 +63,175 @@ Image::thumbnail('@webroot/img/test-image.jpg', 120, 120)
->save(Yii::getAlias('@runtime/thumb-test-image.jpg'), ['quality' => 50]);
```
> Info: Extension classes are autoloaded using the [Yii class autoloader](concept-autoloading.md). Yii automatically
creates [aliases](concept-aliases.md#extension-aliases) for the root namespaces declared by the extensions.
Also make sure in the [application configuration](structure-applications.md#application-configurations), you have
configured `extension
> Info: Extension classes are autoloaded by the [Yii class autoloader](concept-autoloading.md).
## Creating Extensions
An extension can contain any code you like, such as a helper class, a widget, a module, etc.
You may consider creating an extension when you feel the need to redistribute some of your great code so that
they can be easily reused by other people or in your other projects.
An extension can contain any code you like, such as a helper class, a widget, a module, etc.
It is recommended that you create an extension in terms of a [Composer package](https://getcomposer.org/) so that
it can be more easily installed and used by other users, liked described in the last subsection.
### Basic Steps
Below are the basic steps you may follow to create an extension.
It is recommended that you create an extension in terms of a Composer package so that it can be more easily
used elsewhere, liked described in the last subsection. Below are the steps you may follow to create an extension.
1. Put all the files you plan to include in the extension in a single directory. The directory should contain
no other irrelevant files. For simplicity, let's call this directory the extension's *root directory*.
2. Create a `composer.json` file directly under the root directory. The file is required by Composer, which describes
the metadata about your extension. Please refer to the [Composer Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup)
for more details about the file format.
3. Create a VCS (version control system) repository to host the extension files. Any future development
and maintenance work about the extension should be done on this repository.
4. Register your extension with a Composer repository so that other users can find and install your extension.
1. Create a project for your extension and host it on a VCS repository, such as [github.com](https://github.com).
Development and maintenance work about the extension should be done on this repository.
2. Under the root directory of the project, create a file named `composer.json` as required by Composer. Please
refer to the next subsection for more details.
3. Register your extension with a Composer repository so that other users can find and install your extension.
If you are creating an open source extension, you can register it with [Packagist](https://packagist.org/);
If you are creating a private extension for internal use, you may register it with
[your own repository](https://getcomposer.org/doc/05-repositories.md#hosting-your-own).
As an example, you may refer to the [yiisoft/yii2-bootstrap](widget-bootstrap) extension which provides a set of
widgets encapsulating the Twitter Bootstrap plugins. The extension is hosted on [GitHub](https://github.com/yiisoft/yii2-bootstrap)
and registered with [Packagist](https://packagist.org/packages/yiisoft/yii2-bootstrap). Below is the content
of its `composer.json` file (some unimportant content is removed for simplicity):
### `composer.json`
Each Composer package must have a `composer.json` file in its root directory. The file contains the metadata about
the package. You may find complete specification about this file in the [Composer Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup).
You may also refer to the following example which is the `composer.json` file for the `yiisoft/yii2-imagine` extension:
```json
{
"name": "yiisoft/yii2-bootstrap",
"description": "The Twitter Bootstrap extension for the Yii framework",
"keywords": ["yii2", "bootstrap"],
// package name
"name": "yiisoft/yii2-imagine",
// package type
"type": "yii2-extension",
"description": "The Imagine integration for the Yii framework",
"keywords": ["yii2", "imagine", "image", "helper"],
"license": "BSD-3-Clause",
"support": {
"issues": "https://github.com/yiisoft/yii2/issues?labels=ext%3Aimagine",
"forum": "http://www.yiiframework.com/forum/",
"wiki": "http://www.yiiframework.com/wiki/",
"irc": "irc://irc.freenode.net/yii",
"source": "https://github.com/yiisoft/yii2"
},
"authors": [
{
"name": "Antonio Ramirez",
"email": "amigo.cobos@gmail.com"
}
],
// package dependencies
"require": {
"yiisoft/yii2": "*",
"twbs/bootstrap": "3.1.* | 3.0.*"
"imagine/imagine": "v0.5.0"
},
// class autoloading specs
"autoload": {
"psr-4": {
"yii\\imagine\\": ""
}
}
}
```
> Info: It is important that you specify the package type as `yii2-extension` so that the package can
be recognized as a Yii extension when being installed.
### Package Names
Each extension, when released as a Composer package, should have a package name which uniquely identifies itself
among all other packages. The format of package names is `vendorName/projectName`. For example, in the package name
`yiisoft/yii2-imagine`, the vendor name and the project name are `yiisoft` and `yii2-imagine`, respectively.
Do NOT use `yiisoft` as vendor name as this is reserved for use by the Yii core code.
Also, to easily tell from package name whether a package is a Yii extension, we recommend you prefix `yii2-`
to the project name.
### Namespaces
To avoid name collisions and make the classes in your extension autoloadable, you should use namespaces and
name the classes in your extension by following the [PSR-4 standard](http://www.php-fig.org/psr/psr-4/) or
[PSR-0 standard](http://www.php-fig.org/psr/psr-0/).
You class namespaces should start with `vendorName\extensionName`, where `extensionName` is similar to the project name
in the package name except that it should not contain the `yii2-` prefix. For example, for the `yiisoft/yii2-imagine`
extension, we use `yii\imagine` as the namespace its classes.
Do not use `yii`, `yii2` or `yiisoft` as vendor name. These names are reserved for use by the Yii core code.
### Class Autoloading
In order for your classes to be autoloaded by the Yii class autoloader or the Composer class autoloader,
you should specify the `autoload` entry in the `composer.json` file, like shown below:
```json
{
// ....
"autoload": {
"psr-4": {
"yii\\bootstrap\\": ""
"yii\\imagine\\": ""
}
}
}
```
You may list one or multiple root namespaces and their corresponding file paths.
When the extension is installed in an application, Yii will create an [alias](concept-aliases.md#extension-aliases)
for each listed root namespace. The alias will refer to the directory corresponding to the root namespace.
For example, the above `autoload` declaration will correspond to an alias named `@yii/imagine`.
### Bootstrapping Classes
Sometimes, you may want your extension to execute some code during the [bootstrapping process](runtime-bootstrapping.md)
stage of an application. For example, your extension may want to respond to the application's `beginRequest` event
to adjust some environment settings. While you can instruct users of the extension to explicitly attach your event
handler in the extension to the `beginRequest` event, a better way is to do this automatically.
### Yii2 Extensions
To achieve this goal, you can create a so-called *bootstrapping class* by implementing [[yii\base\BootstrapInterface]].
For example,
When creating a Composer package, you may specify the package type to be `yii2-extension`, like shown in the example
in the last subsection. This is recommended if your package is an extension that is specifically designed to be
used in Yii applications. By using `yii2-extension` as the package type, your package can get the following extra benefits:
```php
namespace myname\mywidget;
use yii\base\BootstrapInterface;
use yii\base\Application;
class MyBootstrapClass implements BootstrapInterface
{
public function bootstrap($app)
{
$app->on(Application::EVENT_BEFORE_REQUEST, function () {
// do something here
});
}
}
```
You then list this class in the `composer.json` file of your extension like follows,
```json
{
// ...
"extra": {
"bootstrap": "myname\\mywidget\\MyBootstrapClass"
}
}
```
For example, if your package contains a Yii [widget](structure-widgets.md), it is most likely
that the package
When the extension is installed in an application, Yii will automatically instantiate the bootstrapping class
and call its [[yii\base\BootstrapInterface::bootstrap()|bootstrap()]] during the bootstrapping process for
every request.
## Installing Extensions Manually
......
......@@ -171,7 +171,7 @@ public function behaviors()
Response formats and languages often need to be determined much earlier during
the [application lifecycle](structure-applications.md#application-lifecycle). For this reason, ContentNegotiator
is designed in a way such that it can also be used as a [bootstrap component](structure-applications.md#bootstrap)
is designed in a way such that it can also be used as a [bootstrapping component](structure-applications.md#bootstrap)
besides filter. For example, you may configure it in the [application configuration](structure-applications.md#application-configurations)
like the following:
......
......@@ -21,7 +21,7 @@ like the following:
}
```
You may specify a bootstrap class in the `extra` section. The `init()` method of the class will be executed each time
You may specify a bootstrapping class in the `extra` section. The `init()` method of the class will be executed each time
the Yii 2 application is responding to a request. For example,
```json
......
......@@ -298,7 +298,7 @@ abstract class Application extends Module
} elseif ($this->hasModule($class)) {
$component = $this->getModule($class);
} elseif (strpos($class, '\\') === false) {
throw new InvalidConfigException("Unknown bootstrap component ID: $class");
throw new InvalidConfigException("Unknown bootstrapping component ID: $class");
}
}
if (!isset($component)) {
......
......@@ -12,10 +12,10 @@ namespace yii\base;
*
* The main method [[bootstrap()]] will be invoked by an application at the beginning of its `init()` method.
*
* Bootstrap classes can be registered in two approaches.
* Bootstrapping classes can be registered in two approaches.
*
* The first approach is mainly used by extensions and is managed by the Composer installation process.
* You mainly need to list the bootstrap class of your extension in the `composer.json` file like following,
* You mainly need to list the bootstrapping class of your extension in the `composer.json` file like following,
*
* ```json
* {
......@@ -45,7 +45,7 @@ namespace yii\base;
* ];
* ```
*
* As you can see, you can register a bootstrap class in terms of either a class name or a configuration class.
* As you can see, you can register a bootstrapping class in terms of either a class name or a configuration class.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
......
......@@ -27,9 +27,9 @@ use yii\web\UnsupportedMediaTypeHttpException;
* language negotiation based on the value of the GET parameter [[languageParam]] and the `Accept-Language` HTTP header.
* If a match is found, the [[\yii\base\Application::language]] property will be set as the chosen language.
*
* You may use ContentNegotiator as a bootstrap component as well as an action filter.
* You may use ContentNegotiator as a bootstrapping component as well as an action filter.
*
* The following code shows how you can use ContentNegotiator as a bootstrap component. Note that in this case,
* The following code shows how you can use ContentNegotiator as a bootstrapping component. Note that in this case,
* the content negotiation applies to the whole application.
*
* ```php
......
......@@ -73,7 +73,7 @@ class ErrorHandler extends \yii\base\ErrorHandler
$response = new Response();
}
$useErrorView = $response->format === \yii\web\Response::FORMAT_HTML && (!YII_DEBUG || $exception instanceof UserException);
$useErrorView = $response->format === Response::FORMAT_HTML && (!YII_DEBUG || $exception instanceof UserException);
if ($useErrorView && $this->errorAction !== null) {
$result = Yii::$app->runAction($this->errorAction);
......@@ -82,7 +82,7 @@ class ErrorHandler extends \yii\base\ErrorHandler
} else {
$response->data = $result;
}
} elseif ($response->format === \yii\web\Response::FORMAT_HTML) {
} elseif ($response->format === Response::FORMAT_HTML) {
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest' || YII_ENV_TEST) {
// AJAX request
$response->data = '<pre>' . $this->htmlEncode($this->convertExceptionToString($exception)) . '</pre>';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment