Skip to content

Add method to render template to string instead of a file #896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bogdan opened this issue Feb 26, 2025 · 0 comments
Open

Add method to render template to string instead of a file #896

bogdan opened this issue Feb 26, 2025 · 0 comments

Comments

@bogdan
Copy link

bogdan commented Feb 26, 2025

Sometimes rendering a template to file doesn't have enough flexibility and it is better to render template to string and then put content to file manually via inject_into_file etc.
As a bonus, this method can be easier to use to test templates.

Here is the draft from ChatGPT of what is needed:

    # Renders an ERB template from the source path and returns it as a string.
    #
    # ==== Parameters
    # source<String>:: the relative path to the source root.
    # context<Binding>:: binding context for the template (default: instance_eval binding).
    #
    # ==== Returns
    # String:: the rendered template content.
    #
    # ==== Example
    #   render_template("README")
    #
    def render_template(source, context: instance_eval("binding"))
      source = File.expand_path(find_in_source_paths(source.to_s))
      capturable_erb = CapturableERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer")
      capturable_erb.tap { |erb| erb.filename = source }.result(context)
    end

    # Gets an ERB template at the relative source, executes it, and makes a copy
    # at the relative destination. If the destination is not given it's assumed
    # to be equal to the source removing .tt from the filename.
    #
    # ==== Parameters
    # source<String>:: the relative path to the source root.
    # destination<String>:: the relative path to the destination root.
    # config<Hash>:: give :verbose => false to not log the status.
    #
    # ==== Examples
    #
    #   template "README", "doc/README"
    #
    #   template "doc/README"
    #
    def template(source, *args, &block)
      config = args.last.is_a?(Hash) ? args.pop : {}
      destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, "")
      content = render_template(source, context: config.delete(:context) || instance_eval("binding"))
      content = yield(content) if block
      create_file destination, nil, config { content }
    end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant