basic site
This commit is contained in:
parent
e99be95ce6
commit
a4337b3514
8 changed files with 207 additions and 2 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
test_template
|
||||
1
lib.typ
1
lib.typ
|
|
@ -1 +0,0 @@
|
|||
|
||||
7
lib/custom_html.typ
Normal file
7
lib/custom_html.typ
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#let meta-og(property: "", content: "") = {
|
||||
// "property" attr is not supported by html.meta ?
|
||||
html.elem("meta", attrs: (property: property, content: content))
|
||||
}
|
||||
|
||||
#let site-wrapper = html.elem.with("site-wrapper")
|
||||
#let site-container = html.elem.with("site-container")
|
||||
30
lib/html_body.typ
Normal file
30
lib/html_body.typ
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#import "./custom_html.typ" as chtml
|
||||
|
||||
/// Make the body of the webpage
|
||||
#let html_body(
|
||||
/// The visible header of the page
|
||||
header: [],
|
||||
/// Logo of the site, must be an url (TODO)
|
||||
logo,
|
||||
/// Logo alt-text
|
||||
logo_alt,
|
||||
body
|
||||
) = {
|
||||
html.body({
|
||||
chtml.site-wrapper({
|
||||
chtml.site-container({
|
||||
html.header(style: "display: flex; flex-wrap: wrap-reverse;", {
|
||||
html.hgroup({
|
||||
header
|
||||
})
|
||||
// typst `image` function embed the image in the html, which is not great,
|
||||
// and logo is also used for icon, so it's necessarily an url
|
||||
if logo != none {
|
||||
html.img(src: logo, alt: logo_alt, height: 100) // TODO: height bad
|
||||
}
|
||||
})
|
||||
body
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
103
lib/html_head.typ
Normal file
103
lib/html_head.typ
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#import "./custom_html.typ" as chtml
|
||||
|
||||
/// Generate the html <head> element for the page.
|
||||
#let html_head(
|
||||
/// Page url,
|
||||
url,
|
||||
/// Title of the page
|
||||
title,
|
||||
/// Path to the icon (TODO: /!\ must be an url, typst image not yet supported)
|
||||
icon,
|
||||
/// Type of the page for open-graph data
|
||||
og-type: "website",
|
||||
/// Name of the site for metadata of the page
|
||||
site-name: none,
|
||||
/// Description of the site for metadata #TODO default to document.description
|
||||
description: none,
|
||||
/// Author of the site for metadata #TODO default to document.author
|
||||
author: none,
|
||||
/// Additional stylesheet for the page: must be a list of url
|
||||
stylesheets: (),
|
||||
/// List of related sites for metadata
|
||||
me-links: (),
|
||||
) = {
|
||||
html.head({
|
||||
html.meta(charset: "utf-8")
|
||||
html.title(title)
|
||||
// html.meta(http-equiv: "Content-Language", content: "en") Obsolet, now use the html tag attr "lang" instead
|
||||
|
||||
// The width=device-width part sets the width of the page to follow the screen-width of the device (which will vary depending on the device).
|
||||
// The initial-scale=1.0 part sets the initial zoom level when the page is first loaded by the browser.
|
||||
html.meta(name: "viewport", content: "width=device-width, initial-scale=1.0")
|
||||
|
||||
// Only set the Referer header for out request to the same origin
|
||||
html.meta(name: "referrer", content: "same-origin")
|
||||
|
||||
if icon != none {
|
||||
html.link(rel: "icon", type: "image/png", href: icon)
|
||||
}
|
||||
|
||||
// Open Graph (https://ogp.me/), used by social media for link previsualisation
|
||||
chtml.meta-og(property: "og:title", content: repr(title))
|
||||
chtml.meta-og(property: "og:type", content: og-type)
|
||||
chtml.meta-og(property: "og:url", content: url)
|
||||
if icon != none {
|
||||
chtml.meta-og(property: "og:image", content: icon) // TODO: right now the logo need to be the full URL
|
||||
}
|
||||
if site-name != none {
|
||||
chtml.meta-og(property: "og:site_name", content: site-name)
|
||||
}
|
||||
if description != none {
|
||||
chtml.meta-og(property: "og:description", content: description)
|
||||
}
|
||||
|
||||
// Check https://www.w3schools.com/tags/att_link_rel.asp for other interesting link rel
|
||||
for stylesheet in stylesheets {
|
||||
html.link(rel: "stylesheet", type: "text/css", href: stylesheet)
|
||||
}
|
||||
for me-link in me-links {
|
||||
html.elem("link", attrs: (rel: "me", href: me-link))
|
||||
}
|
||||
if description != none {
|
||||
html.meta(name: "description", content: description)
|
||||
}
|
||||
if author != none {
|
||||
html.meta(name: "author", content: author)
|
||||
}
|
||||
|
||||
```raw-css
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
&:has(#theme-light:checked) {
|
||||
color-scheme: light;
|
||||
}
|
||||
&:has(#theme-dark:checked) {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
--color-border: light-dark(#414868, #414868);
|
||||
}
|
||||
site-wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
|
||||
site-container {
|
||||
width: 1050px;
|
||||
padding: 0 20px;
|
||||
|
||||
header {
|
||||
// display: flex
|
||||
// flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px 5px;
|
||||
border-bottom: solid 1px var(--color-border);
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
})
|
||||
}
|
||||
4
lib/html_utils.typ
Normal file
4
lib/html_utils.typ
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#let html_show(body) = {
|
||||
show raw.where(lang: "raw-css"): it => html.style(it.text)
|
||||
body
|
||||
}
|
||||
61
lib/main.typ
Normal file
61
lib/main.typ
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#import "./html_head.typ": html_head
|
||||
#import "./html_body.typ": html_body
|
||||
#import "./html_utils.typ": html_show
|
||||
|
||||
|
||||
/// Mail template function
|
||||
#let webpage(
|
||||
/// Page url
|
||||
url,
|
||||
/// Page logo, also used for icon, so it *needs* to be path (TODO: fix when typst support multi-file out)
|
||||
logo,
|
||||
/// Alt-text for the log
|
||||
logo-alt,
|
||||
/// Title of the page, default to document.title
|
||||
title: none,
|
||||
/// Page header
|
||||
header: [],
|
||||
/// Use only for html 'lang' attribute.
|
||||
lang: "en",
|
||||
//-- <head> only args --
|
||||
/// Type of the page for open-graph data
|
||||
og-type: "website",
|
||||
/// Name of the site for metadata of the page
|
||||
site-name: none,
|
||||
/// Description of the site for metadata #TODO default to document.description
|
||||
description: none,
|
||||
/// Author of the site for metadata #TODO default to document.author
|
||||
author: none,
|
||||
/// Additional stylesheet for the page: must be a list of url
|
||||
stylesheets: (),
|
||||
/// List of related sites for metadata
|
||||
me-links: (),
|
||||
//-- Body --
|
||||
/// Body of the page
|
||||
body
|
||||
) = {
|
||||
show: html_show
|
||||
|
||||
if title == none {
|
||||
title = context document.title
|
||||
}
|
||||
html.html(lang: lang, {
|
||||
html_head(
|
||||
url,
|
||||
title,
|
||||
logo,
|
||||
og-type: og-type,
|
||||
site-name: site-name,
|
||||
description: description,
|
||||
author: author,
|
||||
stylesheets: stylesheets,
|
||||
me-links: me-links
|
||||
)
|
||||
html_body(
|
||||
logo,
|
||||
logo-alt,
|
||||
header: header,
|
||||
body
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "template-web"
|
||||
version = "0.0.1"
|
||||
entrypoint = "lib.typ"
|
||||
entrypoint = "lib/main.typ"
|
||||
authors = ["Jean-Marie 'Histausse' Mineau <tyweb-template-3ebc@jean-marie.mineau.eu>"]
|
||||
license = "MIT"
|
||||
description = "A typst template for web."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue