diff options
author | Jeff Dean <jeff@zilkey.com> | 2008-11-12 01:21:09 -0500 |
---|---|---|
committer | Jeff Dean <jeff@zilkey.com> | 2008-11-12 01:21:09 -0500 |
commit | ccd9ef158953e30e66a4da143314955cd64e71c8 (patch) | |
tree | fb2976e1fb5570913affc988dfc7b24e01a49fcb /railties/doc | |
parent | ef3672dddaf6171b2fd9ef5ecc4458e0349a486f (diff) | |
download | rails-ccd9ef158953e30e66a4da143314955cd64e71c8.tar.gz rails-ccd9ef158953e30e66a4da143314955cd64e71c8.tar.bz2 rails-ccd9ef158953e30e66a4da143314955cd64e71c8.zip |
Updated preparation section of plugins guide
Diffstat (limited to 'railties/doc')
3 files changed, 75 insertions, 85 deletions
diff --git a/railties/doc/guides/html/creating_plugins.html b/railties/doc/guides/html/creating_plugins.html index 48d5f03687..349986c0d3 100644 --- a/railties/doc/guides/html/creating_plugins.html +++ b/railties/doc/guides/html/creating_plugins.html @@ -204,7 +204,7 @@ ul#navMain { <li><a href="#_create_the_basic_app">Create the basic app</a></li> - <li><a href="#_create_the_plugin">Create the plugin</a></li> + <li><a href="#_generate_the_plugin_skeleton">Generate the plugin skeleton</a></li> <li><a href="#_setup_the_plugin_for_testing">Setup the plugin for testing</a></li> @@ -377,11 +377,12 @@ write custom Rake tasks in your plugin. <h2 id="_preparation">1. Preparation</h2>
<div class="sectionbody">
<h3 id="_create_the_basic_app">1.1. Create the basic app</h3>
-<div class="para"><p>In this tutorial we will create a basic rails application with 1 resource: bird. Start out by building the basic rails app:</p></div>
+<div class="para"><p>The examples in this guide require that you have a working rails application. To create a simple rails app execute:</p></div>
<div class="listingblock">
<div class="content">
-<pre><tt>rails plugin_demo
-cd plugin_demo
+<pre><tt>gem install rails
+rails yaffle_guide
+cd yaffle_guide
script/generate scaffold bird name:string
rake db:migrate
script/server</tt></pre>
@@ -392,22 +393,24 @@ script/server</tt></pre> <td class="icon">
<img src="./images/icons/note.png" alt="Note" />
</td>
-<td class="content">The aforementioned instructions will work for sqlite3. For more detailed instructions on how to create a rails app for other databases see the API docs.</td>
+<td class="content">
+<div class="title">Editor's note:</div>The aforementioned instructions will work for sqlite3. For more detailed instructions on how to create a rails app for other databases see the API docs.</td>
</tr></table>
</div>
-<h3 id="_create_the_plugin">1.2. Create the plugin</h3>
-<div class="para"><p>The built-in Rails plugin generator stubs out a new plugin. Pass the plugin name, either <em>CamelCased</em> or <em>under_scored</em>, as an argument. Pass <tt>--with-generator</tt> to add an example generator also.</p></div>
+<h3 id="_generate_the_plugin_skeleton">1.2. Generate the plugin skeleton</h3>
+<div class="para"><p>Rails ships with a plugin generator which creates a basic plugin skeleton. Pass the plugin name, either <em>CamelCased</em> or <em>under_scored</em>, as an argument. Pass <tt>--with-generator</tt> to add an example generator also.</p></div>
<div class="para"><p>This creates a plugin in <em>vendor/plugins</em> including an <em>init.rb</em> and <em>README</em> as well as standard <em>lib</em>, <em>task</em>, and <em>test</em> directories.</p></div>
<div class="para"><p>Examples:</p></div>
<div class="listingblock">
<div class="content">
-<pre><tt>./script/generate plugin BrowserFilters
-./script/generate plugin BrowserFilters --with-generator</tt></pre>
+<pre><tt>./script/generate plugin yaffle
+./script/generate plugin yaffle --with-generator</tt></pre>
</div></div>
-<div class="para"><p>Later in the plugin we will create a generator, so go ahead and add the <tt>--with-generator</tt> option now:</p></div>
+<div class="para"><p>To get more detailed help on the plugin generator, type <tt>./script/generate plugin</tt>.</p></div>
+<div class="para"><p>Later on this guide will describe how to work with generators, so go ahead and generate your plugin with the <tt>--with-generator</tt> option now:</p></div>
<div class="listingblock">
<div class="content">
-<pre><tt>script/generate plugin yaffle --with-generator</tt></pre>
+<pre><tt>./script/generate plugin yaffle --with-generator</tt></pre>
</div></div>
<div class="para"><p>You should see the following output:</p></div>
<div class="listingblock">
@@ -430,22 +433,8 @@ create vendor/plugins/yaffle/generators/yaffle/templates create vendor/plugins/yaffle/generators/yaffle/yaffle_generator.rb
create vendor/plugins/yaffle/generators/yaffle/USAGE</tt></pre>
</div></div>
-<div class="para"><p>For this plugin you won't need the file <em>vendor/plugins/yaffle/lib/yaffle.rb</em> so you can delete that.</p></div>
-<div class="listingblock">
-<div class="content">
-<pre><tt>rm vendor/plugins/yaffle/lib/yaffle.rb</tt></pre>
-</div></div>
-<div class="admonitionblock">
-<table><tr>
-<td class="icon">
-<img src="./images/icons/note.png" alt="Note" />
-</td>
-<td class="content">
-<div class="title">Editor's note:</div>Many plugin authors prefer to keep this file, and add all of the require statements in it. That way, they only line in init.rb would be <tt>require "yaffle"</tt>. If you are developing a plugin that has a lot of files in the lib directory, you may want to create a subdirectory like lib/yaffle and store your files in there. That way your init.rb file stays clean</td>
-</tr></table>
-</div>
<h3 id="_setup_the_plugin_for_testing">1.3. Setup the plugin for testing</h3>
-<div class="para"><p>Testing plugins that use the entire Rails stack can be complex, and the generator doesn't offer any help. In this tutorial you will learn how to test your plugin against multiple different adapters using ActiveRecord. This tutorial will not cover how to use fixtures in plugin tests.</p></div>
+<div class="para"><p>In this guide you will learn how to test your plugin against multiple different adapters using Active Record. This guide will not cover how to use fixtures in plugin tests.</p></div>
<div class="para"><p>To setup your plugin to allow for easy testing you'll need to add 3 files:</p></div>
<div class="ilist"><ul>
<li>
@@ -464,7 +453,6 @@ A test helper that sets up the database before your tests. </p>
</li>
</ul></div>
-<div class="para"><p>For this plugin you'll need 2 tables/models, Hickwalls and Wickwalls, so add the following files:</p></div>
<div class="para"><p><strong>vendor/plugins/yaffle/test/database.yml:</strong></p></div>
<div class="listingblock">
<div class="content">
@@ -490,7 +478,8 @@ mysql: :password:
:database: yaffle_plugin_test</tt></pre>
</div></div>
-<div class="para"><p><strong>vendor/plugins/yaffle/test/test_helper.rb:</strong></p></div>
+<div class="para"><p>For this guide you'll need 2 tables/models, Hickwalls and Wickwalls, so add the following:</p></div>
+<div class="para"><p><strong>vendor/plugins/yaffle/test/schema.rb:</strong></p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
by Lorenzo Bettini
@@ -508,10 +497,14 @@ http://www.gnu.org/software/src-highlite --> t<span style="color: #990000">.</span>datetime <span style="color: #990000">:</span>last_tweeted_at
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
-
-<span style="font-style: italic"><span style="color: #9A1900"># File: vendor/plugins/yaffle/test/test_helper.rb</span></span>
-
-ENV<span style="color: #990000">[</span><span style="color: #FF0000">'RAILS_ENV'</span><span style="color: #990000">]</span> <span style="color: #990000">=</span> <span style="color: #FF0000">'test'</span>
+</tt></pre></div></div>
+<div class="para"><p><strong>vendor/plugins/yaffle/test/test_helper.rb:</strong></p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt>ENV<span style="color: #990000">[</span><span style="color: #FF0000">'RAILS_ENV'</span><span style="color: #990000">]</span> <span style="color: #990000">=</span> <span style="color: #FF0000">'test'</span>
ENV<span style="color: #990000">[</span><span style="color: #FF0000">'RAILS_ROOT'</span><span style="color: #990000">]</span> <span style="color: #990000">||=</span> File<span style="color: #990000">.</span>dirname<span style="color: #990000">(</span><span style="font-weight: bold"><span style="color: #0000FF">__FILE__</span></span><span style="color: #990000">)</span> <span style="color: #990000">+</span> <span style="color: #FF0000">'/../../../..'</span>
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'test/unit'</span>
@@ -522,7 +515,6 @@ ActiveRecord<span style="color: #990000">::</span>Base<span style="color: #99000 db_adapter <span style="color: #990000">=</span> ENV<span style="color: #990000">[</span><span style="color: #FF0000">'DB'</span><span style="color: #990000">]</span>
-<span style="font-style: italic"><span style="color: #9A1900"># no db passed, try one of these fine config-free DBs before bombing.</span></span>
db_adapter <span style="color: #990000">||=</span>
<span style="font-weight: bold"><span style="color: #0000FF">begin</span></span>
<span style="font-weight: bold"><span style="color: #000080">require</span></span> <span style="color: #FF0000">'rubygems'</span>
@@ -547,11 +539,9 @@ ActiveRecord<span style="color: #990000">::</span>Base<span style="color: #99000 <span style="font-weight: bold"><span style="color: #000080">require</span></span> File<span style="color: #990000">.</span>dirname<span style="color: #990000">(</span><span style="font-weight: bold"><span style="color: #0000FF">__FILE__</span></span><span style="color: #990000">)</span> <span style="color: #990000">+</span> <span style="color: #FF0000">'/../init.rb'</span>
<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Hickwall <span style="color: #990000"><</span> ActiveRecord<span style="color: #990000">::</span>Base
- acts_as_yaffle
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> Wickwall <span style="color: #990000"><</span> ActiveRecord<span style="color: #990000">::</span>Base
- acts_as_yaffle <span style="color: #990000">:</span>yaffle_text_field <span style="color: #990000">=></span> <span style="color: #990000">:</span>last_tweet<span style="color: #990000">,</span> <span style="color: #990000">:</span>yaffle_date_field <span style="color: #990000">=></span> <span style="color: #990000">:</span>last_tweeted_at
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
</tt></pre></div></div>
</div>
@@ -1219,32 +1209,34 @@ ActionController<span style="color: #990000">::</span>Routing<span style="color: <div class="sectionbody">
<h3 id="_work_with_init_rb">8.1. Work with init.rb</h3>
<div class="para"><p>The plugin initializer script <em>init.rb</em> is invoked via <tt>eval</tt> (not <tt>require</tt>) so it has slightly different behavior.</p></div>
-<div class="para"><p>If you reopen any classes in init.rb itself your changes will potentially be made to the wrong module. There are 2 ways around this:</p></div>
-<div class="para"><p>The first way is to explicitly define the top-level module space for all modules and classes, like <tt>::Hash</tt>:</p></div>
+<div class="para"><p>If you reopen any classes in init.rb itself your changes will potentially be made to the wrong module. As a rule, it's better not to open any classes in <tt>init.rb</tt>, and it makes the plugin more difficult to turn into a gem.</p></div>
+<div class="para"><p>A better alternative is to reopen the class in a different file, and require that file from <tt>init.rb</tt>.</p></div>
+<div class="para"><p>If you must reopen a class in <tt>init.rb</tt>, there are various techniques. One way is to use <tt>module_eval</tt> or <tt>class_eval</tt>:</p></div>
+<div class="para"><p><strong>vendor/plugins/yaffle/init.rb</strong></p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 2.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
-<pre><tt><span style="font-style: italic"><span style="color: #9A1900"># File: vendor/plugins/yaffle/init.rb</span></span>
-
-<span style="font-weight: bold"><span style="color: #0000FF">class</span></span> <span style="color: #990000">::</span>Hash
+<pre><tt>Hash<span style="color: #990000">.</span>class_eval <span style="font-weight: bold"><span style="color: #0000FF">do</span></span>
<span style="font-weight: bold"><span style="color: #0000FF">def</span></span> is_a_special_hash?
<span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
</tt></pre></div></div>
-<div class="para"><p>OR you can use <tt>module_eval</tt> or <tt>class_eval</tt>:</p></div>
+<div class="para"><p>Another way is to explicitly define the top-level module space for all modules and classes, like <tt>::Hash</tt>:</p></div>
+<div class="para"><p><strong>vendor/plugins/yaffle/init.rb</strong></p></div>
<div class="listingblock">
-<div class="content">
-<pre><tt># File: vendor/plugins/yaffle/init.rb
-
-Hash.class_eval do
- def is_a_special_hash?
- true
- end
-end</tt></pre>
-</div></div>
+<div class="content"><!-- Generator: GNU source-highlight 2.9
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt><span style="font-weight: bold"><span style="color: #0000FF">class</span></span> <span style="color: #990000">::</span>Hash
+ <span style="font-weight: bold"><span style="color: #0000FF">def</span></span> is_a_special_hash?
+ <span style="font-weight: bold"><span style="color: #0000FF">true</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+<span style="font-weight: bold"><span style="color: #0000FF">end</span></span>
+</tt></pre></div></div>
<h3 id="_generate_rdoc_documentation">8.2. Generate RDoc Documentation</h3>
<div class="para"><p>Once your plugin is stable, the tests pass on all database and you are ready to deploy do everyone else a favor and document it! Luckily, writing documentation for your plugin is easy.</p></div>
<div class="para"><p>The first step is to update the README file with detailed information about how to use your plugin. A few key things to include are:</p></div>
diff --git a/railties/doc/guides/source/creating_plugins/odds_and_ends.txt b/railties/doc/guides/source/creating_plugins/odds_and_ends.txt index eb127f73ca..32da7ed7f3 100644 --- a/railties/doc/guides/source/creating_plugins/odds_and_ends.txt +++ b/railties/doc/guides/source/creating_plugins/odds_and_ends.txt @@ -4,27 +4,30 @@ The plugin initializer script 'init.rb' is invoked via `eval` (not `require`) so it has slightly different behavior. -If you reopen any classes in init.rb itself your changes will potentially be made to the wrong module. There are 2 ways around this: +If you reopen any classes in init.rb itself your changes will potentially be made to the wrong module. As a rule, it's better not to open any classes in `init.rb`, and it makes the plugin more difficult to turn into a gem. -The first way is to explicitly define the top-level module space for all modules and classes, like `::Hash`: +A better alternative is to reopen the class in a different file, and require that file from `init.rb`. + +If you must reopen a class in `init.rb`, there are various techniques. One way is to use `module_eval` or `class_eval`: + +*vendor/plugins/yaffle/init.rb* [source, ruby] --------------------------------------------------- -# File: vendor/plugins/yaffle/init.rb - -class ::Hash +Hash.class_eval do def is_a_special_hash? true end end --------------------------------------------------- -OR you can use `module_eval` or `class_eval`: +Another way is to explicitly define the top-level module space for all modules and classes, like `::Hash`: ---------------------------------------------------- -# File: vendor/plugins/yaffle/init.rb +*vendor/plugins/yaffle/init.rb* -Hash.class_eval do +[source, ruby] +--------------------------------------------------- +class ::Hash def is_a_special_hash? true end diff --git a/railties/doc/guides/source/creating_plugins/preparation.txt b/railties/doc/guides/source/creating_plugins/preparation.txt index 77e3a3561f..83717c7ac8 100644 --- a/railties/doc/guides/source/creating_plugins/preparation.txt +++ b/railties/doc/guides/source/creating_plugins/preparation.txt @@ -2,11 +2,12 @@ === Create the basic app === -In this tutorial we will create a basic rails application with 1 resource: bird. Start out by building the basic rails app: +The examples in this guide require that you have a working rails application. To create a simple rails app execute: ------------------------------------------------ -rails plugin_demo -cd plugin_demo +gem install rails +rails yaffle_guide +cd yaffle_guide script/generate scaffold bird name:string rake db:migrate script/server @@ -14,25 +15,28 @@ script/server Then navigate to http://localhost:3000/birds. Make sure you have a functioning rails app before continuing. +.Editor's note: NOTE: The aforementioned instructions will work for sqlite3. For more detailed instructions on how to create a rails app for other databases see the API docs. -=== Create the plugin === +=== Generate the plugin skeleton === -The built-in Rails plugin generator stubs out a new plugin. Pass the plugin name, either 'CamelCased' or 'under_scored', as an argument. Pass `\--with-generator` to add an example generator also. +Rails ships with a plugin generator which creates a basic plugin skeleton. Pass the plugin name, either 'CamelCased' or 'under_scored', as an argument. Pass `\--with-generator` to add an example generator also. This creates a plugin in 'vendor/plugins' including an 'init.rb' and 'README' as well as standard 'lib', 'task', and 'test' directories. Examples: ---------------------------------------------- -./script/generate plugin BrowserFilters -./script/generate plugin BrowserFilters --with-generator +./script/generate plugin yaffle +./script/generate plugin yaffle --with-generator ---------------------------------------------- -Later in the plugin we will create a generator, so go ahead and add the `\--with-generator` option now: +To get more detailed help on the plugin generator, type `./script/generate plugin`. + +Later on this guide will describe how to work with generators, so go ahead and generate your plugin with the `\--with-generator` option now: ---------------------------------------------- -script/generate plugin yaffle --with-generator +./script/generate plugin yaffle --with-generator ---------------------------------------------- You should see the following output: @@ -57,19 +61,10 @@ create vendor/plugins/yaffle/generators/yaffle/yaffle_generator.rb create vendor/plugins/yaffle/generators/yaffle/USAGE ---------------------------------------------- -For this plugin you won't need the file 'vendor/plugins/yaffle/lib/yaffle.rb' so you can delete that. - ----------------------------------------------- -rm vendor/plugins/yaffle/lib/yaffle.rb ----------------------------------------------- - -.Editor's note: -NOTE: Many plugin authors prefer to keep this file, and add all of the require statements in it. That way, they only line in init.rb would be `require "yaffle"`. If you are developing a plugin that has a lot of files in the lib directory, you may want to create a subdirectory like lib/yaffle and store your files in there. That way your init.rb file stays clean - === Setup the plugin for testing === -Testing plugins that use the entire Rails stack can be complex, and the generator doesn't offer any help. In this tutorial you will learn how to test your plugin against multiple different adapters using ActiveRecord. This tutorial will not cover how to use fixtures in plugin tests. +In this guide you will learn how to test your plugin against multiple different adapters using Active Record. This guide will not cover how to use fixtures in plugin tests. To setup your plugin to allow for easy testing you'll need to add 3 files: @@ -77,8 +72,6 @@ To setup your plugin to allow for easy testing you'll need to add 3 files: * A 'schema.rb' file with your table definitions. * A test helper that sets up the database before your tests. -For this plugin you'll need 2 tables/models, Hickwalls and Wickwalls, so add the following files: - *vendor/plugins/yaffle/test/database.yml:* ---------------------------------------------- @@ -105,7 +98,9 @@ mysql: :database: yaffle_plugin_test ---------------------------------------------- -*vendor/plugins/yaffle/test/test_helper.rb:* +For this guide you'll need 2 tables/models, Hickwalls and Wickwalls, so add the following: + +*vendor/plugins/yaffle/test/schema.rb:* [source, ruby] ---------------------------------------------- @@ -121,9 +116,12 @@ ActiveRecord::Schema.define(:version => 0) do t.datetime :last_tweeted_at end end +---------------------------------------------- -# File: vendor/plugins/yaffle/test/test_helper.rb +*vendor/plugins/yaffle/test/test_helper.rb:* +[source, ruby] +---------------------------------------------- ENV['RAILS_ENV'] = 'test' ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..' @@ -135,7 +133,6 @@ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log") db_adapter = ENV['DB'] -# no db passed, try one of these fine config-free DBs before bombing. db_adapter ||= begin require 'rubygems' @@ -160,10 +157,8 @@ load(File.dirname(__FILE__) + "/schema.rb") require File.dirname(__FILE__) + '/../init.rb' class Hickwall < ActiveRecord::Base - acts_as_yaffle end class Wickwall < ActiveRecord::Base - acts_as_yaffle :yaffle_text_field => :last_tweet, :yaffle_date_field => :last_tweeted_at end ---------------------------------------------- |