-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpackages.html
executable file
·318 lines (221 loc) · 17.3 KB
/
packages.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Documentation</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="css/style.css">
<script src="js/vendor/modernizr-2.6.2.min.js"></script>
</head>
<body>
<!--[if lt IE 7]>
<p class="chromeframe">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">activate Google Chrome Frame</a> to improve your experience.</p>
<![endif]-->
<div class="wrapper">
<header>
<h1>Documentation</h1>
</header>
<aside class="sidebar">
<ul>
<li>Preface
<ul>
<li><a href="index.html">Introduction</a></li>
<li><a href="contributing.html">Contributing</a></li>
</ul></li>
<li>Getting Started
<ul>
<li><a href="installation.html">Installation</a></li>
<li><a href="configuration.html">Configuration</a></li>
<li><a href="lifecycle.html">Request Lifecycle</a></li>
<li><a href="routing.html">Routing</a></li>
<li><a href="requests.html">Requests & Input</a></li>
<li><a href="responses.html">Views & Responses</a></li>
<li><a href="controllers.html">Controllers</a></li>
<li><a href="errors.html">Errors & Logging</a></li>
</ul></li>
<li>Learning More
<ul>
<li><a href="cache.html">Cache</a></li>
<li><a href="events.html">Events</a></li>
<li><a href="html.html">Forms & HTML</a></li>
<li><a href="ioc.html">IoC Container</a></li>
<li><a href="localization.html">Localization</a></li>
<li><a href="mail.html">Mail</a></li>
<li><a href="packages.html">Package Development</a></li>
<li><a href="pagination.html">Pagination</a></li>
<li><a href="queues.html">Queues</a></li>
<li><a href="security.html">Security</a></li>
<li><a href="session.html">Session</a></li>
<li><a href="templates.html">Templates</a></li>
<li><a href="testing.html">Unit Testing</a></li>
<li><a href="validation.html">Validation</a></li>
</ul></li>
<li>Database
<ul>
<li><a href="database.html">Basic Usage</a></li>
<li><a href="queries.html">Query Builder</a></li>
<li><a href="eloquent.html">Eloquent ORM</a></li>
<li><a href="schema.html">Schema Builder</a></li>
<li><a href="migrations.html">Migrations & Seeding</a></li>
<li><a href="redis.html">Redis</a></li>
</ul></li>
<li>Artisan CLI
<ul>
<li><a href="artisan.html">Overview</a></li>
<li><a href="commands.html">Development</a></li>
</ul></li>
</ul>
</aside>
<section class="content">
<h1>Package Development</h1>
<ul>
<li><a href="packages.html#introduction">Introduction</a></li>
<li><a href="packages.html#creating-a-package">Creating A Package</a></li>
<li><a href="packages.html#package-structure">Package Structure</a></li>
<li><a href="packages.html#service-providers">Service Providers</a></li>
<li><a href="packages.html#package-conventions">Package Conventions</a></li>
<li><a href="packages.html#development-workflow">Development Workflow</a></li>
<li><a href="packages.html#package-routing">Package Routing</a></li>
<li><a href="packages.html#package-configuration">Package Configuration</a></li>
<li><a href="packages.html#package-migrations">Package Migrations</a></li>
<li><a href="packages.html#package-assets">Package Assets</a></li>
<li><a href="packages.html#publishing-packages">Publishing Packages</a></li>
</ul>
<p><a name="introduction"></a></p>
<h2>Introduction</h2>
<p>Packages are the primary way of adding functionality to Laravel. Packages might be anything from a great way to work with dates like <a href="https://github.com/briannesbitt/Carbon">Carbon</a>, or an entire BDD testing framework like <a href="https://github.com/Behat/Behat">Behat</a>.</p>
<p>Of course, there are different types of packages. Some packages are stand-alone, meaning they work with any framework, not just Laravel. Both Carbon and Behat are examples of stand-alone packages. Any of these packages may be used with Laravel by simply requesting them in your <code>composer.json</code> file.</p>
<p>On the other hand, other packages are specifically intended for use with Laravel. In previous versions of Laravel, these types of packages were called "bundles". These packages may have routes, controllers, views, configuration, and migrations specifically intended to enhance a Laravel application. As no special process is needed to develop stand-alone packages, this guide primarily covers the development of those that are Laravel specific.</p>
<p>All Laravel packages are distributed via <a href="http://packagist.org">Packagist</a> and <a href="http://getcomposer.org">Composer</a>, so learning about these wonderful PHP package distribution tools is essential.</p>
<p><a name="creating-a-package"></a></p>
<h2>Creating A Package</h2>
<p>The easiest way to create a new package for use with Laravel is the <code>workbench</code> Artisan command. First, you will need to set a few options in the <code>app/config/workbench.php</code> file. In that file, you will find a <code>name</code> and <code>email</code> option. These values will be used to generate a <code>composer.json</code> file for your new package. Once you have supplied those values, you are ready to build a workbench package!</p>
<p><strong>Issuing The Workbench Artisan Command</strong></p>
<pre><code>php artisan workbench vendor/package --resources
</code></pre>
<p>The vendor name is a way to distinguish your package from other packages of the same name from different authors. For example, if I (Taylor Otwell) were to create a new package named "Zapper", the vendor name could be <code>Taylor</code> while the package name would be <code>Zapper</code>. By default, the workbench will create framework agnostic packages; however, the <code>resources</code> command tells the workbench to generate the package with Laravel specific directories such as <code>migrations</code>, <code>views</code>, <code>config</code>, etc.</p>
<p>Once the <code>workbench</code> command has been executed, your package will be available within the <code>workbench</code> directory of your Laravel installation. Next, you should register the <code>ServiceProvider</code> that was created for your package. You may register the provider by adding it to the <code>providers</code> array in the <code>app/config/app.php</code> file. This will instruct Laravel to load your package when your application starts. Service providers use a <code>[Package]ServiceProvider</code> naming convention. So, using the example above, you would add <code>Taylor\Zapper\ZapperServiceProvider</code> to the <code>providers</code> array.</p>
<p>Once the provider has been registered, you are ready to start developing your package! However, before diving in, you may wish to review the sections below to get more familiar with the package structure and development workflow.</p>
<p><a name="package-structure"></a></p>
<h2>Package Structure</h2>
<p>When using the <code>workbench</code> command, your package will be setup with conventions that allow the package to integrate well with other parts of the Laravel framework:</p>
<p><strong>Basic Package Directory Structure</strong></p>
<pre><code>/src
/Vendor
/Package
PackageServiceProvider.php
/config
/lang
/migrations
/views
/tests
/public
</code></pre>
<p>Let's explore this structure further. The <code>src/Vendor/Package</code> directory is the home of all of your package's classes, including the <code>ServiceProvider</code>. The <code>config</code>, <code>lang</code>, <code>migrations</code>, and <code>views</code> directories, as you might guess, contain the corresponding resources for your package. Packages may have any of these resources, just like "regular" applications.</p>
<p><a name="service-providers"></a></p>
<h2>Service Providers</h2>
<p>Service providers are simply bootstrap classes for packages. By default, they contain two methods: <code>boot</code> and <code>register</code>. Within these methods you may do anything you like: include a routes file, register bindings in the IoC container, attach to events, or anything else you wish to do.</p>
<p>The <code>register</code> method is called immediately when the service provider is registered, while the <code>boot</code> command is only called right before a request is routed. So, if actions in your service provider rely on another service provider already being registered, or you are overriding services bound by another provider, you should use the <code>boot</code> method.</p>
<p>When creating a package using the <code>workbench</code>, the <code>boot</code> command will already contain one action:</p>
<pre><code>$this->package('vendor/package');
</code></pre>
<p>This method allows Laravel to know how to properly load the views, configuration, and other resources for your application. In general, there should be no need for you to change this line of code, as it will setup the package using the workbench conventions.</p>
<p><a name="package-conventions"></a></p>
<h2>Package Conventions</h2>
<p>When utilizing resources from a package, such as configuration items or views, a double-colon syntax will generally be used:</p>
<p><strong>Loading A View From A Package</strong></p>
<pre><code>return View::make('package::view.name');
</code></pre>
<p><strong>Retrieving A Package Configuration Item</strong></p>
<pre><code>return Config::get('package::group.option');
</code></pre>
<blockquote>
<p><strong>Note:</strong> If your package contains migrations, consider prefixing the migration name with your package name to avoid potential class name conflicts with other packages.</p>
</blockquote>
<p><a name="development-workflow"></a></p>
<h2>Development Workflow</h2>
<p>When developing a package, it is useful to be able to develop within the context of an application, allowing you to easily view and experiment with your templates, etc. So, to get started, install a fresh copy of the Laravel framework, then use the <code>workbench</code> command to create your package structure.</p>
<p>After the <code>workbench</code> command has created your package. You may <code>git init</code> from the <code>workbench/[vendor]/[package]</code> directory and <code>git push</code> your package straight from the workbench! This will allow you to conveniently develop the package in an application context without being bogged down by constant <code>composer update</code> commands.</p>
<p>Since your packages are in the <code>workbench</code> directory, you may be wondering how Composer knows to autoload your package's files. When the <code>workbench</code> directory exists, Laravel will intelligently scan it for packages, loading their Composer autoload files when the application starts!</p>
<p><a name="package-routing"></a></p>
<h2>Package Routing</h2>
<p>In prior versions of Laravel, a <code>handles</code> clause was used to specify which URIs a package could respond to. However, in Laravel 4, a package may respond to any URI. To load a routes file for your package, simply <code>include</code> it from within your service provider's <code>boot</code> method.</p>
<p><strong>Including A Routes File From A Service Provider</strong></p>
<pre><code>public function boot()
{
$this->package('vendor/package');
include __DIR__.'/../../routes.php';
}
</code></pre>
<p><a name="package-configuration"></a></p>
<h2>Package Configuration</h2>
<p>Some packages may require configuration files. These files should be defined in the same way as typical application configuration files. And, when using the default <code>$this->package</code> method of registering resources in your service provider, may be accessed using the usual "double-colon" syntax:</p>
<p><strong>Accessing Package Configuration Files</strong></p>
<pre><code>Config::get('package::file.option');
</code></pre>
<p>However, if your package contains a single configuration file, you may simply name the file <code>config.php</code>. When this is done, you may access the options directly, without specifying the file name:</p>
<p><strong>Accessing Single File Package Configuration</strong></p>
<pre><code>Config::get('package::option');
</code></pre>
<h3>Cascading Configuration Files</h3>
<p>When other developers install your package, they may wish to override some of the configuration options. However, if they change the values in your package source code, they will be overwritten the next time Composer updates the package. Instead, the <code>config:publish</code> artisan command should be used:</p>
<p><strong>Executing The Config Publish Command</strong></p>
<pre><code>php artisan config:publish vendor/package
</code></pre>
<p>When this command is executed, the configuration files for your application will be copied to <code>app/config/packages/vendor/package</code> where they can be safely modified by the developer!</p>
<blockquote>
<p><strong>Note:</strong> The developer may also create environment specific configuration files for your package by placing them in <code>app/config/packages/vendor/package/environment</code>.</p>
</blockquote>
<p><a name="package-migrations"></a></p>
<h2>Package Migrations</h2>
<p>You may easily create and run migrations for any of your packages. To create a migration for a package in the workbench, use the <code>--bench</code> option:</p>
<p><strong>Creating Migrations For Workbench Packages</strong></p>
<pre><code>php artisan migrate:make create_users_table --bench="vendor/package"
</code></pre>
<p><strong>Running Migrations For Workbench Packages</strong></p>
<pre><code>php artisan migrate --bench="vendor/package"
</code></pre>
<p>To run migrations for a finished package that was installed via Composer into the <code>vendor</code> directory, you may use the <code>--package</code> directive:</p>
<p><strong>Running Migrations For An Installed Package</strong></p>
<pre><code>php artisan migrate --package="vendor/package"
</code></pre>
<p><a name="package-assets"></a></p>
<h2>Package Assets</h2>
<p>Some packages may have assets such as JavaScript, CSS, and images. However, we are unable to link to assets in the <code>vendor</code> or <code>workbench</code> directories, so we need a way to move these assets into the <code>public</code> directory of our application. The <code>asset:publish</code> command will take care of this for you:</p>
<p><strong>Moving Package Assets To Public</strong></p>
<pre><code>php artisan asset:publish
php artisan asset:publish vendor/package
</code></pre>
<p>If the package is still in the <code>workbench</code>, use the <code>--bench</code> directive:</p>
<pre><code>php artisan asset:publish --bench="vendor/package"
</code></pre>
<p>This command will move the assets into the <code>public/packages</code> directory according to the vendor and package name. So, a package named <code>userscape/kudos</code> would have its assets moved to <code>public/packages/userscape/kudos</code>. Using this asset publishing convention allows you to safely code asset paths in your package's views.</p>
<p><a name="publishing-packages"></a></p>
<h2>Publishing Packages</h2>
<p>When your package is ready to publish, you should submit the package to the <a href="http://packagist.org">Packagist</a> repository. If the package is specific to Laravel, consider adding a <code>laravel</code> tag to your package's <code>composer.json</code> file.</p>
<p>Also, it is courteous and helpful to tag your releases so that developers can depend on stable versions when requesting your package in their <code>composer.json</code> files. If a stable version is not ready, consider using the <code>branch-alias</code> Composer directive.</p>
<p>Once your package has been published, feel free to continue developing it within the application context created by <code>workbench</code>. This is a great way to continue to conveniently develop the package even after it has been published.</p>
<p>Some organizations choose to host their own private repository of packages for their own developers. If you are interested in doing this, review the documentation for the <a href="http://github.com/composer/satis">Satis</a> project provided by the Composer team.</p>
<footer>
<p><a href="http://four.laravel.com" title="Laravel 4 Documentation">Laravel 4 Documentation</a> grabbed by <a href="http://roes-wibowo.com" title="Roes Wibowo">Roes Wibowo</a>.</p>
</footer>
</section>
<div class="clearfix"></div>
</div>
<script src="js/vendor/jquery-1.8.2.min.js"></script>
<script src="js/vendor/prettify.js"></script>
<script src="js/plugins.js"></script>
<script src="js/main.js"></script>
<script>
var _gaq=[['_setAccount','UA-37104170-1'],['_trackPageview']];
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
s.parentNode.insertBefore(g,s)}(document,'script'));
</script>
</body>
</html>