/Cobweb.jl

🕸️ Cobble together web content in Julia

Primary LanguageJuliaOtherNOASSERTION

CI codecov

🕸️ Cobweb

A Julia package for cobbling together web pages.

Features

  • Open any "text/html"-representable object in your browser with Page(x) or Tab(x).
  • Nice syntax for writing HTML: Cobweb.h.<tag>(children...; attributes...).
    • Cobweb.h.<TAB> autocompletes HTML5 tags for you.
  • Great for templating/building your own text/html representations of Julia objects.



🚀 Quickstart

using Cobweb: h, Page

page = h.html(
    h.head(
        h.meta(charset="UTF-8"),
        h.meta(name="viewport", content="width=device-width, initial-scale=1.0"),
        h.title("Page Title")
    ),
    h.body(
        h.h1("This is my page title."),
        h.p("This is a paragraph."),
        h.button("Click Me for an alert!", onclick="buttonClicked()"),
        Cobweb.Javascript("const buttonClicked = () => alert('This button was clicked!')"),
    )
)

Page(page)  # Open in browser


✨ Creating Nodes with Cobweb.h

  • Syntax is similar to HTML:
using Cobweb: h

h.div."some-class"(
    h.p("This is a child."),
    h.div("So is this.")
)
# <div class="some-class">
#   <p>This is a child.</p>
#   <div>So is this.</div>
# </div>
  • Any Union{AbstractString, Symbol, Number} children will be inserted verbatim.
  • Everything else will use the MIME"text/html" representation.
using Markdown

h.div(
    "Here is markdown:",
    Markdown.parse("""
    - This \"just work\"™s!
    """)
)
# <div>
#   Here is markdown:
#   <div class="markdown">
#     <ul>
#       <li>
#         <p>This &quot;just work&quot;™s&#33;</p>
#       </li>
#     </ul>
#   </div>
# </div>


Cobweb.h Syntax Summary:

  • h(tag::String) creates a Cobweb.Node
  • h.<tag> is simplified syntax for h(tag) and you can tab-autocomplete HTML5 tags.
julia> node = Cobweb.h.div
# <div></div>
  • Calling a Node creates a copy with the specified changes.

    • Positional arguments add children:
    julia> node = node("child")
    # <div>child</div>
    • Keyword arguments add attributes:
    julia> node = node(; id = "myid", class="myclass")
    # <div id="myid"></div>
  • There's convenient syntax for appending classes as well:

julia> node = node."append classes"
# <div id="myid" class="myclass append classes">child</div>

Attributes

  • Nodes act like a mutable NamedTuple when it comes to attributes:
node = Cobweb.h.div

node.id = "my_id"

node
# <div id="my_id"></div>

Children

  • Nodes act like a Vector when it comes to children:
node = Cobweb.h.div

push!(node, Cobweb.h.h1("Hello!"))

node[:]
# 1-element Vector{Any}:
#  <h1>Hello!</h1>


The @h macro

This is a simple utility macro that replaces each HTML5 tag x with Cobweb.h.x for a cleaner syntax:

Cobweb.@h begin
    div."text-center text-xl"(
        h4("This generates an h4 node!"),
        p("This is a paragraph"),
        div("Here is a div.")
    )
end
# <div class="text-center text-xl">
#   <h4>This generates an h4 node!</h4>
#   <p>This is a paragraph</p>
#   <div>Here is a div.</div>
# </div>


📄 Writing Javascript with Cobweb.Javascript

  • Simple wrapper around a String that gets printed verbatim with MIME"text/javascript".
  • The following create the same result when represented with MIME"text/html":
    • h.script("alert('hi')")
    • Cobweb.Javascript("alert('hi')")


📄 Writing CSS with Cobweb.CSS

You can create Cobweb.CSS from any nested AbstractDict, e.g. selector => (property => value).

using EasyConfig
using Cobweb: h

style = Config()
style.p."font-family" = "Arial"
style."p.upper"."text-transform" = "uppercase"
style."p.blue".color = "blue"

css = Cobweb.CSS(style)
# p {
#   font-family: Arial;
# }
# p.upper {
#   text-transform: uppercase;
# }
# p.blue {
#   color: blue;
# }

page = h.html(
    h.head(css),
    h.body(
        h.p("this is uppercased and blue in an Arial font.", class="upper blue")
    )
)

Cobweb.Page(page)


Parsing HTML to Cobweb.Node

using Downloads, Cobweb

Cobweb.read(Downloads.download("https://juliacomputing.github.io/Cobweb.jl/"))


Attribution