Current section
37 Versions
Jump to
Current section
37 Versions
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…