fix: templates are not copied automatically to projects
This commit is contained in:
@@ -6,7 +6,6 @@ defmodule BDS.Projects do
|
||||
alias BDS.Persistence
|
||||
alias BDS.Projects.Project
|
||||
alias BDS.Repo
|
||||
alias BDS.StarterTemplates
|
||||
alias BDS.Slug
|
||||
alias BDS.Templates
|
||||
|
||||
@@ -59,7 +58,6 @@ defmodule BDS.Projects do
|
||||
})
|
||||
|> Repo.insert!()
|
||||
|
||||
:ok = StarterTemplates.install(project)
|
||||
{:ok, _templates} = Templates.rebuild_templates_from_files(project.id)
|
||||
project
|
||||
end)
|
||||
@@ -94,7 +92,6 @@ defmodule BDS.Projects do
|
||||
})
|
||||
|> Repo.insert!()
|
||||
|
||||
:ok = StarterTemplates.install(project)
|
||||
{:ok, _templates} = Templates.rebuild_templates_from_files(project.id)
|
||||
project
|
||||
end)
|
||||
|
||||
@@ -14,6 +14,7 @@ defmodule BDS.Rendering do
|
||||
alias BDS.Rendering.FileSystem
|
||||
alias BDS.Rendering.Filters
|
||||
alias BDS.Repo
|
||||
alias BDS.StarterTemplates
|
||||
alias BDS.Posts.Post
|
||||
alias BDS.Posts.Translation
|
||||
alias BDS.Tags.Tag
|
||||
@@ -46,9 +47,14 @@ defmodule BDS.Rendering do
|
||||
end
|
||||
|
||||
defp load_template_source(project_id, kind, slug) do
|
||||
project = Projects.get_project!(project_id)
|
||||
|
||||
case select_template(project_id, kind, slug) do
|
||||
nil -> {:error, :template_not_found}
|
||||
%Template{} = template -> published_template_body(template)
|
||||
%Template{} = template ->
|
||||
published_template_body(template)
|
||||
|
||||
nil ->
|
||||
load_bundled_template_source(project, kind, slug)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -60,7 +66,7 @@ defmodule BDS.Rendering do
|
||||
template.status == :published and
|
||||
template.enabled == true and template.slug == ^slug,
|
||||
limit: 1
|
||||
) || select_template(project_id, kind, nil)
|
||||
)
|
||||
end
|
||||
|
||||
defp select_template(project_id, kind, nil) do
|
||||
@@ -97,13 +103,12 @@ defmodule BDS.Rendering do
|
||||
defp render_template(project_id, source, assigns) do
|
||||
with {:ok, template_ast} <- Liquex.parse(source) do
|
||||
project = Projects.get_project!(project_id)
|
||||
template_root = Path.join(Projects.project_data_dir(project), "templates")
|
||||
|
||||
context =
|
||||
Liquex.Context.new(assigns,
|
||||
static_environment: assigns,
|
||||
filter_module: Filters,
|
||||
file_system: FileSystem.new(template_root)
|
||||
file_system: FileSystem.new(StarterTemplates.template_roots(project))
|
||||
)
|
||||
|
||||
{result, _context} = Liquex.render!(template_ast, context)
|
||||
@@ -113,6 +118,30 @@ defmodule BDS.Rendering do
|
||||
error -> {:error, error}
|
||||
end
|
||||
|
||||
defp load_bundled_template_source(project, kind, slug) do
|
||||
desired_slug = bundled_template_slug(kind, slug)
|
||||
|
||||
if is_binary(desired_slug) do
|
||||
file_system = project |> StarterTemplates.template_roots() |> FileSystem.new()
|
||||
source = Liquex.FileSystem.read_template_file(file_system, desired_slug)
|
||||
|
||||
case Frontmatter.parse_document(source) do
|
||||
{:ok, %{body: body}} -> {:ok, body}
|
||||
{:error, :invalid_frontmatter} -> {:ok, source}
|
||||
{:error, reason} -> {:error, reason}
|
||||
end
|
||||
else
|
||||
{:error, :template_not_found}
|
||||
end
|
||||
rescue
|
||||
error in [Liquex.Error] ->
|
||||
_ = error
|
||||
{:error, :template_not_found}
|
||||
end
|
||||
|
||||
defp bundled_template_slug(_kind, slug) when is_binary(slug) and slug != "", do: slug
|
||||
defp bundled_template_slug(kind, _slug), do: StarterTemplates.default_slug(kind)
|
||||
|
||||
defp post_assigns(project_id, assigns) do
|
||||
metadata = project_metadata(project_id)
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
defmodule BDS.Rendering.FileSystem do
|
||||
@moduledoc false
|
||||
|
||||
defstruct [:root_path]
|
||||
defstruct [:root_paths]
|
||||
|
||||
def new(root_path) do
|
||||
%__MODULE__{root_path: root_path}
|
||||
def new(root_paths) when is_list(root_paths) do
|
||||
%__MODULE__{root_paths: Enum.uniq(root_paths)}
|
||||
end
|
||||
|
||||
def full_path(%__MODULE__{root_path: root_path}, template_path) do
|
||||
def new(root_path) when is_binary(root_path) do
|
||||
new([root_path])
|
||||
end
|
||||
|
||||
def full_path(%__MODULE__{root_paths: root_paths}, template_path) do
|
||||
normalized_path = to_string(template_path)
|
||||
|
||||
cond do
|
||||
@@ -21,7 +25,16 @@ defmodule BDS.Rendering.FileSystem do
|
||||
raise Liquex.Error, message: "Illegal template path '#{template_path}'"
|
||||
|
||||
true ->
|
||||
Path.expand(Path.join(root_path, normalized_path <> ".liquid"))
|
||||
root_paths
|
||||
|> Enum.map(&Path.expand(Path.join(&1, normalized_path <> ".liquid")))
|
||||
|> Enum.find(&File.regular?/1)
|
||||
|> case do
|
||||
nil ->
|
||||
Path.expand(Path.join(List.first(root_paths) || ".", normalized_path <> ".liquid"))
|
||||
|
||||
path ->
|
||||
path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,62 +1,22 @@
|
||||
defmodule BDS.StarterTemplates do
|
||||
@moduledoc false
|
||||
|
||||
alias BDS.Frontmatter
|
||||
alias BDS.Projects
|
||||
|
||||
@top_level_templates [
|
||||
%{file_name: "single-post.liquid", slug: "single-post", title: "Single Post", kind: :post},
|
||||
%{file_name: "post-list.liquid", slug: "post-list", title: "Post List", kind: :list},
|
||||
%{file_name: "not-found.liquid", slug: "not-found", title: "Not Found", kind: :not_found}
|
||||
]
|
||||
|
||||
def install(project) do
|
||||
source_root = Path.join(Application.app_dir(:bds, "priv/starter_templates"), "templates")
|
||||
target_root = Path.join(Projects.project_data_dir(project), "templates")
|
||||
|
||||
:ok = File.mkdir_p(target_root)
|
||||
|
||||
source_root
|
||||
|> list_files()
|
||||
|> Enum.each(fn source_path ->
|
||||
relative_path = Path.relative_to(source_path, source_root)
|
||||
target_path = Path.join(target_root, relative_path)
|
||||
:ok = File.mkdir_p(Path.dirname(target_path))
|
||||
|
||||
unless File.exists?(target_path) do
|
||||
case Enum.find(@top_level_templates, &(&1.file_name == relative_path)) do
|
||||
nil ->
|
||||
File.cp!(source_path, target_path)
|
||||
|
||||
template ->
|
||||
body = File.read!(source_path)
|
||||
|
||||
File.write!(
|
||||
target_path,
|
||||
Frontmatter.serialize_document(
|
||||
[
|
||||
{:id, Ecto.UUID.generate()},
|
||||
{:slug, template.slug},
|
||||
{:title, template.title},
|
||||
{:kind, template.kind},
|
||||
{:enabled, true},
|
||||
{:version, 1}
|
||||
],
|
||||
body
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
:ok
|
||||
def root_path do
|
||||
Path.join(Application.app_dir(:bds, "priv/starter_templates"), "templates")
|
||||
end
|
||||
|
||||
defp list_files(root) do
|
||||
root
|
||||
|> Path.join("**/*")
|
||||
|> Path.wildcard(match_dot: true)
|
||||
|> Enum.reject(&File.dir?/1)
|
||||
|> Enum.sort()
|
||||
def template_roots(project) do
|
||||
[Path.join(Projects.project_data_dir(project), "templates"), root_path()]
|
||||
end
|
||||
|
||||
def default_slug(:post), do: "single-post"
|
||||
def default_slug(:list), do: "post-list"
|
||||
def default_slug(:not_found), do: "not-found"
|
||||
def default_slug(_kind), do: nil
|
||||
|
||||
def default_template?(kind, slug) when is_binary(slug) do
|
||||
default_slug(kind) == slug
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user