【问题标题】:Ruby ERB - Create a content_for methodRuby ERB - 创建一个 content_for 方法
【发布时间】:2016-12-27 19:54:09
【问题描述】:

我目前正在为 gem 开发 ERB View 类。有了这个类,我想有一些 ERB 模板的辅助方法。
h(string) 这样的基本助手没关系。我找到了erbh gem,他帮助我更多地了解上下文的工作原理。
但现在我正在尝试创建一个 content_for 方法,就像在 Rails 或 Sinatra 中一样。

我第一次使用简单的Proc 来捕获视图块,然后调用call 方法来打印它。一开始就够用了。
但是在完成视图后,我看到了有线的想法,有些内容被打印了多次。
所以我看了一下Sinatra ContentFor helper 以了解他们是如何做到的,我复制了这个助手的一些方法。我没有错误,但块返回总是空的......我真的不知道为什么。

我对 ERB 的了解不足以了解 ERB 缓冲的工作原理。

代码

这里有一个解释我的代码状态的要点。我从我的库中提取了代码并对其进行了一些简化。

https://gist.github.com/nicolas-brousse/ac7f5454a1a45bae30c52dae826d587f/66cf76c97c35a02fc6bf4a3bc13d8d3b587356de

我想要什么?

我只想让content_for 方法像在 Rails 和 Sinatra 中一样工作。

谢谢!

【问题讨论】:

    标签: ruby erb


    【解决方案1】:

    阅读此blog article 后,我终于找到了它不起作用的原因。我不知道我是否以最好的方式和更清洁的方式做到了,但它确实有效。

    所以这个错误主要来自ERB initilization。通过使用属性而不是局部变量 eoutvar 现在它可以工作了。

    erb = ERB.new(str, nil, "<>", "@_erbout")
    

    我还对content_for helper 使用的capture 方法做了一点改动。

    现在看起来像这样 (gist)

    def content_for(key, content = nil, &block)
      block ||= proc { |*| content }
      content_blocks[key.to_sym] << capture_later(&block)
    end
    
    def content_for?(key)
      content_blocks[key.to_sym].any?
    end
    
    def yield_content(key, default = nil)
      return default if content_blocks[key.to_sym].empty?
      content_blocks[key.to_sym].map { |b| capture(&b) }.join
    end
    
    def capture(&block)
      @capture = nil
      @_erbout, _buf_was = '', @_erbout
      result = yield
      @_erbout = _buf_was
      result.strip.empty? && @capture ? @capture : result
    end
    
    def capture_later(&block)
      proc { |*| @capture = capture(&block) }
    end
    

    【讨论】:

      猜你喜欢
      • 2011-05-19
      • 2013-11-17
      • 2016-07-06
      • 1970-01-01
      • 2014-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      相关资源
      最近更新 更多