diff --git a/Manifest.toml b/Manifest.toml index d28e6ba0..8eac90ad 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,5 +1,8 @@ # This file is machine-generated - editing it directly is not advised +[[ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" + [[Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" @@ -17,16 +20,37 @@ git-tree-sha1 = "9c209fb7536406834aa938fb149964b985de6c83" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" version = "0.7.1" +[[CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" + [[ConcurrentUtilities]] deps = ["Serialization", "Sockets"] git-tree-sha1 = "b306df2650947e9eb100ec125ff8c65ca2053d30" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" version = "2.1.1" +[[DataAPI]] +git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.15.0" + +[[DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + [[Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" + +[[FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + [[HTTP]] deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] git-tree-sha1 = "69182f9a2d6add3736b7a06ab6416aafdeec2196" @@ -37,6 +61,11 @@ version = "1.8.0" deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + [[JLLWrappers]] deps = ["Preferences"] git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1" @@ -49,9 +78,29 @@ git-tree-sha1 = "84b10656a41ef564c39d2d477d7236966d2b5683" uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" version = "1.12.0" +[[LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" + +[[LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" + +[[LibGit2]] +deps = ["Base64", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" + [[Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +[[LinearAlgebra]] +deps = ["Libdl", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" @@ -86,9 +135,19 @@ uuid = "a63ad114-7e13-5084-954f-fe012c677804" [[MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +[[Mustache]] +deps = ["Printf", "Tables"] +git-tree-sha1 = "821e918c170ead5298ff84bffee41dd28929a681" +uuid = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" +version = "1.0.17" + [[NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +[[OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" + [[OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] git-tree-sha1 = "7fb975217aea8f1bb360cf1dde70bad2530622d2" @@ -101,12 +160,27 @@ git-tree-sha1 = "6cc6366a14dbe47e5fc8f3cbe2816b1185ef5fc4" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" version = "3.0.8+0" +[[OrderedCollections]] +git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.2" + +[[OteraEngine]] +deps = ["Pkg", "TOML"] +git-tree-sha1 = "aba81eddd54cc8de55d88341e1ee852e914c2db3" +uuid = "b2d7f28f-acd6-4007-8b26-bc27716e5513" +version = "0.2.4" + [[Parsers]] deps = ["Dates", "SnoopPrecompile"] git-tree-sha1 = "478ac6c952fddd4399e71d4779797c538d0ff2bf" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" version = "2.5.8" +[[Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" + [[Preferences]] deps = ["TOML"] git-tree-sha1 = "47e5f437cc0e7ef2ce8406ce1e7e24d44915f88d" @@ -117,8 +191,12 @@ version = "1.3.0" deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +[[REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + [[Random]] -deps = ["Serialization"] +deps = ["SHA", "Serialization"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[RelocatableFolders]] @@ -163,6 +241,22 @@ version = "1.10.0" deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +[[TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "a1f34829d5ac0ef499f6d84428bd6b4c71f02ead" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.0" + +[[Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" + [[Test]] deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" @@ -188,3 +282,15 @@ uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" [[Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" + +[[libblastrampoline_jll]] +deps = ["Artifacts", "Libdl", "OpenBLAS_jll"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" + +[[nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" + +[[p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" diff --git a/Project.toml b/Project.toml index 1650adff..87b8bb99 100644 --- a/Project.toml +++ b/Project.toml @@ -1,13 +1,15 @@ name = "Oxygen" uuid = "df9a0d86-3283-4920-82dc-4555fc0d1d8b" authors = ["Nathan Ortega "] -version = "1.2" +version = "1.2.0" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3" JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" MIMEs = "6c6e2e6c-3030-632d-7369-2d6c69616d65" +Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70" +OteraEngine = "b2d7f28f-acd6-4007-8b26-bc27716e5513" RelocatableFolders = "05181044-ff0b-4ac5-8273-598c1e38db00" Sockets = "6462fe0b-24de-5631-8697-dd941f90decc" diff --git a/README.md b/README.md index d3b56337..91e36bcd 100644 --- a/README.md +++ b/README.md @@ -767,3 +767,41 @@ Returns the body of a request as a binary file (returns a vector of `UInt8`s) | `classtype` | `struct` | A struct to deserialize a JSON object into | Deserialize the body of a request into a julia struct + + +### Working with Basic Templating +This section only gives a very quick introduction into how to use Jinja2-Like syntax with Oxygen.jl. +Our templating engine of choice can either be Mustache.jl via `render_html()` or OteraEngine.jl via `render_template()`. This is a very basic implementation and hopefully will be improved with more features. + +With these we can pass data from the backend to our frontend html files as below + +```julia +using Oxygen +using HTTP + +@get "/blog/{title}" function(req::HTTP.Request,title::String) + mylist = [3,5,1] + context = Dict("title" => uppercase(title),"mylist" => mylist) + return render_template("blog.html", context, status=200) +end + +serve() + +``` +This provides the option of using `{{}}` or `{% %}` to render variables from our context or Julia code. + +```html + +
+

