Current section
37 Versions
Jump to
Current section
37 Versions
Compare versions
12
files changed
+155
additions
-82
deletions
| @@ -17,7 +17,7 @@ _If you are having problems, view `README_INSTALL.md` for manual instructions._ | |
| 17 17 | |
| 18 18 | ```elixir |
| 19 19 | def deps do |
| 20 | - [{:thesis, "~> 0.0.14"}] |
| 20 | + [{:thesis, "~> 0.0.15"}] |
| 21 21 | end |
| 22 22 | |
| 23 23 | def application do |
| @@ -88,6 +88,23 @@ becomes... | |
| 88 88 | <h1><%= content(@conn, "Title identifier", :text, do: "My Title") %></h1> |
| 89 89 | ``` |
| 90 90 | |
| 91 | + ### Global Content Areas |
| 92 | + |
| 93 | + Content areas in Thesis are page-specific. However, if you want an editable |
| 94 | + region that can be displayed on multiple pages, use the |
| 95 | + `Thesis.View.global_content/4` function. Internally, the page_id will be set |
| 96 | + to `nil` to indicate it applies globally, rather than to a specific page. |
| 97 | + |
| 98 | + ```eex |
| 99 | + <%= global_content(@conn, "Footer Text", :html) do %> |
| 100 | + <h4>Contact Info</h4> |
| 101 | + <ul> |
| 102 | + <li>Call us at (800) 555-1212</li> |
| 103 | + <li>Email us at hello@example.com.</li> |
| 104 | + </ul> |
| 105 | + <% end %> |
| 106 | + ``` |
| 107 | + |
| 91 108 | ### Meta Title and Description |
| 92 109 | |
| 93 110 | In your layout, you can output the current title and description like so: |
| @@ -110,37 +127,44 @@ end | |
| 110 127 | ## Authorization |
| 111 128 | |
| 112 129 | You probably don't want your website editable by the world. Thesis doesn't |
| 113 | - force you to use any particular authorization strategy. Instead, Thesis will |
| 114 | - call your auth module's `can_edit_page?/1` function and provide the current |
| 115 | - `conn`, which can be used to extract current user session data, the current |
| 116 | - page, and then decide on your own how that should affect authorization. |
| 130 | + force you to use any particular authorization strategy. |
| 131 | + |
| 132 | + Instead, Thesis will call your auth module's `page_is_editable?/1` function |
| 133 | + and provide the current `conn`, which can be used to extract current user |
| 134 | + session data as well as the current page, and then you can decide how that |
| 135 | + should affect authorization. |
| 117 136 | |
| 118 137 | Here's an example which we use on our own website, [https://infinite.red](https://infinite.red): |
| 119 138 | |
| 120 139 | ```elixir |
| 121 140 | defmodule IrWebsite.ThesisAuth do |
| 122 141 | def page_is_editable?(conn) do |
| 123 | - !!IrWebsite.AuthController.current_user(conn) |
| 142 | + IrWebsite.AuthController.logged_in?(conn) |
| 124 143 | end |
| 125 144 | end |
| 126 145 | ``` |
| 127 146 | |
| 128 | - In our `auth_controller.ex` file, the `current_user/1` function looks like this: |
| 147 | + In our `auth_controller.ex` file, the `logged_in?/1` function looks something |
| 148 | + like this: |
| 129 149 | |
| 130 150 | ```elixir |
| 151 | + def logged_in?(conn) do |
| 152 | + !!current_user(conn) |
| 153 | + end |
| 154 | + |
| 131 155 | def current_user(conn) do |
| 132 156 | get_session(conn, :current_user) |
| 133 157 | end |
| 134 158 | ``` |
| 135 159 | |
| 136 160 | So, in this case, we're simply checking to see if the user has been logged in |
| 137 | - or not. Since we're verifying their identity before letting them log in, |
| 138 | - it's safe for us to assume that if they're logged in, they have permission to |
| 139 | - edit the page. |
| 161 | + or not. Since only Infinite Red employees have logins, it's safe for us to |
| 162 | + assume that if they're logged in, they have permission to edit the page. |
| 140 163 | |
| 141 164 | ## What Thesis Isn't |
| 142 165 | |
| 143 | - You can't have it all. Thesis isn't the same as other -bloated- full-functional content management systems out there. This is a list of what it's not now and |
| 166 | + You can't have it all. Thesis isn't the same as other -bloated- full-function |
| 167 | + content management systems out there. This is a list of what it's not now and |
| 144 168 | not likely to be in the future. |
| 145 169 | |
| 146 170 | _We reserve the right to change our mind, however. :-)_ |
| @@ -149,8 +173,7 @@ _We reserve the right to change our mind, however. :-)_ | |
| 149 173 | * Not a full featured CMS |
| 150 174 | * Not a full featured WYSIWYG editor |
| 151 175 | * Not an authentication or permission system |
| 152 | - * Not a library that works well outside of Phoenix |
| 153 | - |
| 176 | + * Not supported outside of a Phoenix app |
| 154 177 | |
| 155 178 | ## Contributing |
| 156 179 | |
| @@ -174,11 +197,11 @@ websites. Please help us improve! | |
| 174 197 | |
| 175 198 | Also supported by others on the [Infinite Red](https://infinite.red) team. |
| 176 199 | |
| 177 | - ### License |
| 200 | + ### License: MIT |
| 178 201 | |
| 179 202 | Copyright (c) 2016 Infinite Red, Inc. |
| 180 203 | |
| 181 204 | Thesis depends on Elixir, which is under the Apache 2 license, and |
| 182 | - Phoenix, which is also MIT. |
| 205 | + Phoenix, which is MIT. |
| 183 206 | |
| 184 207 | See LICENSE.md for more information. |
| @@ -6,7 +6,7 @@ For automatic setup, see `README.md`. | |
| 6 6 | |
| 7 7 | ```elixir |
| 8 8 | def deps do |
| 9 | - [{:thesis, "~> 0.0.5"}] |
| 9 | + [{:thesis, "~> 0.0.15"}] |
| 10 10 | end |
| 11 11 | |
| 12 12 | def application do |
| @@ -30,7 +30,7 @@ config :thesis, Thesis.EctoStore, repo: <MyApp>.Repo | |
| 30 30 | ```elixir |
| 31 31 | defmodule <MyApp>.ThesisAuth do |
| 32 32 | def page_is_editable?(conn) do |
| 33 | - true |
| 33 | + true # editable by the world |
| 34 34 | end |
| 35 35 | end |
| 36 36 | ``` |
| @@ -120,30 +120,30 @@ | |
| 120 120 | <<"package.json">>]}. |
| 121 121 | {<<"licenses">>,[<<"MIT">>]}. |
| 122 122 | {<<"links">>, |
| 123 | - [{<<"Docs">>,<<"https://hexdocs.pm/thesis/0.0.14/api-reference.html">>}, |
| 123 | + [{<<"Docs">>,<<"https://hexdocs.pm/thesis/0.0.15/api-reference.html">>}, |
| 124 124 | {<<"GitHub">>,<<"https://github.com/infinite_red/thesis">>}]}. |
| 125 125 | {<<"maintainers">>, |
| 126 126 | [<<"Jamon Holmgren">>,<<"Ken Miller">>,<<"Daniel Berkompas">>]}. |
| 127 127 | {<<"name">>,<<"thesis">>}. |
| 128 128 | {<<"requirements">>, |
| 129 | - [{<<"ecto">>, |
| 130 | - [{<<"app">>,<<"ecto">>}, |
| 131 | - {<<"optional">>,false}, |
| 132 | - {<<"requirement">>,<<">= 0.0.0">>}]}, |
| 133 | - {<<"html_sanitize_ex">>, |
| 134 | - [{<<"app">>,<<"html_sanitize_ex">>}, |
| 135 | - {<<"optional">>,false}, |
| 136 | - {<<"requirement">>,<<"~> 0.1.0">>}]}, |
| 137 | - {<<"phoenix">>, |
| 138 | - [{<<"app">>,<<"phoenix">>}, |
| 139 | - {<<"optional">>,false}, |
| 140 | - {<<"requirement">>,<<">= 0.0.0">>}]}, |
| 141 | - {<<"phoenix_html">>, |
| 142 | - [{<<"app">>,<<"phoenix_html">>}, |
| 143 | - {<<"optional">>,false}, |
| 144 | - {<<"requirement">>,<<">= 0.0.0">>}]}, |
| 145 | - {<<"plug">>, |
| 146 | - [{<<"app">>,<<"plug">>}, |
| 147 | - {<<"optional">>,false}, |
| 148 | - {<<"requirement">>,<<"~> 1.0">>}]}]}. |
| 149 | - {<<"version">>,<<"0.0.14">>}. |
| 129 | + [[{<<"app">>,<<"phoenix">>}, |
| 130 | + {<<"name">>,<<"phoenix">>}, |
| 131 | + {<<"optional">>,false}, |
| 132 | + {<<"requirement">>,<<">= 0.0.0">>}], |
| 133 | + [{<<"app">>,<<"phoenix_html">>}, |
| 134 | + {<<"name">>,<<"phoenix_html">>}, |
| 135 | + {<<"optional">>,false}, |
| 136 | + {<<"requirement">>,<<">= 0.0.0">>}], |
| 137 | + [{<<"app">>,<<"ecto">>}, |
| 138 | + {<<"name">>,<<"ecto">>}, |
| 139 | + {<<"optional">>,false}, |
| 140 | + {<<"requirement">>,<<">= 0.0.0">>}], |
| 141 | + [{<<"app">>,<<"plug">>}, |
| 142 | + {<<"name">>,<<"plug">>}, |
| 143 | + {<<"optional">>,false}, |
| 144 | + {<<"requirement">>,<<"~> 1.0">>}], |
| 145 | + [{<<"app">>,<<"html_sanitize_ex">>}, |
| 146 | + {<<"name">>,<<"html_sanitize_ex">>}, |
| 147 | + {<<"optional">>,false}, |
| 148 | + {<<"requirement">>,<<"~> 0.1.0">>}]]}. |
| 149 | + {<<"version">>,<<"0.0.15">>}. |
| @@ -20,4 +20,28 @@ defmodule Thesis.PageContent do | |
| 20 20 | |
| 21 21 | timestamps |
| 22 22 | end |
| 23 | + |
| 24 | + @doc """ |
| 25 | + Selects the right page content from a list. |
| 26 | + |
| 27 | + iex> foo = [%Thesis.PageContent{id: 1, page_id: nil, name: "Test"},%Thesis.PageContent{id: 2, page_id: 1, name: "Test"},%Thesis.PageContent{id: 3, page_id: 2, name: "Test"},%Thesis.PageContent{id: 4, page_id: nil, name: "Test2"},%Thesis.PageContent{id: 5, page_id: 1, name: "Test2"}] |
| 28 | + iex> Thesis.PageContent.find(foo, nil, "Test").id == 1 |
| 29 | + true |
| 30 | + iex> Thesis.PageContent.find(foo, 1, "Test").id == 2 |
| 31 | + true |
| 32 | + iex> Thesis.PageContent.find(foo, 2, "Test").id == 3 |
| 33 | + true |
| 34 | + iex> Thesis.PageContent.find(foo, nil, "Test2").id == 4 |
| 35 | + true |
| 36 | + iex> Thesis.PageContent.find(foo, 1, "Test2").id == 5 |
| 37 | + true |
| 38 | + iex> Thesis.PageContent.find(foo, 1, "Test7") |
| 39 | + nil |
| 40 | + """ |
| 41 | + |
| 42 | + def find(contents, page_id, name) do |
| 43 | + contents |
| 44 | + |> Enum.find(fn c -> c.name == name && c.page_id == page_id end) |
| 45 | + end |
| 46 | + |
| 23 47 | end |
| @@ -3,26 +3,20 @@ defmodule Thesis.Store do | |
| 3 3 | Thesis.Store is an Elixir "behaviour" that defines the public function |
| 4 4 | interface necessary for Thesis to use a particular store module. |
| 5 5 | |
| 6 | - There are currently five required functions, as described below. |
| 6 | + There are currently three required functions, as described below. |
| 7 7 | """ |
| 8 8 | |
| 9 | - @doc """ |
| 10 | - Returns all pages currently in the database, as a list of Thesis.Page |
| 11 | - structs. Will return an empty list if none are found. |
| 12 | - """ |
| 13 | - @callback pages() :: %{String.t => Thesis.Page.t} |
| 14 | - |
| 15 9 | @doc """ |
| 16 10 | Returns a Thesis.Page struct with the given slug (aka request_path). |
| 17 11 | """ |
| 18 12 | @callback page(String.t) :: Thesis.Page.t |
| 19 13 | |
| 20 14 | @doc """ |
| 21 | - Returns a map consisting of string keys and Thesis.PageContent structs |
| 22 | - for the given Thesis.Page struct. This is generally used to populate the |
| 23 | - page content using the Thesis.View.content/4 function. |
| 15 | + Returns a list of related Thesis.PageContent structs both for the given |
| 16 | + Thesis.Page struct and global content areas. This is generally used to |
| 17 | + populate the page content using the Thesis.View.content/4 function. |
| 24 18 | """ |
| 25 | - @callback page_contents(Thesis.Page.t) :: %{String.t => Thesis.PageContent.t} |
| 19 | + @callback page_contents(Thesis.Page.t) :: [ Thesis.PageContent.t ] |
| 26 20 | |
| 27 21 | @doc """ |
| 28 22 | Updates the given page (identified by its slug) with the given map of |
Loading more files…