Packages
arctic
4.0.0
11.0.10
11.0.9
11.0.8
11.0.7
11.0.6
11.0.6-z6
11.0.6-z5
11.0.6-z4
11.0.6-z3
11.0.6-z2
11.0.6-z1
11.0.6-gamma
11.0.6-delta
11.0.6-beta
11.0.6-alpha
11.0.5
11.0.4
11.0.3
11.0.2
11.0.1
11.0.0
11.0.0-alpha5
11.0.0-alpha4
11.0.0-alpha3
11.0.0-alpha2
11.0.0-alpha
10.0.1
10.0.0
10.0.0-alpha2
10.0.0-alpha
9.0.5
9.0.4
9.0.3
9.0.2
9.0.0
8.0.0
7.0.0
6.0.0
5.0.0
4.0.0
3.0.0
2.0.0
1.0.1
1.0.0
A friendly web framework for fast response times and a lightweight or serverless backend, written in Gleam!
Current section
Files
Jump to
Current section
Files
src/build/build.gleam
import arctic.{
type Collection, type Config, type Page, type ProcessedCollection,
ProcessedCollection,
}
import gleam/list
import gleam/option.{None, Some}
import gleam/result.{map_error}
import lustre/ssg
import simplifile
import snag.{type Result}
fn read_collection(collection: Collection) -> Result(List(Page)) {
use paths <- result.try(
simplifile.get_files(in: collection.directory)
|> map_error(fn(err) {
snag.new(
"couldn't get files in `"
<> collection.directory
<> "` ("
<> simplifile.describe_error(err)
<> ")",
)
}),
)
list.try_fold(over: paths, from: [], with: fn(so_far, path) {
use content <- result.try(
map_error(simplifile.read(path), fn(err) {
snag.new(
"could not load file `"
<> path
<> "` ("
<> simplifile.describe_error(err)
<> ")",
)
}),
)
use p <- result.try(collection.parse(content))
Ok([p, ..so_far])
})
|> result.map(list.reverse)
}
fn process(collections: List(Collection)) -> Result(List(ProcessedCollection)) {
use rest, collection <- list.try_fold(over: collections, from: [])
use pages_unsorted <- result.try(read_collection(collection))
let pages = list.sort(pages_unsorted, fn(p, q) { p.above(q) })
Ok([ProcessedCollection(collection:, pages:), ..rest])
}
pub fn build(config: Config, collections: List(Collection)) -> Result(Nil) {
use processed_collections <- result.try(process(collections))
use ssg_config <- result.try(
ssg.new("site")
|> ssg.use_index_routes()
|> ssg.add_static_route("/", config.render_home(processed_collections))
|> list.fold(over: config.main_pages, with: fn(ssg_config, page) {
ssg.add_static_route(ssg_config, "/" <> page.id, page.html)
})
|> list.try_fold(
over: processed_collections,
with: fn(ssg_config, processed) {
let ssg_config2 = case processed.collection.index {
Some(render) ->
ssg.add_static_route(
ssg_config,
"/" <> processed.collection.directory,
render(processed.pages),
)
None -> ssg_config
}
list.fold(
over: processed.pages,
from: ssg_config2,
with: fn(s, p: Page) {
ssg.add_static_route(
s,
"/" <> processed.collection.directory <> "/" <> p.id,
p.html,
)
},
)
|> Ok
},
),
)
use _ <- result.try(
ssg.build(ssg_config)
|> map_error(fn(err) {
case err {
ssg.CannotCreateTempDirectory(file_err) ->
snag.new(
"couldn't create temp directory ("
<> simplifile.describe_error(file_err)
<> ")",
)
ssg.CannotWriteStaticAsset(file_err, path) ->
snag.new(
"couldn't put asset at `"
<> path
<> "` ("
<> simplifile.describe_error(file_err)
<> ")",
)
ssg.CannotGenerateRoute(file_err, path) ->
snag.new(
"couldn't generate `"
<> path
<> "` ("
<> simplifile.describe_error(file_err)
<> ")",
)
ssg.CannotWriteToOutputDir(file_err) ->
snag.new(
"couldn't move from temp directory to output directory ("
<> simplifile.describe_error(file_err)
<> ")",
)
ssg.CannotCleanupTempDir(file_err) ->
snag.new(
"couldn't remove temp directory ("
<> simplifile.describe_error(file_err)
<> ")",
)
}
}),
)
use _ <- result.try(
simplifile.create_directory("site/public")
|> map_error(fn(err) {
snag.new(
"couldn't create directory `site/public` ("
<> simplifile.describe_error(err)
<> ")",
)
}),
)
use _ <- result.try(
simplifile.copy_directory(at: "public", to: "site/public")
|> map_error(fn(err) {
snag.new(
"couldn't copy `public` to `site/public` ("
<> simplifile.describe_error(err)
<> ")",
)
}),
)
use _ <- result.try(
simplifile.create_file("site/public/feed.rss")
|> map_error(fn(err) {
snag.new(
"couldn't create file `site/public/feed.rss` ("
<> simplifile.describe_error(err)
<> ")",
)
}),
)
list.try_each(over: processed_collections, with: fn(processed) {
case processed.collection.rss {
Some(render) ->
simplifile.write(
contents: render(processed.pages),
to: "site/public/feed.rss",
)
|> map_error(fn(err) {
snag.new(
"couldn't write to `site/public/feed.rss` ("
<> simplifile.describe_error(err)
<> ")",
)
})
None -> Ok(Nil)
}
})
}