Add feature to customize menu links via a menu file
This commit is contained in:
parent
9f17f21d6d
commit
b8888dcf12
7 changed files with 82 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
29
lib/mebe_engine/menuparser.ex
Normal file
29
lib/mebe_engine/menuparser.ex
Normal 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
|
|
@ -26,4 +26,9 @@ defmodule MebeEngine.Models do
|
|||
title: nil,
|
||||
content: nil
|
||||
end
|
||||
|
||||
defmodule MenuItem do
|
||||
defstruct slug: nil,
|
||||
title: nil
|
||||
end
|
||||
end
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Reference in a new issue