`
fantaxy025025
  • 浏览: 1309050 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

动手写rails(二)Rails_Ruby_ERB使用_模板_定制

 
阅读更多

动手写rails(二)Rails_Ruby_ERB使用_模板_定制

 

一。基础:基本知识

 

先看例子代码:

例子1:

require "erb"

#例子1:
erb = ERB.new("I am <%= 'Fantaxy' %>")
puts "例子1:"
puts erb.result
puts erb.src

 

输出:

例子1:

I am Fantaxy

_erbout = ''; _erbout.concat "I am "; _erbout.concat(( 'Fantaxy' ).to_s); _erbout

 

例子2:

#例子2:
a = 123
erb = ERB.new("it is <%=a %>")
puts "例子2:"
puts erb.result(binding)
puts erb.src

输出: 

例子2:

it is 123

_erbout = ''; _erbout.concat "it is "; _erbout.concat((a ).to_s); _erbout

 

 

例子3:

erb_str = %q*
  <%
  x = "_aaa_"
  1.upto(5) do |i|
    x << "_#{i}_"
  end
  %>
  <%= x %>
*
erb = ERB.new(erb_str)
puts erb.result(binding)
puts erb.src

输出:

 


  

  _aaa__1__2__3__4__5_

_erbout = ''; _erbout.concat "\n  "

  x = "_aaa_"

  1.upto(5) do |i|

    x << "_#{i}_"

  end

  ; _erbout.concat "\n  "

; _erbout.concat(( x ).to_s); _erbout.concat "\n"

; _erbout

 

 

小结:

#1 如果不是用绑定的变量,则不许要binding参数,否则需要把环境传进来

#2 ERB中可以使用<%= 1111 %> 和 <% 控制语句 %>, 这一点和jsp是如如出一辙的

#3 ERB的src命令可以输出可以run的ruby代码

#4 在rvm中运行输出的src代码 等价于 调用result方法 等价于在rvm中运行 eval(erb.src)

_erbout = ''; _erbout.concat "\n  "
; 
  x = "_aaa_"
  1.upto(5) do |i|
    x << "_#{i}_"
  end
  ; _erbout.concat "\n  "
; _erbout.concat(( x ).to_s); _erbout.concat "\n"
; _erbout

输出:

 


  

  _aaa__1__2__3__4__5_

puts eval(erb.src) 

输出同上。

 

二。进阶:输出新起一行设置,安全设置,返回值设置,及灵活使用

 

ERB.new(str, safe_level=nil, trim_mode=nil, eoutvar='_erbout')

#1 安全级别

#2 新起一行设置

ERB默认会把%>结尾的行单独成行;

If trim_mode is passed a String containing one or more of the following modifiers, ERB will adjust its code generation as listed:

%  enables Ruby code processing for lines beginning with %
<> omit newline for lines starting with <% and ending in %>
>  omit newline for lines ending in %>

上面的输出部分,会看见前面有空行,这个就是输出的准确内容,空行原因就是这里说的。

 

#3 返回值设置

eoutvar can be used to set the name of the variable ERB will build up its output in. This is useful when you need to run multiple ERB templates through the same binding and/or when you want to control where output ends up. Pass the name of the variable to be used inside a String.

例子:

require "erb"

a = "Fantaxy"
@output_buffer = "I am "
erb = ERB.new("<% @output_buffer ||= '';%> Yes!  <%= @output_buffer << a %>", 1, "@output_buffer")
puts erb.result(binding)
a = "025025"
puts erb.result(binding)
puts @output_buffer

输出(请选中查看):

 

 Yes!  I am Fantaxy

 Yes!  I am Fantaxy025025

I am Fantaxy025025

 

这里有个问题,@output_buffer在模板中共用了。

因为变量共用导致了模板使用没有了独立性,一般不会使用共用变量的方式。

但如果不共用一个变量,erb每次都会重新对输出结果保存的变量进行赋值。

看这个例子:

require "erb"

user_name = "Fantaxy"
@output_buffer = ""
puts "@output_buffer = #{@output_buffer}"
erb = ERB.new("I am <%= user_name %>", 1, "<>", "@output_buffer")

puts "erb_result = #{erb.result(binding)}"
puts "@output_buffer = #{@output_buffer}"

user_name = "June"
puts "erb_result = #{erb.result(binding)}"
puts "@output_buffer = #{@output_buffer}"

输出:

@output_buffer = 

erb_result = I am Fantaxy

@output_buffer = I am Fantaxy

erb_result = I am June

@output_buffer = I am June

 

从结果可以验证,@output_buffer的被重新赋值了。

为什么?

从本质上来说,erb的执行就是生成src后用rvm执行的。

每次调用src方法,都会重新使用输出变量并赋值为空字符串(''),请看前面几个例子中src生成的代码:

_erbout = '';

 

怎么解决这个问题:

折中的办法是保持erb模板文件的独立性,用逻辑来达到输出结果的关联。

看例子的改进版本:

require "erb"

user_name = "Fantaxy"
@output_buffer = ""
puts "@output_buffer = #{@output_buffer}"
erb = ERB.new("I am <%= user_name %>", 1, "<>", "@output_buffer")

puts "erb_result = #{erb.result(binding)}"
puts "@output_buffer = #{@output_buffer}"

old_output_buffer = @output_buffer #先保存下来
user_name = "June"
puts "erb_result = #{erb.result(binding)}" #@output_buffer被覆盖了
puts "@output_buffer = #{@output_buffer}"
@output_buffer = "#{old_output_buffer} AND #{@output_buffer}"
puts "@output_buffer = #{@output_buffer}"

输出结果:

@output_buffer = 

erb_result = I am Fantaxy

@output_buffer = I am Fantaxy

erb_result = I am June

@output_buffer = I am June

@output_buffer = I am Fantaxy AND I am June

 

这样就使得view的erb模板成为了独立,想怎么使用(比如内容前置,后置等),何时使用,交给了控制端灵活使用。

 

上面的做法可以解决view模板内容前置,后置的问题,但是如果想把一个view模板的内容插入另一个erb模板的中间,该怎么办呢?

需求简写条件:

erbA的内容是:

This is head

body content xxx

body(将会有内容插入此处)

body content yyy

This is foot

erbB的内容是:

I am Fantaxy

需求简写问题:

如何可以用erb渲染后,把erbB的内容插入erbA中间bodyXXX的位置(别用replace哈)

 

解决方法:yield

 

require "erb"

#mocking
@output_buffer = ""
def test_erb_out_mocking_layout
  erbA_str = <<-ERB
    <%="This is head"%>
    <%="body content xxx"%>
    <% yield %>
    <%="body content yyy"%>
    <%="This is foot"%>
  ERB
  erbA = ERB.new(erbA_str, 1, '<>', "@output_buffer")
  erbA.result(binding)
end

#run
test_erb_out_mocking_layout do
  @old_output_buffer = @output_buffer
  erbB = ERB.new("I am Fantaxy!", 1, '<>', "@output_buffer")
  erbB.result(binding)
  @output_buffer = "#{@old_output_buffer}#{@output_buffer}"
end

#testing
puts @output_buffer 

输出:

 

    This is head

    body content xxx

    I am Fantaxy!

    body content yyy

    This is foot

这样rails的layout问题如何写的核心问题也就解决了。

再强调一下核心内容(对么?):

erb模板run(result)的过程本质就是转化成ruby语句后在rvm中运行。

上面的yield如何使用,只需要把erb的src输出来看看就知道了,这也是为什么这个例子包装入了一个方法内,其他的例子可以直接写代码了。(自己试试看吧,不贴上来了)

 

三。高级:erb的其他内容

 

1)erb中的ruby代码空白换行问题

erb中的ruby代码嵌入了<% ruby代码 %>

但是默认会认为其前后的内容也是输出result的结果。但很多时候不许要这个,比如html代码中的这些ruby逻辑控制,仅仅想让他成为控制,而不影响生成的html格式。

方法:上面已经有了,可以设置new中的3ed参数,以及解释:

%  enables Ruby code processing for lines beginning with %
<> omit newline for lines starting with <% and ending in %>
>  omit newline for lines ending in %>

 

但是rails中的 -%>怎么会其作用呢?

原来有个hack没有在文档中写出来:3ed参数传递'-'则打开了 <%-  和  -%>标签

 

2)erb中可以定义方法和类等,作用如同freemarker中的macro或者c中的宏吧

A:定义Class:

<%# file: example.html.erb %>
<%= "arg1 = #{@arg1}" %>
<%= "arg2 = #{@arg2}" %>
class MyClass_1
  def initialize(arg1, arg2)
    @arg1 = arg1;  @arg2 = arg2
  end
end
filename = 'example.html.erb'  # @arg1 and @arg2 are used in example.html.erb
erb = ERB.new(File.read(filename))
erb.filename = filename
MyClass_1 = erb.def_class(MyClass_1, 'render()')
print MyClass_1.new('foo', 123).render()

 输出:

 

(注:空行)

arg1 = foo

arg2 = 123

 

 

B:定义方法

<%# example.rhtml %>
<%= "arg1 = #{arg1}" %>
<%= "arg2 = #{arg2}" %>
class MyClass; end
filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml
erb = ERB.new(File.read(filename))
erb.def_method(MyClass, 'render(arg1, arg2)', filename)
print MyClass.new.render('foo', 123)

输出:同上

 

C:定义Module

 

filename = 'example.rhtml'   # 'arg1' and 'arg2' are used in example.rhtml
erb = ERB.new(File.read(filename))
erb.filename = filename
MyModule = erb.def_module('render(arg1, arg2)')
class MyClass
  include MyModule
  def test_render(arg1, arg2)
    puts render(arg1, arg2)
  end
end
MyClass.new.test_render("Lee", "June")

输出:

 

 

arg1 = Lee

arg2 = June

 

结束:

rails中使用的主要模板解析用的是ERB,避免不了很多的地方都出现了ERB的使用方法和技巧。

可以说,ERB的环境和使用方法,影响了整个MVC框架的VC层的设计。

 

 

参考:

官方api介绍比较详细的解释,erb

http://ruby-doc.org/stdlib-1.9.3/

换行问题和ERB标签的识别和扩展:

http://cheat.errtheblog.com/s/erb/

http://stackoverflow.com/questions/9208728/embedded-ruby-erb-tags

http://stackoverflow.com/questions/3311589/how-to-extend-ruby-erb-for-handling-tags-as-well

ERB的一个tutorial step by step:

http://www.stuartellis.eu/articles/erb/

讨论erb和rails以及mvc的几个帖子:

http://www.iteye.com/topic/72525#268222

http://www.iteye.com/topic/84116

 

 

            ||

           |  |

          |    |

====结束====

===           ===

==                ==

=                     =

|                       |

 

 

 

 

分享到:
评论

相关推荐

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    - **视图文件**:通常使用ERB模板语言来编写视图文件,这些文件位于`app/views`目录下。 #### 八、组件 - **定义**:组件是可重用的代码块,用于封装重复使用的UI元素或逻辑。 - **使用**:在视图文件中通过`...

    Ruby中ERB模板的使用

    output = erb_template.result(binding) # 将结果写入新文件 File.write("output_#{domain}.txt", output) end ``` 在这个例子中,`domain2.txt`可能包含一个ERB模板,使用`&lt;%= domain %&gt;`这样的表达式来引用`...

    Ruby新手学习书(Ruby语言中文教程)和Rails_4_days

    5. **视图模板**:使用ERB(Embedded Ruby)编写HTML模板,结合Rails的助手方法,构建用户界面。 6. **测试驱动开发**:Rails鼓励TDD(Test-Driven Development),使用RSpec或MiniTest进行单元测试和集成测试。 7...

    Rails确认替换为SweetAlert_Ruby_HTML_下载.zip

    Rails框架是基于Ruby的一种Web开发框架,它以其“约定优于配置”的理念,为开发者提供了高效且灵活的开发环境。在Rails应用中,我们经常需要处理用户确认操作,比如删除、更新等,确保用户在执行不可逆操作前进行...

    web开发_ruby_on_rails

    Rails充分利用了Ruby社区中的其他工具和技术,如**Rake**用于构建和部署任务,**ERb**作为模板引擎,还有**Test::Unit**用于单元测试。这些工具与Rails紧密集成,共同构成了强大的开发环境。 #### 八、结论 Ruby ...

    ruby_on_rails 源代码上

    Rails支持多种模板引擎,如ERB(嵌入式Ruby)和HAML。视图负责展示数据,通过结合HTML、CSS和JavaScript,创建用户交互界面。Rails还提供了辅助方法,如链接生成、表单构建等,以简化视图代码。 6. **控制器** ...

    Ruby+for+Rails

    ERB(Embedded Ruby)是Rails视图中常用的模板引擎,可以插入Ruby代码到HTML中。例如,`&lt;%= @book.title %&gt;`会显示书籍的标题。 10. **Rails的最佳实践** - 使用`strong_parameters`控制模型接收的参数。 - 遵循...

    rails_best_practices:Rails项目的代码度量工具

    rails_best_practices支持Ruby 1.9.3或更高版本。 外部介绍 用法 在Rails应用程序的根目录中,运行: rails_best_practices . 或用于HTML输出: rails_best_practices -f html . 默认情况下,rails_best_practices...

    Ruby On Rails中文教材(PDF)

    6. **erb模板**:Rails中的视图通常使用ERB(Embedded Ruby)模板语言,将HTML与Ruby代码混合,用于动态生成页面内容。 7. **Helper方法**:Rails提供了许多内置助手方法,帮助开发者在视图中处理复杂的逻辑和呈现...

    Ruby on Rails入门例子

    Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...

    ruby on rails 3 tutorial.pdf

    在Rails中,ERB(Embedded Ruby)模板允许你在HTML中嵌入Ruby代码,动态生成页面内容。 本书还会详细讲解Rails的路由系统,它是应用中URL和控制器动作之间的映射,确保用户请求能够正确地到达目的地。此外,你还将...

    ruby on rails(开发文档)

    Rails提供了许多模板语言,如ERB(Embedded Ruby)和Haml。 7. **Helper方法**:为了保持视图的简洁,Rails允许你在helper模块中定义辅助方法,然后在视图中调用。 8. **测试驱动开发(TDD)**:Rails鼓励使用测试...

    ruby on rails在线考试系统

    4. 模板引擎:Rails使用ERB(Embedded Ruby)或Haml等模板语言,方便快速构建动态视图。在在线考试系统中,这些模板可能会用于生成试卷页面、答题页面以及结果展示页。 5. Active Record关联:Rails中的...

    ruby on rails 教程源码

    - **views**: 视图负责展示数据,通常由ERB(Embedded Ruby)模板组成,将Ruby代码嵌入HTML中。 - **helpers**: 辅助方法存储在`application_helper.rb`等文件中,可跨视图共享代码。 4. **db**目录:包含数据库...

    rails_sample_app:Ruby on Rails 教程

    Rails中的视图使用ERB(Embedded Ruby)模板,将HTML与Ruby代码混合,用于动态渲染内容。 - **控制器(Controller)**:处理用户请求,协调模型和视图。控制器负责处理数据,调用模型方法,并向视图传递数据。 **3....

    ruby on rails最佳敏捷开发

    此外,Rails的 erb(嵌入Ruby的HTML)模板系统使视图和逻辑更加分离。 Rails的另一个显著特点是对测试的重视,它内置了测试框架Rspec和Cucumber,鼓励开发者进行TDD(测试驱动开发)和BDD(行为驱动开发),从而...

    Rails_Recipes_with_Source_Code

    3. **视图(Views)**:视图负责展示数据,通常使用 erb 或haml模板语言。书中可能讲解如何使用辅助方法(Helper Methods)、局部变量、布局(Layouts)和部分视图(Partials)来创建用户友好的界面。 4. **控制器...

    Ruby on Rails入门经典

    6. ** erb和haml模板语言**:Rails支持两种视图模板语言,erb是嵌入式Ruby代码,而haml则是更简洁的HTML抽象语法。它们允许在视图中插入动态内容。 7. **测试驱动开发(TDD)**:Rails鼓励使用测试来确保代码质量,...

    Ruby on Rails入门权威经典

    视图(View)部分主要涉及ERB(Embedded Ruby)模板语言和辅助方法,以及如何使用布局和部分视图来组织界面。此外,书中还会探讨如何利用Rails的强大力量,如局部变量、实例变量和实例方法来传递数据给视图。 控制...

    Ruby on Rails 教程 - 201406

    ActionView组件提供了模板系统,允许开发者使用ERB(Embedded Ruby)或其他模板引擎如Haml、Slim编写视图。这些模板结合了HTML和Ruby代码,方便地渲染动态内容。 路由(Routes)是Rails应用的重要组成部分,它将...

Global site tag (gtag.js) - Google Analytics