Using tags from Pluto notebook metadata #1010
-
I have a site that I generate using Franklin.jl which lists links to HTML formatted pluto notebooks stored in <meta property="og:article:tag" content='notebook'> I was wondering how to make it so the generated tag list in Franklin.jl includes these tags? For example, this is what I have so far. In the using Gumbo
using Cascadia
using Glob
function parse_tags_from_html(filepath::String)
html_content = read(filepath, String)
html = parsehtml(html_content)
tags_selector = Selector("meta[property='og:article:tag']")
tags_nodes = eachmatch(tags_selector, html.root)
return map(x -> get(x.attributes, "content", ""), tags_nodes)
end
function hfun_get_tags()
tags = Set{String}()
# Retrieve tags from HTML Puto notebooks
html_files = glob("*.html", "./_assets/notebooks")
for html_file in html_files
file_tags = parse_tags_from_html(html_file)
union!(tags, file_tags)
end
# Sort and collect the tags
sorted_tags = sort(collect(tags))
# Generate the HTML for the tag list
html_buffer = IOBuffer()
for tag in sorted_tags
write(
html_buffer,
"""
<li class="tag-item">
<a class="tag-link" href="/tag/$(tag)/">$(tag)</a>
</li>
"""
)
end
return String(take!(html_buffer))
end
function hfun_custom_taglist()
# Add this loop to process the HTML Pluto.jl notebooks
html_files = glob("*.html", "./_assets/notebooks")
# Grab all tag names first from the notebooks
tags = []
for html_file in html_files
push!(tags,parse_tags_from_html(html_file)...)
end
# Process the tags and integrate them into the tag list as needed
# For example, adding the tags to the existing rpaths list
rpaths = []
for html_file in html_files
for tag_from_html in parse_tags_from_html(html_file)
if tag_from_html in unique(tags)
push!(rpaths, html_file)
end
end
end
c = IOBuffer()
write(c, "<ul>")
for rpath in rpaths
title = let
path = split(rpath, '/')[end]
name, _ = split(path, '.')
name
end
write(c, "<li><a href=\"/$rpath/\">$title.jl</a></li>")
end
write(c, "</ul>")
return String(take!(c))
end I then use <!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/css/franklin.css">
<link rel="stylesheet" href="/css/basic.css">
<title>Tag: {{fill fd_tag}}</title>
</head>
<body>
{{insert header.html}}
<div class="{{div_content}}">
<h1>Tag: {{fill fd_tag}}</h1>
{{custom_taglist}}
{{insert page_foot.html}}
</div>
</body>
</html> The issue is I'm not seeing any Any help is much appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 8 replies
-
Nice, I think there's three things I'd change:
Code to push to Franklin.set_var!(Franklin.GLOBAL_VARS, "fd_page_tags", Franklin.DTAG((rpath => tags,)); check=false)
This requires a change; I've added on a branch
You can try that by adding
If it doesn't work, it might be good to point me to a simple repo where I can try playing with the code a bit to hopefully get stuff to work If it does work, let me know and I can merge that branch into master and do a patch release. |
Beta Was this translation helpful? Give feedback.
-
Nice, it looks like the types are a bit different, extracting from your paste:
but
Could you check what your What is used internally is:
So what I'd do is check that your |
Beta Was this translation helpful? Give feedback.
-
sorry I couldn't look into this earlier, could you update the branch with your work so I could start from that? |
Beta Was this translation helpful? Give feedback.
-
@stefanbringuier kindly update to get the latest commit on
this is the core of the error that remained. Modifications in
I hope this sets you up to get this working fine! sorry it was a bit of a mess... Note:
using Gumbo
using Cascadia
using Glob
using Franklin
function hfun_bar(vname)
val = Meta.parse(vname[1])
return round(sqrt(val), digits=2)
end
function hfun_m1fill(vname)
var = vname[1]
return pagevar("index", var)
end
function lx_baz(com, _)
# keep this first line
brace_content = Franklin.content(com.braces[1]) # input string
# do whatever you want here
return uppercase(brace_content)
end
get_html_files() = vcat(glob("*.html", "./_assets/notebooks"), glob("*.html", "./_assets/prerendered_notebooks"))
nb_name(rpath) = begin
file = split(rpath, '/')[end]
split(file,'.')[1]
end
function parse_tags_from_html(filepath::String)
html_content = read(filepath, String)
html = parsehtml(html_content)
tags_selector = Selector("meta[property='og:article:tag']")
tags_nodes = eachmatch(tags_selector, html.root)
return map(x -> get(x.attributes, "content", ""), tags_nodes)
end
function parse_title_from_html(filepath::String)
html_content = read(filepath, String)
html = parsehtml(html_content)
# Select the title element using Cascadia
title_selector = Selector("head title")
title_element = eachmatch(title_selector, html.root)
# Extract the title text
if !isempty(title_element)
title = nodeText(title_element[1])
else
title = ""
end
return title
end
function hfun_taglist_pluto()::String
tag = locvar(:fd_tag)::String
c = IOBuffer()
write(c, "<ul>")
rpaths = globvar("fd_tag_pages")[tag]
sorter(p) = begin
pvd = pagevar(p, "date")
if isnothing(pvd)
return Date(Dates.unix2datetime(stat(p).ctime))
end
return pvd
end
sort!(rpaths, by=sorter, rev=true)
for rpath in rpaths
title = parse_title_from_html(replace(rpath, "assets" => "_assets"))
if isempty(title)
title = splitext(splitpath(rpath)[end])[1]
# title = join(nb_name(rpath),".jl")
end
url = get_url(rpath)
write(c, "<li><a href=\"/$rpath\">$title</a></li>")
end
write(c, "</ul>")
return String(take!(c))
end
"""
Working!
Add tags to Franklin variable.
"""
function hfun_get_pluto_tags()
html_files = get_html_files()
# Grab all tag names first
tags = []
rpaths = []
for html_file in html_files
push!(rpaths,replace(html_file, "_assets" => "assets"))
itag = Franklin.refstring.(parse_tags_from_html(html_file))
push!(tags, itag)
end
frmt_tags = Franklin.DTAG(zip(rpaths,map(Set,tags)))
Franklin.set_var!(Franklin.GLOBAL_VARS, "fd_page_tags", frmt_tags; check=false)
return ""
end
"""
Use to add tags on side of page.
"""
function hfun_get_tags()
tags = Set{String}()
html_files = get_html_files()
for html_file in html_files
file_tags = parse_tags_from_html(html_file)
union!(tags, file_tags)
end
# Sort and collect the tags
sorted_tags = sort(collect(tags))
# Generate the HTML for the tag list
html_buffer = IOBuffer()
for tag in sorted_tags
frmt_tag = join([titlecase(word) for word in split(tag)], " ")
write(
html_buffer,
"""
<li class="tag-item">
<a class="tag-link" href="/tag/$(Franklin.refstring(tag))/">$(frmt_tag)</a>
</li>
"""
)
end
return String(take!(html_buffer))
end
|
Beta Was this translation helpful? Give feedback.
@stefanbringuier kindly update to get the latest commit on
tags-i1010
. The attachedutils.jl
file has a few modifications and should work. A few notes:rpath
is the relative path to the root of the website in unix/url format. For markdown given that a pagefoo.md
will eventually lead to afoo/index.html
which will be accessed atfoo/
, the rpath isfoo
; for an assets page however this is not the case, and so the rpath contains the extension, therefore my logic of adding*.html
was wrong (ended up checking iffile.html.html
existed)this is the core of the error that remained.
Modifications in
utils.jl
:sorter(p) = begin ...
logic inhfun_taglist_pluto
should…