Current section

37 Versions

Jump to

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…