Current section

37 Versions

Jump to

Compare versions

9 files changed
+43 additions
-19 deletions
  @@ -42,7 +42,7 @@ _If you are having problems, view `README_INSTALL.md` for manual instructions._
42 42
43 43 ```elixir
44 44 def deps do
45 - [{:thesis, "~> 0.0.26"}]
45 + [{:thesis, "~> 0.0.27"}]
46 46 end
47 47
48 48 def application do
  @@ -145,8 +145,7 @@ You can have the user specify an image URL and display the image with the `image
145 145 becomes...
146 146
147 147 ```eex
148 - <%= content(@conn, "Image identifier", :image, alt: "My alt tag", do: "http://placekitten.com/200/300")
149 - %>
148 + <%= content(@conn, "Image identifier", :image, alt: "My alt tag", do: "http://placekitten.com/200/300") %>
150 149 ```
151 150
152 151 If you prefer to use a `div` with a background image, you can use the `background_image`
  @@ -190,7 +189,7 @@ config :thesis,
190 189 uploader: <MyApp>.<CustomUploaderModule>
191 190 ```
192 191
193 - The module should have an `upload/1` function that accepts a `%Plug.Upload{}` struct. This function should return either `{:ok, "path/to/file.jpg"}` tuple with an image url or path, or {:error, _}. You can view
192 + The module should have an `upload/1` function that accepts a `%Plug.Upload{}` struct. This function should return either `{:ok, "path/to/file.jpg"}` tuple with an image url or path, or `{:error, _}`. You can view
194 193 [/lib/thesis/uploaders/repo_uploader.ex](https://github.com/infinitered/thesis-phoenix/blob/master/lib/thesis/uploaders/repo_uploader.ex)
195 194 for an example.
196 195
  @@ -307,7 +306,7 @@ choice.
307 306 You can pass in a default template (otherwise, it'll use the first template
308 307 option in your config) with `render_dynamic(conn, template: "index.html")`.
309 308
310 - You can choose to make only a portion of your website support static pages by
309 + You can choose to make only a portion of your website support dynamic pages by
311 310 routing more specifically. For example, if you want a blog section:
312 311
313 312 ```elixir
  @@ -6,7 +6,7 @@ For automatic setup, see `README.md`.
6 6
7 7 ```elixir
8 8 def deps do
9 - [{:thesis, "~> 0.0.26"}]
9 + [{:thesis, "~> 0.0.27"}]
10 10 end
11 11
12 12 def application do
  @@ -138,7 +138,7 @@
138 138 <<"README_INSTALL.md">>,<<"LICENSE.md">>,<<"package.json">>]}.
139 139 {<<"licenses">>,[<<"MIT">>]}.
140 140 {<<"links">>,
141 - [{<<"Docs">>,<<"https://hexdocs.pm/thesis/0.0.26/api-reference.html">>},
141 + [{<<"Docs">>,<<"https://hexdocs.pm/thesis/0.0.27/api-reference.html">>},
142 142 {<<"GitHub">>,<<"https://github.com/infinitered/thesis">>}]}.
143 143 {<<"maintainers">>,
144 144 [<<"Jamon Holmgren">>,<<"Yulian Glukhenko">>,<<"Ken Miller">>,
  @@ -169,4 +169,4 @@
169 169 {<<"name">>,<<"html_sanitize_ex">>},
170 170 {<<"optional">>,false},
171 171 {<<"requirement">>,<<">= 1.0.1">>}]]}.
172 - {<<"version">>,<<"0.0.26">>}.
172 + {<<"version">>,<<"0.0.27">>}.
  @@ -4,7 +4,7 @@ defmodule Thesis.ApiController do
4 4 use Phoenix.Controller
5 5 import Thesis.Config
6 6
7 - plug :ensure_authorized!
7 + plug :ensure_authorized! when not action in [:show_file]
8 8
9 9 def assets(conn, _params), do: conn
  @@ -21,7 +21,7 @@ defmodule Thesis.EctoStore do
21 21
22 22 @doc """
23 23 Calls page_contents/1 passing through either:
24 - - `nil`, if the Page could not be found (usually means page has not been edited)
24 + - ```nil`, if the Page could not be found (usually means page has not been edited)
25 25 - `%Page{...}` struct, if the Page has already been edited and saved
26 26 """
27 27 def page_contents(slug) when is_binary(slug) do
  @@ -37,13 +37,39 @@ defmodule Thesis.EctoStore do
37 37 end
38 38
39 39 @doc """
40 - Handles `%Page{...} struct - means page has been edited and saved.
40 + Handles `%Page{...}`` struct - means page has been edited and saved.
41 41 Retrieves page content and global content.
42 42 """
43 43 def page_contents(%Page{id: page_id}) do
44 44 repo.all(from pc in PageContent, where: pc.page_id == ^page_id or is_nil(pc.page_id))
45 45 end
46 46
47 + # TODO: Issue #83 - intermittent issue with duplicate content rows
48 + # We're using `page_content/2` here to be more vigorous about checking for
49 + # duplicates, but realize that it's an N+1 on save.
50 + @doc """
51 + Returns an existing %PageContent{} record or a newly created one with the
52 + provided page_id and name set.
53 + """
54 + def page_content_or_new(page_id, name, _preloaded_contents) do
55 + # Original (more efficient but buggy code):
56 + # page_content = PageContent.find(preloaded_contents, page_id, name) ||
57 + # %PageContent{page_id: page_id, name: name}
58 +
59 + page_content(page_id, name) || %PageContent{page_id: page_id, name: name}
60 + end
61 +
62 + @doc """
63 + Retrieves a single %PageContent{} (or nil, if it doesn't exist) based on page_id
64 + and name.
65 + """
66 + def page_content(nil, name) do
67 + repo.one(from pc in PageContent, where: is_nil(pc.page_id) and pc.name == ^name)
68 + end
69 + def page_content(page_id, name) do
70 + repo.get_by(PageContent, page_id: page_id, name: name)
71 + end
72 +
47 73 @doc """
48 74 Retrieves a file by slug.
49 75 """
  @@ -92,10 +118,10 @@ defmodule Thesis.EctoStore do
92 118 %{"name" => name, "content" => content, "content_type" => content_type} = new_contents
93 119
94 120 page_id = page_id_or_global(new_contents, page)
95 - page_content = PageContent.find(preloaded_contents, page_id, name) ||
96 - %PageContent{page_id: page_id, name: name}
97 121
98 - PageContent.changeset(page_content, %{
122 + existing_page_content = page_content_or_new(page_id, name, preloaded_contents)
123 +
124 + PageContent.changeset(existing_page_content, %{
99 125 content: content,
100 126 content_type: content_type,
101 127 meta: new_contents["meta"]
Loading more files…