Skip to content

Commit d766c22

Browse files
authored
feat: site assign (#20)
1 parent ca5217f commit d766c22

11 files changed

+82
-28
lines changed

README.md

+27-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ Documentation can be found at <https://hexdocs.pm/tableau>.
3131

3232
The examples in the README use the [Temple](https://github.com/mhanberg/temple) library to demonstrate that Tableau can be used with any markup language of your choice. You could easily use the builtin EEx, or use HEEx, Surface, or HAML.
3333

34+
### Layouts
35+
36+
Layouts are modules that use the `use Tableau.Layout` macro.
37+
38+
Layouts have assess to the `@site` and `@page` assign.
39+
40+
The `@site` assign contains your site's config.
41+
42+
The `@page` assign contains all the options passed to the `use Tableau.Page` macro.
43+
3444
```elixir
3545
defmodule MySite.RootLayout do
3646
use Tableau.Layout
@@ -47,6 +57,10 @@ defmodule MySite.RootLayout do
4757
meta http_equiv: "X-UA-Compatible", content: "IE=edge"
4858
meta name: "viewport", content: "width=device-width, initial-scale=1.0"
4959

60+
title do
61+
@page.some_assign
62+
end
63+
5064
link rel: "stylesheet", href: "/css/site.css"
5165
end
5266

@@ -77,11 +91,21 @@ end
7791

7892
#### Page
7993

94+
Pages are modules that use the `use Tableau.Page` macro.
95+
96+
Required options:
97+
98+
* `:layout` - which layout module to use.
99+
* `:permalink` - the permalink of the page
100+
101+
Any remaining options are arbitrary and will be available under the `@page` assign available to layout and page templates.
102+
80103
```elixir
81104
defmodule MySite.AboutPage do
82105
use Tableau.Page,
83106
layout: MySite.RootLayout,
84-
permalink: "/about"
107+
permalink: "/about",
108+
some_assign: "foo"
85109

86110
import Temple
87111

@@ -186,7 +210,8 @@ Other static assets can be copied into the "out" directory by placing them in an
186210
This directory can be configured.
187211

188212
```elixir
189-
config :tableau, :include, "static"
213+
config :tableau, :config,
214+
include_dir: "static"
190215
```
191216

192217
### Development

lib/mix/tasks/tableau.build.ex

+17-6
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ defmodule Mix.Tasks.Tableau.Build do
66
@moduledoc "Task to build the tableau site"
77
@shortdoc "Builds the site"
88

9-
@include_dir Application.compile_env(:tableau, :include, "extra")
9+
@config Application.compile_env(:tableau, :config, %{})
1010

1111
@impl Mix.Task
1212
def run(argv) do
13+
{:ok, config} = Tableau.Config.new(@config)
14+
site = %{config: config}
1315
Mix.Task.run("app.start", ["--preload-modules"])
1416

1517
{opts, _argv} = OptionParser.parse!(argv, strict: [out: :string])
@@ -19,7 +21,7 @@ defmodule Mix.Tasks.Tableau.Build do
1921
mods = :code.all_available()
2022

2123
for module <- pre_build_extensions(mods) do
22-
with :error <- module.run(%{site: %{}}) do
24+
with :error <- module.run(%{site: site}) do
2325
Logger.error("#{inspect(module)} failed to run")
2426
end
2527
end
@@ -28,8 +30,17 @@ defmodule Mix.Tasks.Tableau.Build do
2830
graph = Tableau.Graph.new(mods)
2931
File.mkdir_p!(out)
3032

31-
for mod <- Graph.vertices(graph), {:ok, :page} == Tableau.Graph.Node.type(mod) do
32-
content = Tableau.Document.render(graph, mod, %{site: %{}})
33+
pages =
34+
for mod <- Graph.vertices(graph), {:ok, :page} == Tableau.Graph.Node.type(mod) do
35+
{mod, Map.new(mod.__tableau_opts__() || [])}
36+
end
37+
38+
{mods, pages} = Enum.unzip(pages)
39+
40+
site = Map.put(site, :pages, pages)
41+
42+
for mod <- mods do
43+
content = Tableau.Document.render(graph, mod, %{site: site})
3344
permalink = mod.__tableau_permalink__()
3445
dir = Path.join(out, permalink)
3546

@@ -38,8 +49,8 @@ defmodule Mix.Tasks.Tableau.Build do
3849
File.write!(Path.join(dir, "index.html"), content)
3950
end
4051

41-
if File.exists?(@include_dir) do
42-
File.cp_r!(@include_dir, out)
52+
if File.exists?(config.include_dir) do
53+
File.cp_r!(config.include_dir, out)
4354
end
4455
end
4556

lib/tableau/config.ex

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
defmodule Tableau.Config do
2+
@moduledoc false
3+
4+
import Schematic
5+
6+
defstruct include_dir: "extra"
7+
8+
def new(config) do
9+
unify(schematic(), config)
10+
end
11+
12+
defp schematic do
13+
schema(__MODULE__, %{
14+
optional(:include_dir) => str()
15+
})
16+
end
17+
end

lib/tableau/document.ex

+3-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ defmodule Tableau.Document do
1010
quote do
1111
case unquote(inner_content) do
1212
[{module, page_assigns} | rest] ->
13-
module.template(Map.merge(page_assigns, %{inner_content: rest}))
13+
module.template(%{page: page_assigns, inner_content: rest})
1414

1515
[] ->
1616
nil
@@ -31,10 +31,9 @@ defmodule Tableau.Document do
3131
raise "Failed to find layout path for #{inspect(module)}"
3232
end
3333

34-
page_assigns = Map.new(module.__tableau_extra__() || [])
34+
page_assigns = Map.new(module.__tableau_opts__() || [])
3535
mods = for mod <- mods, do: {mod, page_assigns}
36-
new_assigns = Map.merge(page_assigns, %{inner_content: mods})
3736

38-
root.template(Map.merge(assigns, new_assigns))
37+
root.template(Map.merge(assigns, %{inner_content: mods, page: page_assigns}))
3938
end
4039
end

lib/tableau/page.ex

+5-4
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ defmodule Tableau.Page do
3232
@callback template(assigns()) :: template()
3333

3434
defmacro __using__(opts) do
35-
opts = Keyword.validate!(opts, [:layout, :permalink, extra: []])
35+
layout = Keyword.fetch!(opts, :layout)
36+
permalink = Keyword.fetch!(opts, :permalink)
3637

3738
quote do
3839
@behaviour unquote(__MODULE__)
3940

4041
def __tableau_type__, do: :page
41-
def __tableau_parent__, do: unquote(opts[:layout])
42-
def __tableau_permalink__, do: unquote(opts[:permalink])
43-
def __tableau_extra__, do: unquote(opts[:extra])
42+
def __tableau_parent__, do: unquote(layout)
43+
def __tableau_permalink__, do: unquote(permalink)
44+
def __tableau_opts__, do: unquote(opts)
4445
end
4546
end
4647
end

mix.exs

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ defmodule Tableau.MixProject do
3232
# Run "mix help deps" to learn about dependencies.
3333
defp deps do
3434
[
35+
{:ex_doc, ">= 0.0.0", only: :dev},
36+
{:file_system, "~> 0.2"},
3537
{:libgraph, "~> 0.16.0"},
3638
{:plug_cowboy, "~> 2.0"},
3739
{:plug_static_index_html, "~> 1.0"},
38-
{:file_system, "~> 0.2"},
39-
{:ex_doc, ">= 0.0.0", only: :dev},
40+
{:schematic, "~> 0.3"},
4041
# {:yaml_front_matter, "~> 1.0"},
4142
# {:jason, "~> 1.4"},
42-
# {:toml, "~> 0.6.2"},
4343
# {:req, "~> 0.3", only: :test},
4444
# {:bypass, "~> 2.0", only: :test},
4545
# {:earmark, "~> 1.4"},

mix.lock

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
1818
"plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"},
1919
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
20-
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
20+
"schematic": {:hex, :schematic, "0.3.0", "936df3904d0d17de543530fbe8e7ea8f7e3b7f0a5da0fedfa85440a2ca77bdfc", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bd6dafb8792f77e4b321ba529572bd97792a3a6b7cec75d736b7ecc4031dff9e"},
21+
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
2122
}

test/mix/tasks/tableau.build_test.exs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ defmodule Mix.Tasks.Tableau.BuildTest.About do
2424
def __tableau_type__, do: :page
2525
def __tableau_parent__, do: InnerLayout
2626
def __tableau_permalink__, do: "/about"
27-
def __tableau_extra__, do: []
27+
def __tableau_opts__, do: []
2828

2929
EEx.function_from_string(
3030
:def,
@@ -46,7 +46,7 @@ defmodule Mix.Tasks.Tableau.BuildTest.Index do
4646
def __tableau_type__, do: :page
4747
def __tableau_parent__, do: InnerLayout
4848
def __tableau_permalink__, do: "/"
49-
def __tableau_extra__, do: []
49+
def __tableau_opts__, do: []
5050

5151
EEx.function_from_string(
5252
:def,

test/tableau/document_test.exs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ defmodule Tableau.DocumentTest.About do
66
def __tableau_type__, do: :page
77
def __tableau_parent__, do: InnerLayout
88
def __tableau_permalink__, do: "/about"
9-
def __tableau_extra__, do: [yo: "lo"]
9+
def __tableau_opts__, do: [yo: "lo"]
1010

1111
EEx.function_from_string(
1212
:def,
1313
:template,
1414
~g'''
15-
<div id="<%= @yo %>">
15+
<div id="<%= @page.yo %>">
1616
hi
1717
</div>
1818
'''html,
@@ -28,7 +28,7 @@ defmodule Tableau.DocumentTest.Index do
2828
def __tableau_type__, do: :page
2929
def __tableau_parent__, do: InnerLayout
3030
def __tableau_permalink__, do: "/"
31-
def __tableau_extra__, do: []
31+
def __tableau_opts__, do: []
3232

3333
EEx.function_from_string(
3434
:def,

test/tableau/graph/node_test.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule Tableau.Graph.NodeTest do
99
def __tableau_type__, do: :page
1010
def __tableau_parent__, do: Layout
1111
def __tableau_permalink__, do: "/about"
12-
def __tableau_extra__, do: []
12+
def __tableau_opts__, do: []
1313

1414
def template(_) do
1515
""

test/tableau/graph_test.exs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule Tableau.GraphTest do
77
def __tableau_type__, do: :page
88
def __tableau_parent__, do: InnerLayout
99
def __tableau_permalink__, do: "/about"
10-
def __tableau_extra__, do: []
10+
def __tableau_opts__, do: []
1111

1212
def template(_), do: ""
1313
end
@@ -18,7 +18,7 @@ defmodule Tableau.GraphTest do
1818
def __tableau_type__, do: :page
1919
def __tableau_parent__, do: RootLayout
2020
def __tableau_permalink__, do: "/about"
21-
def __tableau_extra__, do: []
21+
def __tableau_opts__, do: []
2222
def template(_), do: ""
2323
end
2424

0 commit comments

Comments
 (0)