Add feature to customize menu links via a menu file

This commit is contained in:
Mikko Ahlroth 2015-12-10 22:55:36 +02:00
parent 9f17f21d6d
commit b8888dcf12
7 changed files with 82 additions and 6 deletions

View file

@ -14,6 +14,7 @@ The engine consists of two parts:
* `git clone`
* Copy `config/*.exs.dist`, removing the `.dist` ending and go through the configs.
* `npm install && gulp` to build the frontend.
* Put some content into the data path you specified, at least a `menu` file.
* `mix phoenix.server` to run the development server.
## Features

View file

@ -4,19 +4,22 @@ defmodule MebeEngine.DB do
"""
# Table for meta information, like the counts of posts
@meta_table :meta
@meta_table :mebeweb_meta
# Table for storing pages by slug
@page_table :pages
@page_table :mebeweb_pages
# Table for sequential retrieval of posts (for list pages)
@post_table :posts
@post_table :mebeweb_posts
# Table for quick retrieval of single post (with key)
@single_post_table :single_posts
@single_post_table :mebeweb_single_posts
# Table for storing posts with tag as first element of key
@tag_table :tags
@tag_table :mebeweb_tags
# Table for storing menu data
@menu_table :mebeweb_menu
def init() do
# Only create tables if they don't exist already
@ -26,6 +29,7 @@ defmodule MebeEngine.DB do
:ets.new @post_table, [:named_table, :ordered_set, :protected, read_concurrency: true]
: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]
end
end
@ -41,6 +45,12 @@ defmodule MebeEngine.DB do
:ets.insert @meta_table, {key, count}
end
def insert_menu(menu) do
# Format for ETS because it needs a tuple
menu = Enum.map menu, fn menuitem -> {menuitem.slug, menuitem} end
:ets.insert @menu_table, menu
end
def insert_posts(posts) do
ordered_posts = Enum.map posts, fn post ->
{year, month, day} = post.date
@ -66,6 +76,13 @@ defmodule MebeEngine.DB do
end
def get_menu() do
case :ets.match @menu_table, :"$1" do
[] -> []
results -> format_menu results
end
end
def get_reg_posts(first, last) do
get_post_list @post_table, [{:"$1", [], [:"$_"]}], first, last
end
@ -121,4 +138,9 @@ defmodule MebeEngine.DB do
defp ets_to_data(data) do
Enum.map data, fn {_, actual} -> actual end
end
# Format menu results (convert [{slug, %MenuItem{}}] to %MenuItem{})
defp format_menu(results) do
for [{_, result}] <- results, do: result
end
end

View file

@ -0,0 +1,29 @@
defmodule MebeEngine.MenuParser do
@moduledoc """
This module handles the parsing of the menu file, which lists the links in the menu bar.
"""
alias MebeEngine.Models.MenuItem
def parse(data_path) do
(data_path <> "/menu")
|> File.read!
|> split_lines
|> parse_lines
# Filter out nils that come from badly formatted lines
|> Enum.filter(fn item -> item != nil end)
end
defp split_lines(menudata) do
String.split menudata, ~R/\r?\n/
end
defp parse_lines(menulines) do
for line <- menulines do
case String.split line, " " do
[_] -> nil
[link | rest] -> %MenuItem{slug: link, title: Enum.join(rest, " ")}
end
end
end
end

View file

@ -26,4 +26,9 @@ defmodule MebeEngine.Models do
title: nil,
content: nil
end
defmodule MenuItem do
defstruct slug: nil,
title: nil
end
end

View file

@ -7,6 +7,7 @@ defmodule MebeEngine.Worker do
alias MebeEngine.Crawler
alias MebeEngine.DB
alias MebeEngine.MenuParser
alias MebeWeb.Utils
def start_link(opts \\ []) do
@ -37,6 +38,10 @@ defmodule MebeEngine.Worker do
def load_db() do
data_path = Utils.get_conf :data_path
Logger.info "Loading menu from '#{data_path}/menu'…"
menu = MenuParser.parse data_path
Logger.info "Loading post database from '#{data_path}'…"
%{
@ -51,6 +56,7 @@ defmodule MebeEngine.Worker do
DB.init
DB.insert_menu menu
DB.insert_posts posts
DB.insert_count :all, Enum.count posts

View file

@ -5,6 +5,8 @@ defmodule MebeWeb.PageController do
alias MebeWeb.Utils
import MebeWeb.ControllerUtils, only: [render_posts: 4, insert_config: 1, render_404: 1]
plug :assign_menu
def index(conn, params) do
conn
|> render_page(
@ -159,4 +161,10 @@ defmodule MebeWeb.PageController do
posts_per_page
}
end
# Get menu from ETS and assign it to every page's data
defp assign_menu(conn, _opts) do
conn
|> assign(:menu, DB.get_menu)
end
end

View file

@ -28,7 +28,12 @@
</div>
<ul class="nav navbar-nav">
<li><a href="<%= page_path @conn, :page, "about" %>">About</a></li>
<%= for menuitem <- @menu do %>
<li>
<a href="<%= menuitem.slug %>"><%= menuitem.title %></a>
</li>
<% end %>
</ul>
</div>
</div>