Skip to content
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

chore: add render_template with jinja-like syntax #129

Closed

Conversation

Jcharis
Copy link

@Jcharis Jcharis commented Sep 28, 2023

Type of PR

  • Add render_template() and render_html() to render data passed from backend to frontend html files
  • Utilize Julia code in html

@ndortega
Copy link
Member

ndortega commented Oct 4, 2023

Hi @Jcharis,

Thanks for the PR! I like the idea and decided to approach this with a different interface to mustache and oteraengine. The primary reason is that these functions have to load the template every time they are rendered. In most cases, templates don't change at runtime so we can store the template files in memory and reuse them as needed.

Here are the different function signatures of the mustache helper function. Together they can handle strings, files and the native mustache templates. These helper functions can also autodetect mime types so we can use mustache to template any kind of file and return it with the correct headers.

function mustache(template::String; kwargs...)
function mustache(tokens::Mustache.MustacheTokens; kwargs...)
function mustache(file::IO; mime_type=nothing, kwargs...)

Here's a simple example of how to use it

using Oxygen

# define our template
mustache_template_str = """
Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}
"""

# load the template and provide a helper function to create the HTML Response
# (the name of this variable doesn't matter)
render = mustache(mustache_template_str)

@get "/mustache/string" function()
  data = Dict(
      "name" => "Chris",
      "value" => 10000,
      "taxed_value" => 10000 - (10000 * 0.4),
      "in_ca" => true
  )
  # render this template with our data and return an HTML.Response 
  return render(data)
end

Here's the mustache helper function that handles string templates and filepaths. it will pass off any files to the mustache function that deals with files explicitly

"""
    mustache(template::String; kwargs...)

Create a function that renders a Mustache `template` string with the provided `kwargs`.
If `template` is a file path, it reads the file content as the template string.
Returns a function that takes a dictionary `data`, optional `status`, and `headers`, and
returns an HTTP Response object with the rendered content.
"""
function mustache(template::String; kwargs...)
    # Case 1: a path to a file was passed
    if isfile(template)
        # deterime the mime type based on the extension type 
        content_type = mime_from_path(template, MIME"application/octet-stream"()) |> contenttype_from_mime
        return mustache(open(template); mime_type=content_type, kwargs...)
    end

    # Case 2: A string template was passed directly
    return function(data::AbstractDict; status=200, headers=[])
        content = Mustache.render(template, data; kwargs...)
        response(content, status, headers)
    end
end

What do you think?

@Jcharis
Copy link
Author

Jcharis commented Oct 4, 2023

Hi @ndortega, thanks for the reply and the feedback. I like your approach,
I did not consider that in most cases the templates don't change at runtime, so I think we can use your implementation

@ndortega
Copy link
Member

closing this pr to replace it for #132

@ndortega ndortega closed this Oct 17, 2023
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

Successfully merging this pull request may close these issues.

2 participants