Current section
37 Versions
Jump to
Current section
37 Versions
Compare versions
12
files changed
+266
additions
-359
deletions
| @@ -10,11 +10,13 @@ the same name and author. | |
| 10 10 | |
| 11 11 | ## Installation and Configuration |
| 12 12 | |
| 13 | + _If you are having problems, view `README_INSTALL.md` for manual instructions._ |
| 14 | + |
| 13 15 | #### 1. Add thesis to your `mix.exs`: |
| 14 16 | |
| 15 17 | ```elixir |
| 16 18 | def deps do |
| 17 | - [{:thesis, "~> 0.0.3"}] |
| 19 | + [{:thesis, "~> 0.0.5"}] |
| 18 20 | end |
| 19 21 | |
| 20 22 | def application do |
| @@ -24,14 +26,154 @@ end | |
| 24 26 | |
| 25 27 | #### 2. Run `mix thesis.install` |
| 26 28 | |
| 27 | - This will add Thesis to your `package.json`, `config.exs`, and `web.ex`, |
| 28 | - and generate a migration and an authorization module. |
| 29 | + This install script will add Thesis to your `config.exs` and `web.ex`, as well |
| 30 | + as generate a migration and an authorization module in `lib/thesis_auth.ex`. |
| 31 | + |
| 32 | + #### 3. Add the Thesis editor to your layout |
| 33 | + |
| 34 | + ```eex |
| 35 | + <body> |
| 36 | + <%= thesis_editor(@conn) %> |
| 37 | + ``` |
| 38 | + |
| 39 | + #### 4. Run `mix ecto.migrate` |
| 40 | + |
| 41 | + ``` |
| 42 | + $ mix ecto.migrate |
| 43 | + ``` |
| 29 44 | |
| 30 45 | ## Making Pages Editable |
| 31 46 | |
| 32 | - TODO |
| 47 | + Use the `Thesis.View.content/4` view helper function to make a content area |
| 48 | + editable. If you added `use Thesis.View` in your `web.ex` file, this function |
| 49 | + is already available on all of your views. |
| 50 | + |
| 51 | + Thesis will add a wrapper `<div>` around editable HTML and plain-text content |
| 52 | + areas. |
| 53 | + |
| 54 | + ### Rich Text Areas |
| 55 | + |
| 56 | + Simply wrap your HTML in a `content` function call. |
| 57 | + |
| 58 | + ```eex |
| 59 | + <h1>Title</h1> |
| 60 | + <p> |
| 61 | + Here's my default description! |
| 62 | + </p> |
| 63 | + ``` |
| 64 | + |
| 65 | + becomes... |
| 66 | + |
| 67 | + ```eex |
| 68 | + <%= content(@conn, "Section identifier", :html) do %> |
| 69 | + <h1>Title</h1> |
| 70 | + <p> |
| 71 | + Here's my default description! |
| 72 | + </p> |
| 73 | + <% end %> |
| 74 | + ``` |
| 75 | + |
| 76 | + ### Plain Text Areas |
| 77 | + |
| 78 | + For plain-text, provide a `do:` option for default text. |
| 79 | + |
| 80 | + ```eex |
| 81 | + <h1>My Title</h1> |
| 82 | + ``` |
| 83 | + |
| 84 | + becomes... |
| 85 | + |
| 86 | + ```eex |
| 87 | + <h1><%= content(@conn, "Title identifier", :text, do: "My Title") %></h1> |
| 88 | + ``` |
| 33 89 | |
| 34 90 | ## Authorization |
| 35 91 | |
| 36 | - TODO |
| 92 | + You probably don't want your website editable by the world. Thesis doesn't |
| 93 | + force you to use any particular authorization strategy. Instead, Thesis will |
| 94 | + call your auth module's `can_edit_page?/1` function and provide the current |
| 95 | + `conn`, which can be used to extract current user session data, the current |
| 96 | + page, and then decide on your own how that should affect authorization. |
| 37 97 | |
| 98 | + Here's an example which we use on our own website, [https://infinite.red](https://infinite.red): |
| 99 | + |
| 100 | + ```elixir |
| 101 | + defmodule IrWebsite.ThesisAuth do |
| 102 | + def page_is_editable?(conn) do |
| 103 | + !!IrWebsite.AuthController.current_user(conn) |
| 104 | + end |
| 105 | + end |
| 106 | + ``` |
| 107 | + |
| 108 | + In our `auth_controller.ex` file, the `current_user/1` function looks like this: |
| 109 | + |
| 110 | + ```elixir |
| 111 | + def current_user(conn) do |
| 112 | + get_session(conn, :current_user) |
| 113 | + end |
| 114 | + ``` |
| 115 | + |
| 116 | + So, in this case, we're simply checking to see if the user has been logged in |
| 117 | + or not. Since we're verifying their identity before letting them log in, |
| 118 | + it's safe for us to assume that if they're logged in, they have permission to |
| 119 | + edit the page. |
| 120 | + |
| 121 | + ## What Thesis Isn't |
| 122 | + |
| 123 | + 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 |
| 124 | + not likely to be in the future. |
| 125 | + |
| 126 | + _We reserve the right to change our mind, however. :-)_ |
| 127 | + |
| 128 | + * Not a WordPress Replacement |
| 129 | + * Not a full featured CMS |
| 130 | + * Not a full featured WYSIWYG editor |
| 131 | + * Not an authentication or permission system |
| 132 | + * Not a library that works well outside of Phoenix |
| 133 | + |
| 134 | + |
| 135 | + ## Contributing |
| 136 | + |
| 137 | + We're committed to making Thesis the go-to content editing system for Phoenix |
| 138 | + websites. Please help us improve! |
| 139 | + |
| 140 | + 1. Fork it |
| 141 | + 2. Create your feature branch (`git checkout -b my-new-feature`) |
| 142 | + 3. Commit your changes (`git commit -am 'Add some feature'`) |
| 143 | + 4. Write tests for your new feature |
| 144 | + 5. Run `rake spec` in the root directory to ensure that all tests pass. |
| 145 | + 6. Push to the branch (`git push origin my-new-feature`) |
| 146 | + 7. Create new Pull Request |
| 147 | + |
| 148 | + ### Key Contributors |
| 149 | + |
| 150 | + * Jamon Holmgren [@jamonholmgren](https://twitter.com/jamonholmgren) |
| 151 | + * Ken Miller [@seriousken](https://github.com/kemiller) |
| 152 | + * Daniel Berkompas [@dberkom](https://twitter.com/dberkom) |
| 153 | + |
| 154 | + Also supported by others on the [Infinite Red](https://infinite.red) team. |
| 155 | + |
| 156 | + ### License |
| 157 | + |
| 158 | + Copyright (c) 2016 Infinite Red, Inc. |
| 159 | + |
| 160 | + MIT License |
| 161 | + |
| 162 | + Permission is hereby granted, free of charge, to any person obtaining |
| 163 | + a copy of this software and associated documentation files (the |
| 164 | + "Software"), to deal in the Software without restriction, including |
| 165 | + without limitation the rights to use, copy, modify, merge, publish, |
| 166 | + distribute, sublicense, and/or sell copies of the Software, and to |
| 167 | + permit persons to whom the Software is furnished to do so, subject to |
| 168 | + the following conditions: |
| 169 | + |
| 170 | + The above copyright notice and this permission notice shall be |
| 171 | + included in all copies or substantial portions of the Software. |
| 172 | + |
| 173 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 174 | + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 175 | + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 176 | + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
| 177 | + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
| 178 | + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| 179 | + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| @@ -0,0 +1,80 @@ | |
| 1 | + # Thesis - Manual Installation |
| 2 | + |
| 3 | + For automatic setup, see `README.md`. |
| 4 | + |
| 5 | + #### 1. Add thesis to your `mix.exs`: |
| 6 | + |
| 7 | + ```elixir |
| 8 | + def deps do |
| 9 | + [{:thesis, "~> 0.0.5"}] |
| 10 | + end |
| 11 | + |
| 12 | + def application do |
| 13 | + [applications: [:thesis]] |
| 14 | + end |
| 15 | + ``` |
| 16 | + |
| 17 | + Run `mix deps.get`. |
| 18 | + |
| 19 | + #### 2. Update your `config/config.exs` |
| 20 | + |
| 21 | + ```elixir |
| 22 | + config :thesis, |
| 23 | + store: Thesis.Store, |
| 24 | + authorization: IrWebsite.ThesisAuth |
| 25 | + config :thesis, Thesis.Store, repo: <MyApp>.Repo |
| 26 | + ``` |
| 27 | + |
| 28 | + #### 3. Create `lib/thesis_auth.ex` |
| 29 | + |
| 30 | + ```elixir |
| 31 | + defmodule <MyApp>.ThesisAuth do |
| 32 | + def page_is_editable?(conn) do |
| 33 | + true |
| 34 | + end |
| 35 | + end |
| 36 | + ``` |
| 37 | + |
| 38 | + #### 4. Generate a migration |
| 39 | + |
| 40 | + ```elixir |
| 41 | + defmodule <MyApp>.Repo.Migrations.CreateThesisTables do |
| 42 | + use Ecto.Migration |
| 43 | + |
| 44 | + def change do |
| 45 | + create table(:thesis_pages) do |
| 46 | + add :slug, :string |
| 47 | + add :title, :string |
| 48 | + add :description, :string |
| 49 | + |
| 50 | + timestamps |
| 51 | + end |
| 52 | + |
| 53 | + create table(:thesis_page_contents) do |
| 54 | + add :page_id, :integer |
| 55 | + add :name, :string, nil: false |
| 56 | + add :content, :text, default: "Edit this content area" |
| 57 | + add :content_type, :string, default: "html" |
| 58 | + |
| 59 | + timestamps |
| 60 | + end |
| 61 | + end |
| 62 | + end |
| 63 | + ``` |
| 64 | + |
| 65 | + #### 5. Add Thesis to your layout |
| 66 | + |
| 67 | + ```eex |
| 68 | + <body> |
| 69 | + <%= thesis_editor(@conn) %> |
| 70 | + ``` |
| 71 | + |
| 72 | + #### 6. Run `mix ecto.migrate` |
| 73 | + |
| 74 | + ``` |
| 75 | + $ mix ecto.migrate |
| 76 | + ``` |
| 77 | + |
| 78 | + #### 7. Done! |
| 79 | + |
| 80 | + Now, start adding content areas. See the `README.md` for further instructions. |
| @@ -10,9 +10,9 @@ | |
| 10 10 | <<"lib/thesis/models/page.ex">>,<<"lib/thesis/models/page_content.ex">>, |
| 11 11 | <<"lib/thesis/router.ex">>,<<"lib/thesis/store.ex">>, |
| 12 12 | <<"lib/thesis/view.ex">>,<<"priv/static/thesis-editor.js">>, |
| 13 | - <<"priv/static/thesis-old.js">>,<<"priv/static/thesis.css">>, |
| 14 | - <<"priv/static/thesis.js">>,<<"priv/templates/thesis.install/auth.exs">>, |
| 13 | + <<"priv/static/thesis.css">>, |
| 15 14 | <<"priv/templates/thesis.install/migration.exs">>, |
| 15 | + <<"priv/templates/thesis.install/thesis_auth.exs">>, |
| 16 16 | <<"web/static/components/add_button.js">>, |
| 17 17 | <<"web/static/components/cancel_button.js">>, |
| 18 18 | <<"web/static/components/delete_button.js">>, |
| @@ -23,10 +23,10 @@ | |
| 23 23 | <<"web/static/components/settings_button.js">>, |
| 24 24 | <<"web/static/components/style_button.js">>, |
| 25 25 | <<"web/static/thesis-editor.js">>,<<"web/static/utilities/net.js">>, |
| 26 | - <<"mix.exs">>,<<"README.md">>,<<"package.json">>]}. |
| 26 | + <<"mix.exs">>,<<"README.md">>,<<"README_INSTALL.md">>,<<"package.json">>]}. |
| 27 27 | {<<"licenses">>,[<<"MIT">>]}. |
| 28 28 | {<<"links">>, |
| 29 | - [{<<"Docs">>,<<"https://hexdocs.pm/thesis/0.0.5/api-reference.html">>}, |
| 29 | + [{<<"Docs">>,<<"https://hexdocs.pm/thesis/0.0.6/api-reference.html">>}, |
| 30 30 | {<<"GitHub">>,<<"https://github.com/infinite_red/thesis">>}]}. |
| 31 31 | {<<"maintainers">>, |
| 32 32 | [<<"Jamon Holmgren">>,<<"Ken Miller">>,<<"Daniel Berkompas">>]}. |
| @@ -52,4 +52,4 @@ | |
| 52 52 | [{<<"app">>,<<"plug">>}, |
| 53 53 | {<<"optional">>,false}, |
| 54 54 | {<<"requirement">>,<<"~> 1.0">>}]}]}. |
| 55 | - {<<"version">>,<<"0.0.5">>}. |
| 55 | + {<<"version">>,<<"0.0.6">>}. |
| @@ -10,13 +10,12 @@ defmodule Mix.Tasks.Thesis.Install do | |
| 10 10 | |
| 11 11 | def run(_args) do |
| 12 12 | thesis_templates |
| 13 | - thesis_npm |
| 14 13 | thesis_config |
| 15 14 | thesis_web |
| 16 15 | end |
| 17 16 | |
| 18 17 | def thesis_templates do |
| 19 | - template_files = [ {"priv/templates/thesis.install/auth.exs", "lib/auth.ex" } ] |
| 18 | + template_files = [ {"priv/templates/thesis.install/thesis_auth.exs", "lib/thesis_auth.ex" } ] |
| 20 19 | migration_exists = File.ls!("priv/repo/migrations") |> Enum.map(fn (f) -> String.contains?(f, "create_thesis_tables") end) |> Enum.any? |
| 21 20 | unless migration_exists do |
| 22 21 | template_files = [{"priv/templates/thesis.install/migration.exs", "priv/repo/migrations/#{timestamp}_create_thesis_tables.exs"} | template_files] |
| @@ -28,11 +27,6 @@ defmodule Mix.Tasks.Thesis.Install do | |
| 28 27 | |> Stream.run |
| 29 28 | end |
| 30 29 | |
| 31 | - def thesis_npm do |
| 32 | - status_msg("updating", "package.json") |
| 33 | - System.cmd("npm", ["install", "./deps/thesis", "--save"]) |
| 34 | - end |
| 35 | - |
| 36 30 | def thesis_config do |
| 37 31 | status_msg("updating", "config/config.exs") |
| 38 32 | dest_file_path = Path.join [File.cwd! | ~w(config config.exs)] |
| @@ -39,7 +39,7 @@ defmodule Thesis.View do | |
| 39 39 | def thesis_editor(conn) do |
| 40 40 | if editable?(conn) do |
| 41 41 | editor = content_tag(:div, "", id: "thesis-editor-container") |
| 42 | - safe_concat([thesis_style, editor]) |
| 42 | + safe_concat([thesis_style, editor, thesis_js]) |
| 43 43 | end |
| 44 44 | end |
| 45 45 | |
| @@ -47,6 +47,27 @@ defmodule Thesis.View do | |
| 47 47 | content_tag :style, @styles |
| 48 48 | end |
| 49 49 | |
| 50 | + def thesis_js do |
| 51 | + raw """ |
| 52 | + <script> |
| 53 | + ;(function () { |
| 54 | + var loadThesis = function () { |
| 55 | + var script = document.createElement('script') |
| 56 | + script.src = '/thesis/thesis-editor.js' |
| 57 | + |
| 58 | + document.head.appendChild(script) |
| 59 | + } |
| 60 | + |
| 61 | + document.addEventListener('DOMContentLoaded', function (event) { |
| 62 | + if (document.querySelector('#thesis-editor-container')) { |
| 63 | + loadThesis() |
| 64 | + } |
| 65 | + }) |
| 66 | + })() |
| 67 | + </script> |
| 68 | + """ |
| 69 | + end |
| 70 | + |
| 50 71 | defp editable?(conn) do |
| 51 72 | Application.get_env(:thesis, :authorization).page_is_editable?(conn) |
| 52 73 | end |
Loading more files…