Blog List

+

{{ title }}

+
+ {% for i in mylist %} +
    +
  • Hello {{i}} {{ title }}
  • +
+ {% end %} +
+
+ +``` \ No newline at end of file diff --git a/src/Oxygen.jl b/src/Oxygen.jl index 589d0ebb..bc1c35b7 100644 --- a/src/Oxygen.jl +++ b/src/Oxygen.jl @@ -14,5 +14,5 @@ export @get, @post, @put, @patch, @delete, @route, @cron, redirect, queryparams, binary, text, json, html, file, configdocs, mergeschema, setschema, getschema, router, enabledocs, disabledocs, isdocsenabled, starttasks, stoptasks, - resetstate, startcronjobs, stopcronjobs + resetstate, startcronjobs, stopcronjobs, render_html, render_template end \ No newline at end of file diff --git a/src/util.jl b/src/util.jl index f3f67aa1..d6e85fb4 100644 --- a/src/util.jl +++ b/src/util.jl @@ -2,6 +2,8 @@ module Util using HTTP using JSON3 using Dates +using OteraEngine +using Mustache export countargs, recursive_merge, parseparam, queryparams, html, redirect @@ -116,5 +118,58 @@ function redirect(path::String; code = 307) :: HTTP.Response return HTTP.Response(code, ["Location" => path]) end +""" + render_html(html_file::String,context::Dict) + + render html files with or without context data using '{{}}' in the html file +""" +function render_html(html_file::String ,context::Dict = Dict(); status=200, headers = ["Content-Type" => "text/html; charset=utf-8"]) :: HTTP.Response + is_context_empty = isempty(context) === true + # Return the raw HTML content as the response body without context + if is_context_empty + io = open(html_file, "r") do file + read(file, String) + end + template = io |> String + else + # Render the Mustache template with the provided context + io = open(html_file, "r") do file + read(file, String) + end + template = String(Mustache.render(io, context)) + end + + return HTTP.Response(status, headers, body= template) +end + + +""" + render_template(html_file::String,context::Dict) + + render html files with or without context data using Jinja Like syntax such as + '{{}}'or {% %} in the html file. Allows support for variables and Julia code in html +""" +function render_template(html_file::String ,context::Dict = Dict(); status=200, headers = ["Content-Type" => "text/html; charset=utf-8"]) :: HTTP.Response + is_context_empty = isempty(context) === true + # Return the raw HTML content as the response body without context + if is_context_empty + io = open(html_file, "r") do file + read(file, String) + end + template = io |> String + else + # Render using OteraEngine template with the provided context + io = open(html_file, "r") do file + read(file, String) + end + txt = io |> String + tmp = Template(txt, path = false) + template = tmp(tmp_init = context) + end + + return HTTP.Response(status, headers, body= template) +end + + end \ No newline at end of file