Implement extra header support and multi author support
Also add a lot of parenthesis
This commit is contained in:
parent
7e6b490465
commit
b33c48c8db
21 changed files with 298 additions and 74 deletions
|
@ -23,6 +23,9 @@ config :mebe_web,
|
|||
blog_author: "Author McAuthor",
|
||||
absolute_url: "http://localhost:4000", # Absolute URL to the site without trailing slash, including protocol
|
||||
|
||||
multi_author_mode: false, # Set to true to show author header from posts, if available (blog_author will be used as default)
|
||||
use_default_author: true, # If multi author mode is on, use blog_author as default author (if this is false, no author will be set if post has no author header)
|
||||
|
||||
force_read_more: false, # Force "Read more…" text to display even if there is no more content
|
||||
|
||||
enable_feeds: false, # Set to true to enable RSS feeds
|
||||
|
|
|
@ -10,6 +10,8 @@ defmodule MebeEngine.Crawler do
|
|||
alias MebeEngine.Models.Page
|
||||
alias MebeEngine.Models.Post
|
||||
|
||||
alias MebeWeb.Utils
|
||||
|
||||
def crawl(path) do
|
||||
get_files(path)
|
||||
|> Enum.map(fn file -> Task.async MebeEngine.Crawler, :parse, [file] end)
|
||||
|
@ -38,16 +40,30 @@ defmodule MebeEngine.Crawler do
|
|||
end
|
||||
|
||||
def construct_archives(datalist) do
|
||||
Enum.reduce datalist, %{pages: %{}, posts: [], years: %{}, months: %{}, tags: %{}}, fn pagedata, acc ->
|
||||
multi_author_mode = Utils.get_conf(:multi_author_mode)
|
||||
|
||||
Enum.reduce datalist, %{pages: %{}, posts: [], years: %{}, months: %{}, tags: %{}, authors: %{}, author_names: %{}}, fn pagedata, acc ->
|
||||
case pagedata.__struct__ do
|
||||
Page -> %{acc | pages: Map.put(acc.pages, pagedata.slug, pagedata)}
|
||||
|
||||
Post ->
|
||||
{year, month, _} = pagedata.date
|
||||
|
||||
tags = Enum.reduce pagedata.tags, acc.tags, fn tag, tagmap ->
|
||||
tags = Enum.reduce(pagedata.tags, acc.tags, fn tag, tagmap ->
|
||||
posts = Map.get(tagmap, tag, [])
|
||||
Map.put(tagmap, tag, [pagedata | posts])
|
||||
end)
|
||||
|
||||
authors = %{}
|
||||
author_names = %{}
|
||||
if multi_author_mode do
|
||||
author_name = Utils.get_author(pagedata)
|
||||
author_slug = Utils.slugify(author_name)
|
||||
author_posts = [pagedata | Map.get(acc.authors, author_slug, [])]
|
||||
authors = Map.put(acc.authors, author_slug, author_posts)
|
||||
|
||||
# Authors end up with the name that was in the post with the first matching slug
|
||||
author_names = Map.put_new(acc.author_names, author_slug, author_name)
|
||||
end
|
||||
|
||||
year_posts = [pagedata | Map.get(acc.years, year, [])]
|
||||
|
@ -58,7 +74,9 @@ defmodule MebeEngine.Crawler do
|
|||
posts: [pagedata | acc.posts],
|
||||
years: Map.put(acc.years, year, year_posts),
|
||||
months: Map.put(acc.months, {year, month}, month_posts),
|
||||
tags: tags
|
||||
tags: tags,
|
||||
authors: authors,
|
||||
author_names: author_names
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
defmodule MebeEngine.DB do
|
||||
require Logger
|
||||
alias MebeWeb.Utils
|
||||
|
||||
@moduledoc """
|
||||
Stuff related to storing the blog data to memory (ETS).
|
||||
"""
|
||||
|
||||
# Table for meta information, like the counts of posts
|
||||
# Table for meta information, like the counts of posts and names
|
||||
# of authors
|
||||
@meta_table :mebeweb_meta
|
||||
|
||||
# Table for storing pages by slug
|
||||
|
@ -18,6 +22,9 @@ defmodule MebeEngine.DB do
|
|||
# Table for storing posts with tag as first element of key
|
||||
@tag_table :mebeweb_tags
|
||||
|
||||
# Table for storing posts by specific authors
|
||||
@author_table :mebeweb_authors
|
||||
|
||||
# Table for storing menu data
|
||||
@menu_table :mebeweb_menu
|
||||
|
||||
|
@ -30,6 +37,10 @@ defmodule MebeEngine.DB do
|
|||
:ets.new @single_post_table, [:named_table, :set, :protected, read_concurrency: true]
|
||||
:ets.new @tag_table, [:named_table, :ordered_set, :protected, read_concurrency: true]
|
||||
:ets.new @menu_table, [:named_table, :ordered_set, :protected, read_concurrency: true]
|
||||
|
||||
if Utils.get_conf(:multi_author_mode) do
|
||||
:ets.new @author_table, [:named_table, :ordered_set, :protected, read_concurrency: true]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -41,8 +52,12 @@ defmodule MebeEngine.DB do
|
|||
:ets.delete_all_objects @tag_table
|
||||
end
|
||||
|
||||
def insert_count(key, count) do
|
||||
:ets.insert @meta_table, {key, count}
|
||||
def insert_count(:all, count) do
|
||||
insert_meta(:all, :all, count)
|
||||
end
|
||||
|
||||
def insert_count(type, key, count) do
|
||||
insert_meta(type, key, count)
|
||||
end
|
||||
|
||||
def insert_menu(menu) do
|
||||
|
@ -61,18 +76,55 @@ defmodule MebeEngine.DB do
|
|||
{year, month, day} = post.date
|
||||
{{year, month, day, post.slug}, post}
|
||||
end
|
||||
|
||||
|
||||
:ets.insert @post_table, ordered_posts
|
||||
:ets.insert @single_post_table, single_posts
|
||||
|
||||
if Utils.get_conf(:multi_author_mode) do
|
||||
author_posts = Enum.filter(posts, fn post -> Map.has_key?(post.extra_headers, "author") end)
|
||||
|> Enum.map(fn post ->
|
||||
{year, month, day} = post.date
|
||||
|
||||
author_slug = Utils.get_author(post) |> Utils.slugify
|
||||
{{author_slug, year, month, day, post.order}, post}
|
||||
end)
|
||||
|
||||
:ets.insert @author_table, author_posts
|
||||
end
|
||||
end
|
||||
|
||||
def insert_page(page) do
|
||||
:ets.insert @page_table, {page.slug, page}
|
||||
end
|
||||
|
||||
def insert_tag_post(tag, post) do
|
||||
{year, month, day} = post.date
|
||||
:ets.insert @tag_table, {{tag, year, month, day, post.order}, post}
|
||||
def insert_tag_posts(tags) do
|
||||
tag_posts = Enum.reduce(Map.keys(tags), [], fn tag, acc ->
|
||||
Enum.reduce(tags[tag], acc, fn post, inner_acc ->
|
||||
{year, month, day} = post.date
|
||||
[{{tag, year, month, day, post.order}, post} | inner_acc]
|
||||
end)
|
||||
end)
|
||||
|
||||
:ets.insert @tag_table, tag_posts
|
||||
end
|
||||
|
||||
def insert_author_posts(authors) do
|
||||
author_posts = Enum.reduce(Map.keys(authors), [], fn author_slug, acc ->
|
||||
Enum.reduce(authors[author_slug], acc, fn post, inner_acc ->
|
||||
{year, month, day} = post.date
|
||||
[{{author_slug, year, month, day, post.order}, post} | inner_acc]
|
||||
end)
|
||||
end)
|
||||
|
||||
:ets.insert @author_table, author_posts
|
||||
end
|
||||
|
||||
def insert_author_names(author_names_map) do
|
||||
author_names = Enum.reduce(Map.keys(author_names_map), [], fn author_slug, acc ->
|
||||
[{{:author_name, author_slug}, author_names_map[author_slug]} | acc]
|
||||
end)
|
||||
|
||||
:ets.insert @meta_table, author_names
|
||||
end
|
||||
|
||||
|
||||
|
@ -84,19 +136,23 @@ defmodule MebeEngine.DB do
|
|||
end
|
||||
|
||||
def get_reg_posts(first, last) do
|
||||
get_post_list @post_table, [{:"$1", [], [:"$_"]}], first, last
|
||||
get_post_list(@post_table, [{:"$1", [], [:"$_"]}], first, last)
|
||||
end
|
||||
|
||||
def get_tag_posts(tag, first, last) do
|
||||
get_post_list @tag_table, [{{{tag, :_, :_, :_, :_}, :"$1"}, [], [:"$_"]}], first, last
|
||||
get_post_list(@tag_table, [{{{tag, :_, :_, :_, :_}, :"$1"}, [], [:"$_"]}], first, last)
|
||||
end
|
||||
|
||||
def get_author_posts(author_slug, first, last) do
|
||||
get_post_list(@author_table, [{{{author_slug, :_, :_, :_, :_}, :"$1"}, [], [:"$_"]}], first, last)
|
||||
end
|
||||
|
||||
def get_year_posts(year, first, last) do
|
||||
get_post_list @post_table, [{{{year, :_, :_, :_}, :"$1"}, [], [:"$_"]}], first, last
|
||||
get_post_list(@post_table, [{{{year, :_, :_, :_}, :"$1"}, [], [:"$_"]}], first, last)
|
||||
end
|
||||
|
||||
def get_month_posts(year, month, first, last) do
|
||||
get_post_list @post_table, [{{{year, month, :_, :_}, :"$1"}, [], [:"$_"]}], first, last
|
||||
get_post_list(@post_table, [{{{year, month, :_, :_}, :"$1"}, [], [:"$_"]}], first, last)
|
||||
end
|
||||
|
||||
def get_page(slug) do
|
||||
|
@ -113,16 +169,33 @@ defmodule MebeEngine.DB do
|
|||
end
|
||||
end
|
||||
|
||||
def get_count(type) do
|
||||
case :ets.match_object @meta_table, {type, :"$1"} do
|
||||
[{_, count}] -> count
|
||||
[] -> 0
|
||||
end
|
||||
def get_count(:all) do
|
||||
get_count(:all, :all)
|
||||
end
|
||||
|
||||
def get_count(type, key) do
|
||||
get_meta(type, key, 0)
|
||||
end
|
||||
|
||||
def get_author_name(author_slug) do
|
||||
get_meta(:author_name, author_slug, author_slug)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
defp insert_meta(type, key, value) do
|
||||
:ets.insert @meta_table, {{type, key}, value}
|
||||
end
|
||||
|
||||
defp get_meta(type, key, default) do
|
||||
case :ets.match_object @meta_table, {{type, key}, :"$1"} do
|
||||
[{{_, _}, value}] -> value
|
||||
[] -> default
|
||||
end
|
||||
end
|
||||
|
||||
# Combine error handling of different post listing functions
|
||||
defp get_post_list(table, matchspec, first, last) do
|
||||
case :ets.select_reverse table, matchspec, first + last do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
defmodule MebeEngine.Models do
|
||||
@moduledoc """
|
||||
This module contains the data models (not db models) of the blog engine.
|
||||
This module contains the data models of the blog engine.
|
||||
"""
|
||||
|
||||
defmodule PageData do
|
||||
|
@ -18,13 +18,15 @@ defmodule MebeEngine.Models do
|
|||
content: nil,
|
||||
short_content: nil,
|
||||
order: 0,
|
||||
has_more: false
|
||||
has_more: false,
|
||||
extra_headers: %{}
|
||||
end
|
||||
|
||||
defmodule Page do
|
||||
defstruct slug: nil,
|
||||
title: nil,
|
||||
content: nil
|
||||
content: nil,
|
||||
extra_headers: %{}
|
||||
end
|
||||
|
||||
defmodule MenuItem do
|
||||
|
|
|
@ -59,11 +59,12 @@ defmodule MebeEngine.Parser do
|
|||
%Page{
|
||||
slug: slug,
|
||||
title: title,
|
||||
content: content
|
||||
content: content,
|
||||
extra_headers: parse_headers(headers)
|
||||
}
|
||||
|
||||
[_, year, month, day, order, slug] ->
|
||||
[tags | _] = headers
|
||||
[tags | extra_headers] = headers
|
||||
|
||||
order = format_order order
|
||||
|
||||
|
@ -77,12 +78,27 @@ defmodule MebeEngine.Parser do
|
|||
content: content,
|
||||
short_content: hd(split_content),
|
||||
order: order,
|
||||
has_more: (Enum.count(split_content) > 1)
|
||||
has_more: (Enum.count(split_content) > 1),
|
||||
extra_headers: parse_headers(extra_headers)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
defp parse_headers(headers) do
|
||||
# Parse a list of headers into a string keyed map
|
||||
Enum.reduce(headers, %{}, fn header, acc ->
|
||||
{key, val} = split_header(header)
|
||||
Map.put(acc, key, val)
|
||||
end)
|
||||
end
|
||||
|
||||
defp split_header(header) do
|
||||
# Enforce 2 parts
|
||||
[key | [val]] = String.split(header, ":", parts: 2)
|
||||
{String.strip(key), String.strip(val)}
|
||||
end
|
||||
|
||||
defp parse_tags(tagline) do
|
||||
String.split tagline, ~R/,\s*/iu
|
||||
end
|
||||
|
|
|
@ -36,42 +36,47 @@ defmodule MebeEngine.Worker do
|
|||
Initialize the database by crawling the configured path and parsing data to the DB.
|
||||
"""
|
||||
def load_db() do
|
||||
data_path = Utils.get_conf :data_path
|
||||
data_path = Utils.get_conf(:data_path)
|
||||
|
||||
Logger.info "Loading menu from '#{data_path}/menu'…"
|
||||
Logger.info("Loading menu from '#{data_path}/menu'…")
|
||||
|
||||
menu = MenuParser.parse data_path
|
||||
menu = MenuParser.parse(data_path)
|
||||
|
||||
Logger.info "Loading post database from '#{data_path}'…"
|
||||
Logger.info("Loading post database from '#{data_path}'…")
|
||||
|
||||
%{
|
||||
pages: pages,
|
||||
posts: posts,
|
||||
tags: tags,
|
||||
authors: authors,
|
||||
author_names: author_names,
|
||||
years: years,
|
||||
months: months,
|
||||
} = Crawler.crawl data_path
|
||||
} = Crawler.crawl(data_path)
|
||||
|
||||
Logger.info "Loaded #{Enum.count pages} pages and #{Enum.count posts} posts."
|
||||
Logger.info("Loaded #{Enum.count pages} pages and #{Enum.count posts} posts.")
|
||||
|
||||
DB.init
|
||||
DB.init()
|
||||
|
||||
DB.insert_menu menu
|
||||
DB.insert_posts posts
|
||||
DB.insert_count :all, Enum.count posts
|
||||
DB.insert_menu(menu)
|
||||
DB.insert_posts(posts)
|
||||
DB.insert_count(:all, Enum.count(posts))
|
||||
|
||||
Enum.each Map.keys(pages), fn page -> DB.insert_page pages[page] end
|
||||
|
||||
Enum.each Map.keys(tags),
|
||||
fn tag ->
|
||||
Enum.each(tags[tag], fn post -> DB.insert_tag_post(tag, post) end)
|
||||
DB.insert_count tag, Enum.count tags[tag]
|
||||
end
|
||||
DB.insert_tag_posts(tags)
|
||||
Enum.each(Map.keys(tags), fn tag -> DB.insert_count(:tag, tag, Enum.count(tags[tag])) end)
|
||||
|
||||
if Utils.get_conf(:multi_author_mode) do
|
||||
DB.insert_author_posts(authors)
|
||||
DB.insert_author_names(author_names)
|
||||
Enum.each(Map.keys(authors), fn author -> DB.insert_count(:author, author, Enum.count(authors[author])) end)
|
||||
end
|
||||
|
||||
# For years and months, only insert the counts (the data can be fetched from main posts table)
|
||||
Enum.each Map.keys(years), fn year -> DB.insert_count year, Enum.count years[year] end
|
||||
Enum.each Map.keys(months), fn month -> DB.insert_count month, Enum.count months[month] end
|
||||
Enum.each(Map.keys(years), fn year -> DB.insert_count(:year, year, Enum.count(years[year])) end)
|
||||
Enum.each(Map.keys(months), fn month -> DB.insert_count(:month, month, Enum.count(months[month])) end)
|
||||
|
||||
Logger.info "Posts loaded."
|
||||
Logger.info("Posts loaded.")
|
||||
end
|
||||
end
|
56
lib/utils.ex
56
lib/utils.ex
|
@ -1,4 +1,7 @@
|
|||
defmodule MebeWeb.Utils do
|
||||
alias MebeEngine.Models
|
||||
alias MebeEngine.DB
|
||||
|
||||
@moduledoc """
|
||||
This module contains functions and other stuff that just don't fit anywhere else properly.
|
||||
"""
|
||||
|
@ -12,4 +15,57 @@ defmodule MebeWeb.Utils do
|
|||
def get_conf(key) do
|
||||
Application.get_env :mebe_web, key
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get the author of a post.
|
||||
|
||||
Returns a value according to the following pseudocode
|
||||
|
||||
if multi author mode is on then
|
||||
if post has author then
|
||||
return post's author
|
||||
else if use default author is on then
|
||||
return blog author
|
||||
else return nil
|
||||
else if use default author is on then
|
||||
return blog author
|
||||
else return nil
|
||||
"""
|
||||
def get_author(post = %Models.Post{}) do
|
||||
multi_author_mode = get_conf(:multi_author_mode)
|
||||
use_default_author = get_conf(:use_default_author)
|
||||
blog_author = get_conf(:blog_author)
|
||||
|
||||
if multi_author_mode do
|
||||
cond do
|
||||
Map.has_key?(post.extra_headers, "author") ->
|
||||
Map.get(post.extra_headers, "author")
|
||||
|
||||
use_default_author ->
|
||||
blog_author
|
||||
|
||||
true -> nil
|
||||
end
|
||||
else
|
||||
if use_default_author, do: blog_author, else: nil
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get slug out of a given value.
|
||||
|
||||
Nil is returned as is.
|
||||
"""
|
||||
def slugify(nil), do: nil
|
||||
|
||||
def slugify(value) do
|
||||
Slugger.slugify_downcase(value)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Get the author name related to this slug from the DB.
|
||||
"""
|
||||
def unslugify_author(slug) do
|
||||
DB.get_author_name(slug)
|
||||
end
|
||||
end
|
||||
|
|
3
mix.exs
3
mix.exs
|
@ -35,7 +35,8 @@ defmodule MebeWeb.Mixfile do
|
|||
{:cowboy, "~> 1.0"},
|
||||
{:earmark, "~> 0.2.0"},
|
||||
{:exrm, "~> 1.0.0-rc5"},
|
||||
{:conform, "~> 1.0.0-rc4"}
|
||||
{:conform, "~> 1.0.0-rc4"},
|
||||
{:slugger, github: "h4cc/slugger", ref: "558e435c232034551123f034f6dd7f1f395e6759"}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
16
mix.lock
16
mix.lock
|
@ -1,18 +1,20 @@
|
|||
%{"bbmustache": {:hex, :bbmustache, "1.0.3"},
|
||||
%{"bbmustache": {:hex, :bbmustache, "1.0.4"},
|
||||
"cf": {:hex, :cf, "0.2.1"},
|
||||
"conform": {:hex, :conform, "1.0.0-rc8"},
|
||||
"cowboy": {:hex, :cowboy, "1.0.4"},
|
||||
"cowlib": {:hex, :cowlib, "1.0.2"},
|
||||
"earmark": {:hex, :earmark, "0.2.1"},
|
||||
"erlware_commons": {:hex, :erlware_commons, "0.15.0"},
|
||||
"exrm": {:hex, :exrm, "1.0.0-rc7"},
|
||||
"erlware_commons": {:hex, :erlware_commons, "0.18.0"},
|
||||
"exrm": {:hex, :exrm, "1.0.0-rc8"},
|
||||
"fs": {:hex, :fs, "0.9.2"},
|
||||
"getopt": {:hex, :getopt, "0.8.2"},
|
||||
"neotoma": {:hex, :neotoma, "1.7.3"},
|
||||
"phoenix": {:hex, :phoenix, "1.1.4"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "2.5.0"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.0.3"},
|
||||
"plug": {:hex, :plug, "1.1.0"},
|
||||
"poison": {:hex, :poison, "2.0.1"},
|
||||
"providers": {:hex, :providers, "1.4.1"},
|
||||
"plug": {:hex, :plug, "1.1.1"},
|
||||
"poison": {:hex, :poison, "2.1.0"},
|
||||
"providers": {:hex, :providers, "1.6.0"},
|
||||
"ranch": {:hex, :ranch, "1.2.1"},
|
||||
"relx": {:hex, :relx, "3.5.0"}}
|
||||
"relx": {:hex, :relx, "3.16.0"},
|
||||
"slugger": {:git, "https://github.com/h4cc/slugger.git", "558e435c232034551123f034f6dd7f1f395e6759", [ref: "558e435c232034551123f034f6dd7f1f395e6759"]}}
|
||||
|
|
|
@ -26,6 +26,8 @@ defmodule MebeWeb.ControllerUtils do
|
|||
|> assign(:blog_name, Utils.get_conf(:blog_name))
|
||||
|> assign(:blog_author, Utils.get_conf(:blog_author))
|
||||
|> assign(:absolute_url, Utils.get_conf(:absolute_url))
|
||||
|> assign(:multi_author_mode, Utils.get_conf(:multi_author_mode))
|
||||
|> assign(:use_default_author, Utils.get_conf(:use_default_author))
|
||||
|> assign(:posts_per_page, Utils.get_conf(:posts_per_page))
|
||||
|> assign(:disqus_comments, Utils.get_conf(:disqus_comments))
|
||||
|> assign(:page_commenting, Utils.get_conf(:page_commenting))
|
||||
|
|
|
@ -11,28 +11,34 @@ defmodule MebeWeb.FeedController do
|
|||
plug :put_layout, "feed.xml"
|
||||
|
||||
def index(conn, params) do
|
||||
posts = DB.get_reg_posts 0, Utils.get_conf(:posts_in_feed)
|
||||
posts = DB.get_reg_posts(0, Utils.get_conf(:posts_in_feed))
|
||||
|
||||
conn
|
||||
|> render_posts(posts, "postlist.xml", params)
|
||||
end
|
||||
|
||||
def tag(conn, params) do
|
||||
%{"tag" => tag} = params
|
||||
|
||||
posts = DB.get_tag_posts tag, 0, Utils.get_conf(:posts_in_feed)
|
||||
def tag(conn, params = %{"tag" => tag}) do
|
||||
posts = DB.get_tag_posts(tag, 0, Utils.get_conf(:posts_in_feed))
|
||||
|
||||
conn
|
||||
|> assign(:tag, tag)
|
||||
|> render_posts(posts, "postlist.xml", params)
|
||||
end
|
||||
|
||||
def author(conn, params = %{"author" => author}) do
|
||||
posts = DB.get_author_posts(author, 0, Utils.get_conf(:posts_in_feed))
|
||||
|
||||
conn
|
||||
|> assign(:author, author)
|
||||
|> render_posts(posts, "postlist.xml", params)
|
||||
end
|
||||
|
||||
# A private plug to check if feeds are enabled at runtime. We need to do this
|
||||
# at runtime to make it work with releases (where the release is compiled with
|
||||
# configuration that was active when the release was made). This plug will halt
|
||||
# the request processing, returning a 404 error if feeds are not enabled.
|
||||
defp check_feeds_enabled(conn, _opts) do
|
||||
case Utils.get_conf :enable_feeds do
|
||||
case Utils.get_conf(:enable_feeds) do
|
||||
true -> conn
|
||||
false ->
|
||||
conn
|
||||
|
|
|
@ -19,21 +19,37 @@ defmodule MebeWeb.PageController do
|
|||
)
|
||||
end
|
||||
|
||||
def tag(conn, params) do
|
||||
%{"tag" => tag} = params
|
||||
|
||||
def tag(conn, params = %{"tag" => tag}) do
|
||||
conn
|
||||
|> assign(:tag, tag)
|
||||
|> render_page(
|
||||
:tag,
|
||||
[tag],
|
||||
fn first, last -> DB.get_tag_posts(tag, first, last) end,
|
||||
DB.get_count(tag),
|
||||
DB.get_count(:tag, tag),
|
||||
"tag.html",
|
||||
params
|
||||
)
|
||||
end
|
||||
|
||||
def author(conn, params = %{"author" => author}) do
|
||||
case Utils.get_conf(:multi_author_mode) do
|
||||
true ->
|
||||
conn
|
||||
|> assign(:author, author)
|
||||
|> render_page(
|
||||
:author,
|
||||
[author],
|
||||
fn first, last -> DB.get_author_posts(author, first, last) end,
|
||||
DB.get_count(:author, author),
|
||||
"author.html",
|
||||
params
|
||||
)
|
||||
|
||||
_ -> render_404(conn)
|
||||
end
|
||||
end
|
||||
|
||||
def year(conn, params) do
|
||||
%{"year" => year} = params
|
||||
|
||||
|
@ -45,13 +61,13 @@ defmodule MebeWeb.PageController do
|
|||
:year,
|
||||
[year],
|
||||
fn first, last -> DB.get_year_posts(year, first, last) end,
|
||||
DB.get_count(year),
|
||||
DB.get_count(:year, year),
|
||||
"year.html",
|
||||
params
|
||||
)
|
||||
|
||||
_ ->
|
||||
render_404 conn
|
||||
render_404(conn)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,7 +86,7 @@ defmodule MebeWeb.PageController do
|
|||
:month,
|
||||
[year, month],
|
||||
fn first, last -> DB.get_month_posts(year, month, first, last) end,
|
||||
DB.get_count({year, month}),
|
||||
DB.get_count(:month, {year, month}),
|
||||
"month.html",
|
||||
params
|
||||
)
|
||||
|
@ -126,8 +142,8 @@ defmodule MebeWeb.PageController do
|
|||
# posts when called, or an empty list if none are found. The function gets
|
||||
# the first and last post to display as integer arguments.
|
||||
defp render_page(conn, page_type, page_args, postgetter, total_count, template, params) do
|
||||
page = get_page params
|
||||
{first, last} = calculate_ranges page
|
||||
page = get_page(params)
|
||||
{first, last} = calculate_ranges(page)
|
||||
|
||||
case postgetter.(first, last) do
|
||||
[] ->
|
||||
|
|
|
@ -20,6 +20,10 @@ defmodule MebeWeb.Router do
|
|||
get "/tag/:tag", PageController, :tag
|
||||
get "/tag/:tag/feed", FeedController, :tag
|
||||
|
||||
get "/author/:author/p/:page", PageController, :author
|
||||
get "/author/:author", PageController, :author
|
||||
get "/author/:author/feed", FeedController, :author
|
||||
|
||||
get "/archive/:year/p/:page", PageController, :year
|
||||
get "/archive/:year", PageController, :year
|
||||
get "/archive/:year/:month/p/:page", PageController, :month
|
||||
|
|
|
@ -23,6 +23,11 @@
|
|||
<title>
|
||||
<![CDATA[<%= post.title %>]]>
|
||||
</title>
|
||||
|
||||
<%= if @multi_author_mode do %>
|
||||
<dc:creator><%= get_author(post) %></dc:creator>
|
||||
<% end %>
|
||||
|
||||
<link><%= @absolute_url %><%= page_path @conn, :post, year, j_month, j_day, post.slug %></link>
|
||||
<guid><%= @absolute_url %><%= page_path @conn, :post, year, j_month, j_day, post.slug %></guid>
|
||||
<description>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<rss version="2.0">
|
||||
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<channel>
|
||||
<title><%= title @conn %></title>
|
||||
<link><%= @absolute_url %></link>
|
||||
<description></description>
|
||||
<generator>Mebe</generator>
|
||||
<copyright>© <%= @blog_author %></copyright>
|
||||
|
||||
<%= render @view_module, @view_template, assigns %>
|
||||
</channel>
|
||||
|
|
7
web/templates/page/author.html.eex
Normal file
7
web/templates/page/author.html.eex
Normal file
|
@ -0,0 +1,7 @@
|
|||
<div class="jumbotron">
|
||||
<p>
|
||||
Viewing posts by author <em><%= unslugify_author(@author) %></em>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<%= render "postlist.html", assigns %>
|
|
@ -6,4 +6,4 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<%= render "postlist.html", assigns %>
|
||||
<%= render "postlist.html", assigns %>
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
}
|
||||
%>
|
||||
|
||||
<%
|
||||
author = get_author(@post)
|
||||
%>
|
||||
|
||||
<div class="post">
|
||||
<div class="post-header">
|
||||
|
||||
|
@ -22,7 +26,10 @@
|
|||
<div class="post-meta">
|
||||
<span>
|
||||
Posted on
|
||||
<a href="<%= page_path @conn, :year, year, 1 %>"><%= year %>-<%= j_month %>-<%= j_day %></a>.
|
||||
<a href="<%= page_path @conn, :year, year, 1 %>"><%= year %>-<%= j_month %>-<%= j_day %></a><!--
|
||||
--><%= if @multi_author_mode and author != nil do %><!--
|
||||
--> by <a href="<%= page_path(@conn, :author, slugify(get_author(@post)), 1) %>"><%= get_author(@post) %></a><!--
|
||||
--><% end %>.
|
||||
</span>
|
||||
|
||||
<%= if @post.tags do %>
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<%= render "postlist.html", assigns %>
|
||||
<%= render "postlist.html", assigns %>
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<%= render "postlist.html", assigns %>
|
||||
<%= render "postlist.html", assigns %>
|
||||
|
|
|
@ -43,14 +43,14 @@ defmodule MebeWeb.Web do
|
|||
|
||||
use Phoenix.View, root: root
|
||||
|
||||
# Import convenience functions from controllers
|
||||
import Phoenix.Controller, only: [get_flash: 2]
|
||||
|
||||
# Import URL helpers from the router
|
||||
import MebeWeb.Router.Helpers
|
||||
|
||||
# Use all HTML functionality (forms, tags, etc)
|
||||
use Phoenix.HTML
|
||||
|
||||
# Custom helpers
|
||||
import MebeWeb.Utils, only: [get_author: 1, slugify: 1, unslugify_author: 1]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Reference in a new issue