MommaWatasu / OteraEngine.jl

This package is a template engine for Julia Lang.
https://mommawatasu.github.io/OteraEngine.jl/stable
MIT License
20 stars 4 forks source link

Tutorial Example is not working #17

Closed ndortega closed 12 months ago

ndortega commented 1 year ago

Hi @MommaWatasu ,

I'm trying to run the following example from your docs but am running into an error. Here are my specs

OS: windows 10 language version: julia 1.6.7

module Main 
using OteraEngine

txt = "```using Dates; now()```. Hello {{ usr }}!"
tmp = Template(txt, path = false)
init = Dict("usr"=>"OteraEngine")
tmp(tmp_init = init)

end

Here is the error logs

julia> include("main.jl")
WARNING: replacing module Main.
ERROR: syntax: invalid escape sequence
Stacktrace:
 [1] top-level scope
   @ none:1
ERROR: LoadError: TemplateError: ProcessFailedException(Base.Process[Process(`julia -e 'using Pkg; Pkg.activate("F:\Programming\otera-demo\Project.toml"); using Dates; function f();now();end; f()'`, ProcessExited(1))]) has occurred during processing jl code blocks. if you can't find any problems in your template, please report issue on https://github.com/MommaWatasu/OteraEngine.jl/issues.
Stacktrace:
 [1] (::OteraEngine.Template)(; tmp_init::Dict{String, String}, jl_init::Dict{String, Union{AbstractString, Number}})
   @ OteraEngine C:\Users\Nate\.julia\packages\OteraEngine\eW6hw\src\template.jl:102
 [2] top-level scope
   @ F:\Programming\otera-demo\main.jl:8
 [3] include(fname::String)
   @ Base.MainInclude .\client.jl:444
 [4] top-level scope
   @ REPL[4]:1
in expression starting at F:\Programming\otera-demo\main.jl:1

caused by: failed process: Process(`julia -e 'using Pkg; Pkg.activate("F:\Programming\otera-demo\Project.toml"); using Dates; function f();now();end; f()'`, ProcessExited(1)) [1]

Stacktrace:
 [1] pipeline_error
   @ .\process.jl:538 [inlined]
 [2] read(cmd::Cmd)
   @ Base .\process.jl:425
 [3] read(cmd::Cmd, #unused#::Type{String})
   @ Base .\process.jl:434
 [4] (::OteraEngine.Template)(; tmp_init::Dict{String, String}, jl_init::Dict{String, Union{AbstractString, Number}})
   @ OteraEngine C:\Users\Nate\.julia\packages\OteraEngine\eW6hw\src\template.jl:100
 [5] top-level scope
   @ F:\Programming\otera-demo\main.jl:8
 [6] include(fname::String)
   @ Base.MainInclude .\client.jl:444
 [7] top-level scope
   @ REPL[4]:1
MommaWatasu commented 1 year ago

Thank you for your report. This issue was caused by the difference between Linux and WIndows. I fixed the bug and released the new version. Please upgrade and try again.

ndortega commented 1 year ago

Hi @MommaWatasu,

Thanks for taking a look at this is issue. I've pulled down your latest changes and am still running into some issues. Thankfully, no error is getting thrown but the output of the code block isn't getting interpolated inside the final string. Am I calling anything incorrectly? Thanks!

Here's the output:

julia> include("main.jl")
WARNING: replacing module Main.
  Activating environment at `F:\Programming\otera-demo\Project.toml`
. Hello OteraEngine!
Main.Main

And here is the code:

module Main 
using OteraEngine

txt = "```using Dates; now()```. Hello {{ usr }}!"
tmp = Template(txt, path = false)
init = Dict("usr"=>"OteraEngine")
output = tmp(tmp_init = init)

println(output)

end
ndortega commented 1 year ago

Hi @MommaWatasu,

Just wanted to bring up a couple more things I noticed when writing my own unit tests.

1.) Test number 4 has inconsistent spacing. There's additional tabs inside your own internal tests, specifically the closing body tag has the wrong level of indentation. This indicates that there is additional spacing getting implicitly added to the template files

image

This seems to be consistent across both our tests. Below is an example of how the test fails if the body tags are aligned properly, the test only passes when an additional level of indentation is applied to the closing body tag.


function otera(template::String; kwargs...)
    tmp = Template(template, path=isfile(template); kwargs...)
    return function(data::AbstractDict; template_kwargs...)
        tmp(tmp_init=data; template_kwargs...)
    end
end

function clean_output(result::String)
    # handles running on windows with carrige returns
    if occursin("\r\n", result)
        return replace(result, "\r\n" =>"\n")
    else 
        return result
    end
end

function remove_trailing_newline(s::String)::String
    if !isempty(s) && last(s) == '\n'
        return s[1:end-1]
    end
    return s
end

@testset "otera() from string" begin 

    template = """
    <html>
        <head><title>MyPage</title></head>
        <body>
            {% set name = "watasu" %}
            {% if name=="watasu" %}
            your name is {{ name }}, right?
            {% end %}
            {% for i in 1 : 10 %}
            Hello {{i}}
            {% end %}
            {% with age = 15 %}
            and your age is {{ age }}.
            {% end %}
        </body>
    </html>
    """ |> remove_trailing_newline

    expected_output = """
    <html>
        <head><title>MyPage</title></head>
        <body>
            your name is watasu, right?
            Hello 1
            Hello 2
            Hello 3
            Hello 4
            Hello 5
            Hello 6
            Hello 7
            Hello 8
            Hello 9
            Hello 10
            and your age is 15.
        </body>
    </html>
    """ |> remove_trailing_newline

    data = Dict("name" => "watasu")
    render = otera(template)
    result = render(data) |> clean_output
    @test result == expected_output

end

I don't want all these requests to come off as pedantic, I'm currently evaluating which templating engines I may want to integrate into Oxygen.jl and your package is one of them. I'm a fan of this package and want to see if we can get it to a place where I can add support for it.

MommaWatasu commented 1 year ago

Hi @ndortega .

I fixed the bugs you reported and released the v0.2.6. So now the jl code blocks work properly, and also the indentation is correct. And I will appreciate it if you would inform me the result that you test this.

ndortega commented 12 months ago

Hi @MommaWatasu ,

Thanks for your changes, they resolved the issue I was facing. On a related note, I've created the package extension for this package and wanted to get your input on the naming of the top-level function that exposes your library.

Right now it's just called otera, but I didn't know if this was good enough. Would you prefer one of the following?

Here's an example of it in use:

@testset "otera() combined tmp_init & jl_init test" begin 
    template = "```parse(Int, value) ^ 3```. Hello {{name}}!"
    expected_output = "27. Hello World!"
    render = otera(template)
    result = render(tmp_init=Dict("name" => "World"), jl_init=Dict("value" => "3"))
end

An below is the where it's defined https://github.com/ndortega/Oxygen.jl/blob/feature/templating-support/src/extensions/templating/oteraengine.jl

MommaWatasu commented 12 months ago

Hi @ndortega,

I’m glad that OteraEngine is used in your Oxygen. I think otera is good enough because it is short and simple. Additionally, as README shows, otera is temple in Japanese, so this is equal to temple(template). This represents the function exactly.

The only thing which I want you to do is to put the link of docs for OteraEngine in your document of otera.