【问题标题】:How to use “Phoenix.View.render_to_string(…)” with text templates?如何在文本模板中使用“Phoenix.View.render_to_string(...)”?
【发布时间】:2019-02-15 04:24:31
【问题描述】:

是否有专门针对文本模板的替代方案?

在文本模板中,我还有需要用值替换的长生不老药变量。也就是说,它是一个“soemthing.txt.eex”,而不仅仅是一个“.txt”

【问题讨论】:

    标签: html elixir phoenix-framework


    【解决方案1】:

    鉴于这些模板:

    world.html.eex

    <h1>From a template: Hello <%= String.capitalize(@name) %></h1>
    

    world.txt.eex

    From a template: Hello <%= String.capitalize(@name) %>
    

    以下是在每个模板上调用render()render_to_string()render_to_iodata() 后shell 中的一些结果:

    ~/phoenix_apps/hello$ iex -S mix
    Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
    Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)
    
    iex(1)> Phoenix.View.render_to_iodata(HelloWeb.HelloView, "world.html", conn: %Plug.Conn{}, name: "Wintermute")
    ["<h1>From a template: Hello ", "Wintermute", "</h1>\n"]
    
    iex(2)> Phoenix.View.render_to_string(HelloWeb.HelloView, "world.html", conn: %Plug.Conn{}, name: "Wintermute")
    "<h1>From a template: Hello Wintermute</h1>\n"
    
    iex(3)> Phoenix.View.render(HelloWeb.HelloView, "world.html", conn: %Plug.Conn{}, name: "Wintermute")          
    {:safe, ["<h1>From a template: Hello ", "Wintermute", "</h1>\n"]}
    
    iex(4)> 
    nil
    iex(5)> 
    nil
    
    iex(6)> Phoenix.View.render_to_iodata(HelloWeb.HelloView, "world.txt", conn: %Plug.Conn{}, name: "Wintermute") 
    "From a template: Hello Wintermute\n"
    
    iex(7)> Phoenix.View.render_to_string(HelloWeb.HelloView, "world.txt", conn: %Plug.Conn{}, name: "Wintermute") 
    "From a template: Hello Wintermute\n"
    
    iex(8)> Phoenix.View.render(HelloWeb.HelloView, "world.txt", conn: %Plug.Conn{}, name: "Wintermute")           
    "From a template: Hello Wintermute\n"
    
    iex(9)> 
    

    所以,在我看来,当您的文件是 .txt.eex 文件时,您可以使用任何渲染函数。

    如何使用 Phoenix.View.render_to_string(...) 与文本 - 非 html - 模板?

    我不知道是否有更好的方法,但这可行:

    defmodule HelloWeb.HelloController do
      use HelloWeb, :controller
    
      def world(conn, %{"name" => name}) do
        str = Phoenix.View.render_to_string(
                  HelloWeb.HelloView, 
                  "world.txt", 
                  conn: %Plug.Conn{}, 
                  name: name)
        text(conn, str)
      end
    
    end
    

    hello_web/templates/hello/world.txt.eex

    From a template: Hello <%= String.capitalize(@name) %>
    

    看起来text()str 中的任何html 字符替换为html 实体,例如&amp;gt;&amp;gt; 替换,这样浏览器就不会呈现 html。

    是否有专门针对文本模板的替代方案?

    完成同样事情的另一种方法是直接使用 EEx (Embedded Elixir) 进行变量替换。诀窍是获取模板文件的路径:

    hello/priv/my_text_templates/world.txt:

    <%= greeting %> <%= String.capitalize(name) %>!
    

    控制器

    defmodule HelloWeb.HelloController do
      use HelloWeb, :controller
    
      def world(conn, %{"name" => name}) do
    
        template_path = Path.join([
                          :code.priv_dir(:hello), 
                          "my_text_templates", 
                          "world.txt.eex"])
        str = EEx.eval_file(
                template_path,
                [greeting: "Hello", name: name]
              )
    
        text(conn, str)
      end
    
    end
    

    顺便说一句,htmljson 都是字符串——浏览器在看到字符串中的 html 时会做一些不同的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-19
      • 2015-07-10
      • 2011-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-07
      • 1970-01-01
      相关资源
      最近更新 更多