关键字: rails generator 来看看怎样写自己的Generator吧
首先运行:
ruby script/generate
console中的输出可以看到Rails默认的generate:
- Installed Generators
- Builtin: controller, integration_test, mailer, migration, model, observer, plugin, resource, scaffold,
- scaffold_resource, session_migration, web_service
Installed Generators Builtin: controller, integration_test, mailer, migration, model, observer, plugin, resource, scaffold, scaffold_resource, session_migration, web_service
我们创建本机的generators目录:
- mkdir -p ~/.rails/generators/app_layout
mkdir -p ~/.rails/generators/app_layout
或者在某个rails项目里创建私有的generators:
- mkdir -p /Users/demo/rails/simple/generators/app_layout
mkdir -p /Users/demo/rails/simple/generators/app_layout
Generators有带参数和不带参数两种,先来看不带参数的Generator:
- app_layout
- --app_layout_generator.rb
- --USAGE
- templates
- ----stylesheet.css
- ----layout.rhtml
app_layout --app_layout_generator.rb --USAGE templates ----stylesheet.css ----layout.rhtml
我们看看不带参数的Generator的写法:
- class AppLayoutGenerator < Rails::Generator::Base
- def manifest
- record do |m|
- m.file "layout.rhtml", "app/views/layouts/application.rhtml"
- m.file "stylesheet.css", "public/stylesheets/application.css"
- end
- end
- end
class AppLayoutGenerator < Rails::Generator::Base def manifest record do |m| m.file "layout.rhtml", "app/views/layouts/application.rhtml" m.file "stylesheet.css", "public/stylesheets/application.css" end end end
我们的AppLayoutGenerator继承与Rails::Generator::Base,它的功能相当于cp layout.rhtml和stylesheet.css到后面的文件
我们再运行ruby script/generate看看:
- Installed Generators
- User: app_layout
- Builtin: controller, integration_test, mailer, migration, model, observer, plugin, resource, scaffold,
- scaffold_resource, session_migration, web_service
Installed Generators User: app_layout Builtin: controller, integration_test, mailer, migration, model, observer, plugin, resource, scaffold, scaffold_resource, session_migration, web_service
OK,我们看到除了Builtin的Generators,我们刚才创建的本机的app_layout这个Generator也出现在User Generators里
我们这样来使用它:
- ruby script/generate app_layout
ruby script/generate app_layout
我们看到console打印出如下信息:
- create app/views/layouts/application.rhtml
- create public/stylesheets/application.css
create app/views/layouts/application.rhtml create public/stylesheets/application.css
系统自动创建了上面两个文件,内容为我们的app_layout/templates目录下的两个文件
如果我们想使用ruby script/generate app_layout home这样的方式,用home参数来指定创建home.rhtml和home.css,
我们该怎样写我们的Generator呢?
答案是继承Rails::Generator::NamedBase
- class AppLayoutGenerator < Rails::Generator::NamedBase
- def manifest
- record do |m|
- m.template "layout.rhtml", "app/views/layouts/#{file_name}.rhtml"
- m.file "stylesheet.css", "public/stylesheets/#{file_name}.css"
- end
- end
- end
class AppLayoutGenerator < Rails::Generator::NamedBase def manifest record do |m| m.template "layout.rhtml", "app/views/layouts/#{file_name}.rhtml" m.file "stylesheet.css", "public/stylesheets/#{file_name}.css" end end end
除了使用m.template,我们还要修改layout.rhtml:
- <html>
- <head>
- <title>Untitled</title>
- <%%= stylesheet_link_tag '<%= file_name %>' %>
- <%%= javascript_include_tag :defaults %>
- </head>
- <body>
- <div id="container">
- <%% flash.each do |name, msg| %>
- <%%= content_tag :div, msg, :id => "flash_#{name}" %>
- <%% end %>
- <%%= yield %>
- </div>
- </body>
- </html>
<html> <head> <title>Untitled</title> <%%= stylesheet_link_tag '<%= file_name %>' %> <%%= javascript_include_tag :defaults %> </head> <body> <div %> <%% end %> <%%= yield %> </div> </body> </html>
这里的template使用<%% %>而不是<% %>
我们可以看看Rails源码/railties/lib/rails_generator/generators/components/scaffold/templates/layout.html.erb:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
- <title><%= controller_class_name %>: <%%= controller.action_name %></title>
- <%%= stylesheet_link_tag 'scaffold' %>
- </head>
- <body>
-
- <p style="color: green"><%%= flash[:notice] %></p>
-
- <%%= yield %>
-
- </body>
- </html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <title><%= controller_class_name %>: <%%= controller.action_name %></title> <%%= stylesheet_link_tag 'scaffold' %> </head> <body> <p style="color: green"><%%= flash[:notice] %></p> <%%= yield %> </body> </html>