Merge branch 'master' of gitlab.com:mythic-insight/legendary

This commit is contained in:
Robert Prehn 2021-03-25 17:22:18 -05:00
commit 1240996e4c
194 changed files with 999 additions and 673 deletions

22
LICENSE Normal file
View file

@ -0,0 +1,22 @@
# MIT License
Copyright (c) 2020 Robert Prehn & Mythic Insight
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -1,6 +1,27 @@
# Legendary # Overview
# Up and Running Legendary is a boilerplate for developing [PETAL-stack](https://changelog.com/posts/petal-the-end-to-end-web-stack)
Phoenix/Elixir applications without reinventing the wheel. Out-of-the-box, we
include many features that are commonly needed in web applications:
- Features
- Authentication & Authorization
- Admin interface & dashboard
- Lightweight content management / blogging
- Background & scheduled jobs with Oban
- Frontend Frameworks
- Tailwind CSS
- Alpine JS
- Fluid HTML email templates
- Full CI / DevOps scripts included
We got tired of setting these things up from scratch on every Phoenix application.
So, we built a boilerplate that lets you start with the unique & interesting thing
that only your application does. We have a roadmap for future feature development
because we still think there are a lot more things we can do to make Phoenix
development better.
## Up and Running
In order to start the server, run `script/server`. Any dependencies required In order to start the server, run `script/server`. Any dependencies required
will be installed automatically using [brew](https://brew.sh/), will be installed automatically using [brew](https://brew.sh/),
@ -8,7 +29,24 @@ will be installed automatically using [brew](https://brew.sh/),
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
# CI Configuration ## Application Development
Your main app lives in apps/app/ and that is where you will do most of your
development there. This is a normal Phoenix application and you can develop it
as such. Any resources which apply to developing Phoenix applications will apply
inside of the app. See the [Phoenix Guides](https://hexdocs.pm/phoenix/overview.html)
for a good starting resource in Phoenix development.
You should not generally need to change code in the other applications which
are part of the framework-- admin, content, core. We encourage you to avoid
changing those as much as possible, because doing so will make it more difficult
to upgrade Legendary to newer versions. However, they are available to you if
you find that there are no other ways to accomplish the changes you want to
accomplish. If you find yourself adding functionality to admin, content, or core
that you feel would be beneficial to all Legendary apps, consider making a
code contribution back to the framework!
## CI Configuration
Legendary comes with gitlab CI settings which should work for you with minimal Legendary comes with gitlab CI settings which should work for you with minimal
setup. setup.
@ -17,18 +55,3 @@ The CI script will automatically tag successful builds. To do this, you will
need to configure a [CI variable](-/settings/ci_cd) named `GITLAB_TOKEN`. This need to configure a [CI variable](-/settings/ci_cd) named `GITLAB_TOKEN`. This
token should be a [personal access token](/-/profile/personal_access_tokens) with token should be a [personal access token](/-/profile/personal_access_tokens) with
`read_repository, write_repository` permissions. `read_repository, write_repository` permissions.
To start your Phoenix server:
* Install dependencies with `mix deps.get`
* Create and migrate your database with `mix ecto.setup`
* Install Node.js dependencies with `npm install` inside the `assets` directory
* Start Phoenix endpoint with `mix phx.server`
# Learn more
* Official website: https://www.phoenixframework.org/
* Guides: https://hexdocs.pm/phoenix/overview.html
* Docs: https://hexdocs.pm/phoenix
* Forum: https://elixirforum.com/c/phoenix-forum
* Source: https://github.com/phoenixframework/phoenix

View file

@ -1,12 +1,12 @@
defmodule Admin do defmodule Legendary.Admin do
@moduledoc """ @moduledoc """
The entrypoint for defining your web interface, such The entrypoint for defining your web interface, such
as controllers, views, channels and so on. as controllers, views, channels and so on.
This can be used in your application as: This can be used in your application as:
use Admin, :controller use Legendary.Admin, :controller
use Admin, :view use Legendary.Admin, :view
The definitions below will be executed for every view, The definitions below will be executed for every view,
controller, etc, so keep them short and clean, focused controller, etc, so keep them short and clean, focused
@ -19,11 +19,11 @@ defmodule Admin do
def controller do def controller do
quote do quote do
use Phoenix.Controller, namespace: Admin use Phoenix.Controller, namespace: Legendary.Admin
import Plug.Conn import Plug.Conn
import Admin.Gettext import Legendary.Admin.Gettext
alias Admin.Router.Helpers, as: Routes alias Legendary.Admin.Router.Helpers, as: Routes
end end
end end
@ -31,7 +31,7 @@ defmodule Admin do
quote do quote do
use Phoenix.View, use Phoenix.View,
root: "lib/admin/templates", root: "lib/admin/templates",
namespace: Admin namespace: Legendary.Admin
# Import convenience functions from controllers # Import convenience functions from controllers
import Phoenix.Controller, import Phoenix.Controller,
@ -54,7 +54,7 @@ defmodule Admin do
def channel do def channel do
quote do quote do
use Phoenix.Channel use Phoenix.Channel
import Admin.Gettext import Legendary.Admin.Gettext
end end
end end
@ -66,9 +66,9 @@ defmodule Admin do
# Import basic rendering functionality (render, render_layout, etc) # Import basic rendering functionality (render, render_layout, etc)
import Phoenix.View import Phoenix.View
import Admin.ErrorHelpers import Legendary.Admin.ErrorHelpers
import Admin.Gettext import Legendary.Admin.Gettext
alias Admin.Router.Helpers, as: Routes alias Legendary.Admin.Router.Helpers, as: Routes
end end
end end

View file

@ -1,4 +1,4 @@
defmodule Admin.Application do defmodule Legendary.Admin.Application do
# See https://hexdocs.pm/elixir/Application.html # See https://hexdocs.pm/elixir/Application.html
# for more information on OTP Applications # for more information on OTP Applications
@moduledoc false @moduledoc false
@ -7,25 +7,25 @@ defmodule Admin.Application do
def start(_type, _args) do def start(_type, _args) do
children = [ children = [
Admin.Repo, Legendary.Admin.Repo,
# Start the Telemetry supervisor # Start the Telemetry supervisor
Admin.Telemetry, Legendary.Admin.Telemetry,
# Start the Endpoint (http/https) # Start the Endpoint (http/https)
Admin.Endpoint Legendary.Admin.Endpoint
# Start a worker by calling: Admin.Worker.start_link(arg) # Start a worker by calling: Legendary.Admin.Worker.start_link(arg)
# {Admin.Worker, arg} # {Legendary.Admin.Worker, arg}
] ]
# See https://hexdocs.pm/elixir/Supervisor.html # See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options # for other strategies and supported options
opts = [strategy: :one_for_one, name: Admin.Supervisor] opts = [strategy: :one_for_one, name: Legendary.Admin.Supervisor]
Supervisor.start_link(children, opts) Supervisor.start_link(children, opts)
end end
# Tell Phoenix to update the endpoint configuration # Tell Phoenix to update the endpoint configuration
# whenever the application is updated. # whenever the application is updated.
def config_change(changed, _new, removed) do def config_change(changed, _new, removed) do
Admin.Endpoint.config_change(changed, removed) Legendary.Admin.Endpoint.config_change(changed, removed)
:ok :ok
end end
end end

View file

@ -1,8 +1,8 @@
defmodule Admin.UserSocket do defmodule Legendary.Admin.UserSocket do
use Phoenix.Socket use Phoenix.Socket
## Channels ## Channels
# channel "room:*", Admin.RoomChannel # channel "room:*", Legendary.Admin.RoomChannel
# Socket params are passed from the client and can # Socket params are passed from the client and can
# be used to verify and authenticate a user. After # be used to verify and authenticate a user. After
@ -27,7 +27,7 @@ defmodule Admin.UserSocket do
# Would allow you to broadcast a "disconnect" event and terminate # Would allow you to broadcast a "disconnect" event and terminate
# all active sockets and channels for a given user: # all active sockets and channels for a given user:
# #
# Admin.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{}) # Legendary.Admin.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{})
# #
# Returning `nil` makes this socket anonymous. # Returning `nil` makes this socket anonymous.
@impl true @impl true

View file

@ -1,4 +1,4 @@
defmodule Admin.Endpoint do defmodule Legendary.Admin.Endpoint do
use Phoenix.Endpoint, otp_app: :admin use Phoenix.Endpoint, otp_app: :admin
def init(_, config) do def init(_, config) do
@ -17,7 +17,7 @@ defmodule Admin.Endpoint do
signing_salt: "zGdDhvUt" signing_salt: "zGdDhvUt"
] ]
socket "/socket", Admin.UserSocket, socket "/socket", Legendary.Admin.UserSocket,
websocket: true, websocket: true,
longpoll: false longpoll: false
@ -58,5 +58,5 @@ defmodule Admin.Endpoint do
plug Plug.Head plug Plug.Head
plug Plug.Session, @session_options plug Plug.Session, @session_options
plug Pow.Plug.Session, otp_app: :admin plug Pow.Plug.Session, otp_app: :admin
plug Admin.Router plug Legendary.Admin.Router
end end

View file

@ -1,11 +1,11 @@
defmodule Admin.Gettext do defmodule Legendary.Admin.Gettext do
@moduledoc """ @moduledoc """
A module providing Internationalization with a gettext-based API. A module providing Internationalization with a gettext-based API.
By using [Gettext](https://hexdocs.pm/gettext), By using [Gettext](https://hexdocs.pm/gettext),
your module gains a set of macros for translations, for example: your module gains a set of macros for translations, for example:
import Admin.Gettext import Legendary.Admin.Gettext
# Simple translation # Simple translation
gettext("Here is the string to translate") gettext("Here is the string to translate")

View file

@ -1,4 +1,4 @@
defmodule Admin.Repo do defmodule Legendary.Admin.Repo do
use Ecto.Repo, use Ecto.Repo,
otp_app: :admin, otp_app: :admin,
adapter: Ecto.Adapters.Postgres adapter: Ecto.Adapters.Postgres

View file

@ -1,5 +1,5 @@
defmodule Admin.Router do defmodule Legendary.Admin.Router do
use Admin, :router use Legendary.Admin, :router
pipeline :browser do pipeline :browser do
plug :accepts, ["html"] plug :accepts, ["html"]
@ -10,12 +10,12 @@ defmodule Admin.Router do
end end
pipeline :require_admin do pipeline :require_admin do
plug AuthWeb.Plugs.RequireAdmin plug Legendary.AuthWeb.Plugs.RequireAdmin
end end
pipeline :api do pipeline :api do
plug :accepts, ["json"] plug :accepts, ["json"]
end end
use Admin.Routes use Legendary.Admin.Routes
end end

View file

@ -1,4 +1,4 @@
defmodule Admin.Routes do defmodule Legendary.Admin.Routes do
defmacro __using__(_opts \\ []) do defmacro __using__(_opts \\ []) do
quote do quote do
use Kaffy.Routes, scope: "/admin", pipe_through: [:require_admin] use Kaffy.Routes, scope: "/admin", pipe_through: [:require_admin]

View file

@ -1,4 +1,4 @@
defmodule Admin.Telemetry do defmodule Legendary.Admin.Telemetry do
use Supervisor use Supervisor
import Telemetry.Metrics import Telemetry.Metrics
@ -49,7 +49,7 @@ defmodule Admin.Telemetry do
[ [
# A module, function and arguments to be invoked periodically. # A module, function and arguments to be invoked periodically.
# This function must call :telemetry.execute/3 and a metric must be added above. # This function must call :telemetry.execute/3 and a metric must be added above.
# {Admin, :count_users, []} # {Legendary.Admin, :count_users, []}
] ]
end end
end end

View file

@ -1,12 +1,12 @@
defmodule Admin.ErrorHelpers do defmodule Legendary.Admin.ErrorHelpers do
@moduledoc """ @moduledoc """
Conveniences for translating and building error messages. Conveniences for translating and building error messages.
""" """
use Phoenix.HTML use Phoenix.HTML
defdelegate error_tag(form, field), to: CoreWeb.ErrorHelpers defdelegate error_tag(form, field), to: Legendary.CoreWeb.ErrorHelpers
defdelegate error_tag(form, field, opts), to: CoreWeb.ErrorHelpers defdelegate error_tag(form, field, opts), to: Legendary.CoreWeb.ErrorHelpers
@doc """ @doc """
Translates an error message using gettext. Translates an error message using gettext.
@ -30,9 +30,9 @@ defmodule Admin.ErrorHelpers do
# should be written to the errors.po file. The :count option is # should be written to the errors.po file. The :count option is
# set by Ecto and indicates we should also apply plural rules. # set by Ecto and indicates we should also apply plural rules.
if count = opts[:count] do if count = opts[:count] do
Gettext.dngettext(Admin.Gettext, "errors", msg, msg, count, opts) Gettext.dngettext(Legendary.Admin.Gettext, "errors", msg, msg, count, opts)
else else
Gettext.dgettext(Admin.Gettext, "errors", msg, opts) Gettext.dgettext(Legendary.Admin.Gettext, "errors", msg, opts)
end end
end end
end end

View file

@ -1,5 +1,5 @@
defmodule Admin.ErrorView do defmodule Legendary.Admin.ErrorView do
use Admin, :view use Legendary.Admin, :view
# If you want to customize a particular status code # If you want to customize a particular status code
# for a certain format, you may uncomment below. # for a certain format, you may uncomment below.

View file

@ -1,3 +1,3 @@
defmodule Admin.LayoutView do defmodule Legendary.Admin.LayoutView do
use Admin, :view use Legendary.Admin, :view
end end

View file

@ -1,3 +1,3 @@
defmodule Admin.PageView do defmodule Legendary.Admin.PageView do
use Admin, :view use Legendary.Admin, :view
end end

View file

@ -1,6 +1,6 @@
defmodule Admin.Kaffy.Config do defmodule Legendary.Admin.Kaffy.Config do
def create_resources(_conn) do def create_resources(_conn) do
config = Application.get_env(:admin, Admin) config = Application.get_env(:admin, Legendary.Admin)
{resources, _} = Keyword.pop(config, :resources, []) {resources, _} = Keyword.pop(config, :resources, [])

View file

@ -1,4 +1,4 @@
defmodule Admin.Kaffy.EditorExtension do defmodule Legendary.Admin.Kaffy.EditorExtension do
def stylesheets(_conn) do def stylesheets(_conn) do
[ [
{:safe, ~s(<link rel="stylesheet" href="/css/content-editor.css" />)}, {:safe, ~s(<link rel="stylesheet" href="/css/content-editor.css" />)},

View file

@ -1,10 +1,13 @@
defmodule Admin.MixProject do defmodule Legendary.Admin.MixProject do
use Mix.Project use Mix.Project
@version "2.1.3"
def project do def project do
[ [
app: :admin, app: :admin,
version: "0.1.0", version: "0.1.0",
version: @version,
build_path: "../../_build", build_path: "../../_build",
config_path: "../../config/config.exs", config_path: "../../config/config.exs",
deps_path: "../../deps", deps_path: "../../deps",
@ -25,7 +28,7 @@ defmodule Admin.MixProject do
# Type `mix help compile.app` for more information. # Type `mix help compile.app` for more information.
def application do def application do
[ [
mod: {Admin.Application, []}, mod: {Legendary.Admin.Application, []},
extra_applications: [:logger, :runtime_tools] extra_applications: [:logger, :runtime_tools]
] ]
end end

View file

@ -5,7 +5,7 @@
# Inside the script, you can read and write to any of your # Inside the script, you can read and write to any of your
# repositories directly: # repositories directly:
# #
# Content.Repo.insert!(%Content.SomeSchema{}) # Legendary.Content.Repo.insert!(%Legendary.Content.SomeSchema{})
# #
# We recommend using the bang functions (`insert!`, `update!` # We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong. # and so on) as they will fail if something goes wrong.

View file

@ -1,3 +1,3 @@
defmodule Admin.PageControllerTest do defmodule Legendary.Admin.PageControllerTest do
use Admin.ConnCase use Legendary.Admin.ConnCase
end end

View file

@ -1,10 +1,10 @@
defmodule Admin.ErrorHelpersTest do defmodule Legendary.Admin.ErrorHelpersTest do
use Admin.ConnCase use Legendary.Admin.ConnCase
import Phoenix.HTML, only: [safe_to_string: 1] import Phoenix.HTML, only: [safe_to_string: 1]
import Phoenix.HTML.Form, only: [form_for: 3] import Phoenix.HTML.Form, only: [form_for: 3]
import Admin.ErrorHelpers import Legendary.Admin.ErrorHelpers
def form do def form do
:example :example

View file

@ -1,14 +1,14 @@
defmodule Admin.ErrorViewTest do defmodule Legendary.Admin.ErrorViewTest do
use Admin.ConnCase, async: true use Legendary.Admin.ConnCase, async: true
# Bring render/3 and render_to_string/3 for testing custom views # Bring render/3 and render_to_string/3 for testing custom views
import Phoenix.View import Phoenix.View
test "renders 404.html" do test "renders 404.html" do
assert render_to_string(Admin.ErrorView, "404.html", []) == "Not Found" assert render_to_string(Legendary.Admin.ErrorView, "404.html", []) == "Not Found"
end end
test "renders 500.html" do test "renders 500.html" do
assert render_to_string(Admin.ErrorView, "500.html", []) == "Internal Server Error" assert render_to_string(Legendary.Admin.ErrorView, "500.html", []) == "Internal Server Error"
end end
end end

View file

@ -1,5 +1,5 @@
defmodule Admin.LayoutViewTest do defmodule Legendary.Admin.LayoutViewTest do
use Admin.ConnCase, async: true use Legendary.Admin.ConnCase, async: true
# When testing helpers, you may want to import Phoenix.HTML and # When testing helpers, you may want to import Phoenix.HTML and
# use functions such as safe_to_string() to convert the helper # use functions such as safe_to_string() to convert the helper

View file

@ -1,3 +1,3 @@
defmodule Admin.PageViewTest do defmodule Legendary.Admin.PageViewTest do
use Admin.ConnCase, async: true use Legendary.Admin.ConnCase, async: true
end end

View file

@ -1,4 +1,4 @@
defmodule Admin.ChannelCase do defmodule Legendary.Admin.ChannelCase do
@moduledoc """ @moduledoc """
This module defines the test case to be used by This module defines the test case to be used by
channel tests. channel tests.
@ -11,7 +11,7 @@ defmodule Admin.ChannelCase do
we enable the SQL sandbox, so changes done to the database we enable the SQL sandbox, so changes done to the database
are reverted at the end of every test. If you are using are reverted at the end of every test. If you are using
PostgreSQL, you can even run database tests asynchronously PostgreSQL, you can even run database tests asynchronously
by setting `use Admin.ChannelCase, async: true`, although by setting `use Legendary.Admin.ChannelCase, async: true`, although
this option is not recommended for other databases. this option is not recommended for other databases.
""" """
@ -21,18 +21,18 @@ defmodule Admin.ChannelCase do
quote do quote do
# Import conveniences for testing with channels # Import conveniences for testing with channels
import Phoenix.ChannelTest import Phoenix.ChannelTest
import Admin.ChannelCase import Legendary.Admin.ChannelCase
# The default endpoint for testing # The default endpoint for testing
@endpoint Admin.Endpoint @endpoint Legendary.Admin.Endpoint
end end
end end
setup tags do setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Admin.Repo) :ok = Ecto.Adapters.SQL.Sandbox.checkout(Legendary.Admin.Repo)
unless tags[:async] do unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(Admin.Repo, {:shared, self()}) Ecto.Adapters.SQL.Sandbox.mode(Legendary.Admin.Repo, {:shared, self()})
end end
:ok :ok

View file

@ -1,4 +1,4 @@
defmodule Admin.ConnCase do defmodule Legendary.Admin.ConnCase do
@moduledoc """ @moduledoc """
This module defines the test case to be used by This module defines the test case to be used by
tests that require setting up a connection. tests that require setting up a connection.
@ -11,7 +11,7 @@ defmodule Admin.ConnCase do
we enable the SQL sandbox, so changes done to the database we enable the SQL sandbox, so changes done to the database
are reverted at the end of every test. If you are using are reverted at the end of every test. If you are using
PostgreSQL, you can even run database tests asynchronously PostgreSQL, you can even run database tests asynchronously
by setting `use Admin.ConnCase, async: true`, although by setting `use Legendary.Admin.ConnCase, async: true`, although
this option is not recommended for other databases. this option is not recommended for other databases.
""" """
@ -22,20 +22,20 @@ defmodule Admin.ConnCase do
# Import conveniences for testing with connections # Import conveniences for testing with connections
import Plug.Conn import Plug.Conn
import Phoenix.ConnTest import Phoenix.ConnTest
import Admin.ConnCase import Legendary.Admin.ConnCase
alias Admin.Router.Helpers, as: Routes alias Legendary.Admin.Router.Helpers, as: Routes
# The default endpoint for testing # The default endpoint for testing
@endpoint Admin.Endpoint @endpoint Legendary.Admin.Endpoint
end end
end end
setup tags do setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(Admin.Repo) :ok = Ecto.Adapters.SQL.Sandbox.checkout(Legendary.Admin.Repo)
unless tags[:async] do unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(Admin.Repo, {:shared, self()}) Ecto.Adapters.SQL.Sandbox.mode(Legendary.Admin.Repo, {:shared, self()})
end end
{:ok, conn: Phoenix.ConnTest.build_conn()} {:ok, conn: Phoenix.ConnTest.build_conn()}

View file

@ -1,2 +1,2 @@
ExUnit.start() ExUnit.start()
Ecto.Adapters.SQL.Sandbox.mode(Admin.Repo, :manual) Ecto.Adapters.SQL.Sandbox.mode(Legendary.Admin.Repo, :manual)

View file

@ -13,6 +13,7 @@ import "../css/app.css"
// import socket from "./socket" // import socket from "./socket"
// //
import "phoenix_html" import "phoenix_html"
import "alpinejs"
import { ready } from "./utils" import { ready } from "./utils"
function togglePasswordFieldVisibility() function togglePasswordFieldVisibility()
@ -22,7 +23,7 @@ function togglePasswordFieldVisibility()
if (el.type == 'password') if (el.type == 'password')
{ {
el.type = 'text' el.type = 'text'
} }
else else
{ {
el.type = 'password' el.type = 'password'

View file

@ -1332,6 +1332,11 @@
"integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
"dev": true "dev": true
}, },
"alpinejs": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-2.8.1.tgz",
"integrity": "sha512-ETJ/k0fbiBeP+OSd5Fhj70c+zb+YRzcVbyh5DVeLT3FBWMUeUvjOSWLi53IVLPSehaT2SKmB7w08WGF2jYTqNA=="
},
"amdefine": { "amdefine": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",

View file

@ -9,6 +9,7 @@
}, },
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^5.14.0", "@fortawesome/fontawesome-free": "^5.14.0",
"alpinejs": "^2.8.1",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"csswring": "^7.0.0", "csswring": "^7.0.0",
"glob": "^7.1.6", "glob": "^7.1.6",

View file

@ -66,7 +66,7 @@ defmodule AppWeb do
# Import basic rendering functionality (render, render_layout, etc) # Import basic rendering functionality (render, render_layout, etc)
import Phoenix.View import Phoenix.View
import CoreWeb.Helpers import Legendary.CoreWeb.Helpers
import AppWeb.ErrorHelpers import AppWeb.ErrorHelpers
import AppWeb.Gettext import AppWeb.Gettext
alias AppWeb.Router.Helpers, as: Routes alias AppWeb.Router.Helpers, as: Routes

View file

@ -4,7 +4,7 @@ defmodule AppWeb.Router do
use Pow.Extension.Phoenix.Router, use Pow.Extension.Phoenix.Router,
extensions: [PowResetPassword, PowEmailConfirmation] extensions: [PowResetPassword, PowEmailConfirmation]
alias AuthWeb.Plugs.{RequireAdmin} alias Legendary.AuthWeb.Plugs.{RequireAdmin}
pipeline :browser do pipeline :browser do
plug :accepts, ["html"] plug :accepts, ["html"]
@ -57,6 +57,6 @@ defmodule AppWeb.Router do
pow_extension_routes() pow_extension_routes()
end end
use Admin.Routes use Legendary.Admin.Routes
use Content.Routes use Legendary.Content.Routes
end end

View file

@ -1,7 +1,7 @@
<nav class="flex items-center justify-between flex-wrap bg-grey-dark p-6 w-full z-10 bg-gray-800"> <nav class="flex items-center justify-between flex-wrap bg-grey-dark p-6 w-full z-10 bg-gray-800">
<div class="flex items-center flex-no-shrink text-white mr-6"> <div class="flex items-center flex-no-shrink text-white mr-6">
<a class="text-white no-underline hover:text-white hover:no-underline" href="/"> <a class="text-white no-underline hover:text-white hover:no-underline" href="/">
<span class="text-2xl pl-2"><i class="em em-grinning"></i> <%= I18n.t! "en", "site.title" %></span> <span class="text-2xl pl-2"><i class="em em-grinning"></i> <%= Legendary.I18n.t! "en", "site.title" %></span>
</a> </a>
</div> </div>
@ -31,7 +31,7 @@
</li> </li>
<%= if has_role?(@conn, :admin) do %> <%= if has_role?(@conn, :admin) do %>
<li class="mr-3"> <li class="mr-3">
<a class="inline-block py-2 px-4 text-white no-underline" href="/admin">Admin</a> <a class="inline-block py-2 px-4 text-white no-underline" href="/admin">Legendary.Admin</a>
</li> </li>
<% end %> <% end %>
<%= if Pow.Plug.current_user(@conn) do %> <%= if Pow.Plug.current_user(@conn) do %>

View file

@ -2,11 +2,11 @@ defmodule AppWeb.LayoutView do
use AppWeb, :view use AppWeb, :view
def title(view_module, template, assigns) do def title(view_module, template, assigns) do
delegate_with_default(view_module, :title, [view_module, template, assigns], I18n.t!("en", "site.title")) delegate_with_default(view_module, :title, [view_module, template, assigns], Legendary.I18n.t!("en", "site.title"))
end end
def excerpt(view_module, template, assigns) do def excerpt(view_module, template, assigns) do
delegate_with_default(view_module, :excerpt, [view_module, template, assigns], I18n.t!("en", "site.excerpt")) delegate_with_default(view_module, :excerpt, [view_module, template, assigns], Legendary.I18n.t!("en", "site.excerpt"))
end end
def feed_tag(conn, view_module, view_template, assigns) do def feed_tag(conn, view_module, view_template, assigns) do

View file

@ -5,7 +5,7 @@ defmodule App.LayoutViewTest do
describe "title/3" do describe "title/3" do
def default_title do def default_title do
I18n.t! "en", "site.title" Legendary.I18n.t! "en", "site.title"
end end
test "for nil" do test "for nil" do
@ -15,7 +15,7 @@ defmodule App.LayoutViewTest do
describe "excerpt/3" do describe "excerpt/3" do
def default_excerpt do def default_excerpt do
I18n.t! "en", "site.excerpt" Legendary.I18n.t! "en", "site.excerpt"
end end
test "for nil" do test "for nil" do

View file

@ -1,6 +1,6 @@
defmodule Content.Application do defmodule Legendary.Content.Application do
@moduledoc """ @moduledoc """
The base module of the Content application. The base module of the Legendary.Content application.
""" """
use Application use Application
@ -12,25 +12,25 @@ defmodule Content.Application do
# Define workers and child supervisors to be supervised # Define workers and child supervisors to be supervised
children = [ children = [
# Start the Ecto repository # Start the Ecto repository
supervisor(Content.Repo, []), supervisor(Legendary.Content.Repo, []),
# Start the endpoint when the application starts # Start the endpoint when the application starts
# Start your own worker by calling: Content.Worker.start_link(arg1, arg2, arg3) # Start your own worker by calling: Legendary.Content.Worker.start_link(arg1, arg2, arg3)
# worker(Content.Worker, [arg1, arg2, arg3]), # worker(Legendary.Content.Worker, [arg1, arg2, arg3]),
Content.Telemetry, Legendary.Content.Telemetry,
Content.Endpoint, Legendary.Content.Endpoint,
{Oban, oban_config()}, {Oban, oban_config()},
] ]
# See https://hexdocs.pm/elixir/Supervisor.html # See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options # for other strategies and supported options
opts = [strategy: :one_for_one, name: Content.Supervisor] opts = [strategy: :one_for_one, name: Legendary.Content.Supervisor]
Supervisor.start_link(children, opts) Supervisor.start_link(children, opts)
end end
# Tell Phoenix to update the endpoint configuration # Tell Phoenix to update the endpoint configuration
# whenever the application is updated. # whenever the application is updated.
def config_change(changed, _new, removed) do def config_change(changed, _new, removed) do
Content.Endpoint.config_change(changed, removed) Legendary.Content.Endpoint.config_change(changed, removed)
:ok :ok
end end

View file

@ -1,9 +1,9 @@
defmodule Content.Attachment do defmodule Legendary.Content.Attachment do
@moduledoc """ @moduledoc """
Helpers for dealing with "attachment"-type posts, which are generally media Helpers for dealing with "attachment"-type posts, which are generally media
uploaded to the site e.g. images. uploaded to the site e.g. images.
""" """
alias Content.Post alias Legendary.Content.Post
def dimensions(attachment) do def dimensions(attachment) do
meta = meta =

View file

@ -1,10 +1,10 @@
defmodule Content.Comment do defmodule Legendary.Content.Comment do
@moduledoc """ @moduledoc """
A comment on the site. A comment on the site.
""" """
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
alias Content.{Post} alias Legendary.Content.{Post}
schema "comments" do schema "comments" do
belongs_to :post, Post belongs_to :post, Post

View file

@ -1,4 +1,4 @@
defmodule Content.CommentAdmin do defmodule Legendary.Content.CommentAdmin do
def index(_) do def index(_) do
[ [
id: nil, id: nil,

View file

@ -1,4 +1,4 @@
defmodule Content.Commentmeta do defmodule Legendary.Content.Commentmeta do
@moduledoc """ @moduledoc """
A piece of metadata about a comment on the site. A piece of metadata about a comment on the site.
""" """

View file

@ -1,10 +1,10 @@
defmodule Content.Comments do defmodule Legendary.Content.Comments do
@moduledoc """ @moduledoc """
Functions for presenting comments on the site. Functions for presenting comments on the site.
""" """
import Ecto.Query, warn: false import Ecto.Query, warn: false
alias Content.Comment alias Legendary.Content.Comment
alias Content.Repo alias Legendary.Content.Repo
def children(parent_id, array_of_comments) do def children(parent_id, array_of_comments) do
array_of_comments array_of_comments

View file

@ -1,4 +1,4 @@
defmodule Content.Link do defmodule Legendary.Content.Link do
@moduledoc """ @moduledoc """
A link for the (deprecated) link roll feature. A link for the (deprecated) link roll feature.
""" """

View file

@ -1,4 +1,4 @@
defmodule Content.MarkupField do defmodule Legendary.Content.MarkupField do
use Ecto.Type use Ecto.Type
def type, do: :string def type, do: :string
@ -34,7 +34,7 @@ defmodule Content.MarkupField do
nil -> nil ->
"" ""
text -> text ->
Content.PostsView.process_content(text) Legendary.Content.PostsView.process_content(text)
end end
end end
end end

View file

@ -1,4 +1,4 @@
defmodule Content.Option do defmodule Legendary.Content.Option do
@moduledoc """ @moduledoc """
A configuration option for the site. A configuration option for the site.
""" """

View file

@ -1,9 +1,9 @@
defmodule Content.Options do defmodule Legendary.Content.Options do
@moduledoc """ @moduledoc """
Query the option key-value pairs for the site. Query the option key-value pairs for the site.
""" """
alias Content.Option alias Legendary.Content.Option
alias Content.Repo alias Legendary.Content.Repo
def put(key, value) do def put(key, value) do
%Option{} %Option{}

View file

@ -1,10 +1,10 @@
defmodule Content.Post do defmodule Legendary.Content.Post do
@moduledoc """ @moduledoc """
One "post" i.e. a blog post, page, attachment, or item of a custom post type. One "post" i.e. a blog post, page, attachment, or item of a custom post type.
""" """
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
alias Content.{MarkupField, Slugs} alias Legendary.Content.{MarkupField, Slugs}
@derive {Phoenix.Param, key: :name} @derive {Phoenix.Param, key: :name}
schema "posts" do schema "posts" do
@ -30,13 +30,13 @@ defmodule Content.Post do
field :mime_type, :string field :mime_type, :string
field :comment_count, :integer field :comment_count, :integer
field :sticky, :boolean, [virtual: true, default: false] field :sticky, :boolean, [virtual: true, default: false]
has_many :metas, Content.Postmeta has_many :metas, Legendary.Content.Postmeta
has_many :comments, Content.Comment has_many :comments, Legendary.Content.Comment
has_many :term_relationships, Content.TermRelationship, foreign_key: :object_id has_many :term_relationships, Legendary.Content.TermRelationship, foreign_key: :object_id
has_many :categories, through: [:term_relationships, :category, :term] has_many :categories, through: [:term_relationships, :category, :term]
has_many :tags, through: [:term_relationships, :tag, :term] has_many :tags, through: [:term_relationships, :tag, :term]
has_one :format, through: [:term_relationships, :format, :term] has_one :format, through: [:term_relationships, :format, :term]
belongs_to :author, Auth.User belongs_to :author, Legendary.Auth.User
end end
def changeset(struct, params \\ %{}) do def changeset(struct, params \\ %{}) do
@ -108,20 +108,20 @@ defmodule Content.Post do
content_page_count(struct) > 1 content_page_count(struct) > 1
end end
def metas_map(%Content.Post{} = struct) do def metas_map(%Legendary.Content.Post{} = struct) do
struct.metas struct.metas
|> Enum.map(&({&1.key, &1.value})) |> Enum.map(&({&1.key, &1.value}))
|> Map.new |> Map.new
end end
def maybe_put_guid(changeset) do def maybe_put_guid(changeset) do
import Content.Router.Helpers, only: [url: 1, posts_url: 3] import Legendary.Content.Router.Helpers, only: [url: 1, posts_url: 3]
slug = changeset |> get_field(:name) slug = changeset |> get_field(:name)
case slug do case slug do
nil -> changeset nil -> changeset
_ -> _ ->
base = url(CoreWeb.Endpoint) base = url(Legendary.CoreWeb.Endpoint)
changeset changeset
|> put_default(:guid, posts_url(URI.merge(base, "/pages"), :show, slug)) |> put_default(:guid, posts_url(URI.merge(base, "/pages"), :show, slug))

View file

@ -1,4 +1,4 @@
defmodule Content.PostAdmin do defmodule Legendary.Content.PostAdmin do
import Ecto.Query, only: [from: 2] import Ecto.Query, only: [from: 2]
def singular_name(_) do def singular_name(_) do
@ -10,11 +10,11 @@ defmodule Content.PostAdmin do
end end
def create_changeset(schema, attrs) do def create_changeset(schema, attrs) do
Content.Post.changeset(schema, attrs) Legendary.Content.Post.changeset(schema, attrs)
end end
def update_changeset(schema, attrs) do def update_changeset(schema, attrs) do
Content.Post.changeset(schema, attrs) Legendary.Content.Post.changeset(schema, attrs)
end end
def index(_) do def index(_) do
@ -31,13 +31,13 @@ defmodule Content.PostAdmin do
def form_fields(_) do def form_fields(_) do
authors_query = authors_query =
from u in Auth.User, from u in Legendary.Auth.User,
where: "admin" in u.roles, where: "admin" in u.roles,
select: [u.email, u.id] select: [u.email, u.id]
authors = authors =
authors_query authors_query
|> Content.Repo.all() |> Legendary.Content.Repo.all()
|> Enum.map(fn [email, id] -> |> Enum.map(fn [email, id] ->
{email, id} {email, id}
end) end)

View file

@ -1,4 +1,4 @@
defmodule Content.Postmeta do defmodule Legendary.Content.Postmeta do
@moduledoc """ @moduledoc """
An item of metadata about a post. An item of metadata about a post.
""" """
@ -6,7 +6,7 @@ defmodule Content.Postmeta do
import Ecto.Changeset import Ecto.Changeset
schema "postmeta" do schema "postmeta" do
belongs_to :post, Content.Post belongs_to :post, Legendary.Content.Post
field :key, :string field :key, :string
field :value, :string field :value, :string
end end

View file

@ -1,15 +1,15 @@
defmodule Content.Posts do defmodule Legendary.Content.Posts do
@page_size 3 @page_size 3
@moduledoc """ @moduledoc """
The Content context. The Legendary.Content context.
""" """
import Ecto.Query, warn: false import Ecto.Query, warn: false
alias Content.Repo alias Legendary.Content.Repo
alias Content.Option alias Legendary.Content.Option
alias Content.Post alias Legendary.Content.Post
alias Ecto.Changeset alias Ecto.Changeset
@preloads [:metas, :author, :categories, :tags, :comments, :format] @preloads [:metas, :author, :categories, :tags, :comments, :format]

View file

@ -1,4 +1,4 @@
defmodule Content.Repo do defmodule Legendary.Content.Repo do
use Ecto.Repo, use Ecto.Repo,
otp_app: :content, otp_app: :content,
adapter: Ecto.Adapters.Postgres adapter: Ecto.Adapters.Postgres

View file

@ -1,9 +1,9 @@
defmodule Content.Sitemaps do defmodule Legendary.Content.Sitemaps do
@moduledoc """ @moduledoc """
This module generates sitemaps for the website and pings search engines as This module generates sitemaps for the website and pings search engines as
appropriate. appropriate.
""" """
alias Content.{Endpoint, Post, Posts, Repo, Router.Helpers, Terms} alias Legendary.Content.{Endpoint, Post, Posts, Repo, Router.Helpers, Terms}
import Ecto.Query import Ecto.Query
require Logger require Logger
@ -14,7 +14,7 @@ defmodule Content.Sitemaps do
host: "https://#{Application.get_env(:content, Endpoint)[:url][:host]}", host: "https://#{Application.get_env(:content, Endpoint)[:url][:host]}",
files_path: "tmp/sitemap/", files_path: "tmp/sitemap/",
public_path: "", public_path: "",
adapter: Content.SitemapStorage adapter: Legendary.Content.SitemapStorage
@impl Oban.Worker @impl Oban.Worker
def perform(_job) do def perform(_job) do

View file

@ -1,10 +1,10 @@
defmodule Content.SitemapStorage do defmodule Legendary.Content.SitemapStorage do
@moduledoc """ @moduledoc """
This module serves as a storage adapter for the Sitemap package. It writes This module serves as a storage adapter for the Sitemap package. It writes
the sitemap as an attachment post into the system, so that the CMS will the sitemap as an attachment post into the system, so that the CMS will
serve it up. serve it up.
""" """
alias Content.{Endpoint, Post, Repo, Router.Helpers} alias Legendary.Content.{Endpoint, Post, Repo, Router.Helpers}
alias Ecto.Changeset alias Ecto.Changeset
alias Sitemap.{Location} alias Sitemap.{Location}
import Ecto.Query import Ecto.Query

View file

@ -1,9 +1,9 @@
defmodule Content.Slugs do defmodule Legendary.Content.Slugs do
@moduledoc """ @moduledoc """
Provides functions for working with post slugs and ensuring that they are unique. Provides functions for working with post slugs and ensuring that they are unique.
""" """
import Ecto.{Changeset, Query} import Ecto.{Changeset, Query}
alias Content.{Post, Repo} alias Legendary.Content.{Post, Repo}
def ensure_post_has_slug(changeset) do def ensure_post_has_slug(changeset) do
cond do cond do

View file

@ -1,4 +1,4 @@
defmodule Content.Term do defmodule Legendary.Content.Term do
@moduledoc """ @moduledoc """
Represents one 'term', i.e. a grouping under a taxonomy. Represents one 'term', i.e. a grouping under a taxonomy.
""" """

View file

@ -1,10 +1,10 @@
defmodule Content.TermRelationship do defmodule Legendary.Content.TermRelationship do
@moduledoc """ @moduledoc """
Maintains the relationship between a term_taxonomy and a post / page / or object. Maintains the relationship between a term_taxonomy and a post / page / or object.
""" """
use Ecto.Schema use Ecto.Schema
import Ecto.Changeset import Ecto.Changeset
alias Content.{Post} alias Legendary.Content.{Post}
@primary_key {:object_id, :integer, []} @primary_key {:object_id, :integer, []}
@primary_key {:term_taxonomy_id, :integer, []} @primary_key {:term_taxonomy_id, :integer, []}
@ -12,21 +12,21 @@ defmodule Content.TermRelationship do
field :term_order, :integer field :term_order, :integer
belongs_to :post, Post, foreign_key: :object_id, references: :id belongs_to :post, Post, foreign_key: :object_id, references: :id
belongs_to :term_taxonomy, belongs_to :term_taxonomy,
Content.TermTaxonomy, Legendary.Content.TermTaxonomy,
foreign_key: :term_taxonomy_id, foreign_key: :term_taxonomy_id,
define_field: false define_field: false
belongs_to :category, belongs_to :category,
Content.TermTaxonomy, Legendary.Content.TermTaxonomy,
foreign_key: :term_taxonomy_id, foreign_key: :term_taxonomy_id,
define_field: false, define_field: false,
where: [taxonomy: "category"] where: [taxonomy: "category"]
belongs_to :tag, belongs_to :tag,
Content.TermTaxonomy, Legendary.Content.TermTaxonomy,
foreign_key: :term_taxonomy_id, foreign_key: :term_taxonomy_id,
define_field: false, define_field: false,
where: [taxonomy: "post_tag"] where: [taxonomy: "post_tag"]
belongs_to :format, belongs_to :format,
Content.TermTaxonomy, Legendary.Content.TermTaxonomy,
foreign_key: :term_taxonomy_id, foreign_key: :term_taxonomy_id,
define_field: false, define_field: false,
where: [taxonomy: "post_format"] where: [taxonomy: "post_format"]

View file

@ -1,4 +1,4 @@
defmodule Content.TermTaxonomy do defmodule Legendary.Content.TermTaxonomy do
@moduledoc """ @moduledoc """
A record in a taxonomy which organizes terms and posts in the system. A record in a taxonomy which organizes terms and posts in the system.
""" """
@ -10,7 +10,7 @@ defmodule Content.TermTaxonomy do
field :description, :string field :description, :string
field :parent, :integer field :parent, :integer
field :count, :integer field :count, :integer
belongs_to :term, Content.Term belongs_to :term, Legendary.Content.Term
end end
def changeset(struct, params \\ %{}) do def changeset(struct, params \\ %{}) do

View file

@ -1,4 +1,4 @@
defmodule Content.Termmeta do defmodule Legendary.Content.Termmeta do
@moduledoc """ @moduledoc """
Represents one piece of metadata around one "term" (a grouping under a taxonomy). Represents one piece of metadata around one "term" (a grouping under a taxonomy).
""" """

View file

@ -1,4 +1,4 @@
defmodule Content.Terms do defmodule Legendary.Content.Terms do
@moduledoc """ @moduledoc """
This module contains functions for retrieving, manipulating, and saving This module contains functions for retrieving, manipulating, and saving
Terms. Terms.
@ -7,8 +7,8 @@ defmodule Content.Terms do
import Ecto.Query import Ecto.Query
def categories do def categories do
from t in Content.Term, from t in Legendary.Content.Term,
join: tt in Content.TermTaxonomy, join: tt in Legendary.Content.TermTaxonomy,
on: t.id == tt.term_id, on: t.id == tt.term_id,
where: tt.taxonomy == "category" where: tt.taxonomy == "category"
end end

View file

@ -1,12 +1,12 @@
defmodule Content do defmodule Legendary.Content do
@moduledoc """ @moduledoc """
The entrypoint for defining your web interface, such The entrypoint for defining your web interface, such
as controllers, views, channels and so on. as controllers, views, channels and so on.
This can be used in your application as: This can be used in your application as:
use Content, :controller use Legendary.Content, :controller
use Content, :view use Legendary.Content, :view
The definitions below will be executed for every view, The definitions below will be executed for every view,
controller, etc, so keep them short and clean, focused controller, etc, so keep them short and clean, focused
@ -19,11 +19,11 @@ defmodule Content do
def controller do def controller do
quote do quote do
use Phoenix.Controller, namespace: Content use Phoenix.Controller, namespace: Legendary.Content
import Plug.Conn import Plug.Conn
import Content.Gettext import Legendary.Content.Gettext
alias Content.Router.Helpers, as: Routes alias Legendary.Content.Router.Helpers, as: Routes
end end
end end
@ -31,7 +31,7 @@ defmodule Content do
quote do quote do
use Phoenix.View, use Phoenix.View,
root: "lib/content_web/templates", root: "lib/content_web/templates",
namespace: Content, namespace: Legendary.Content,
pattern: "**/*" pattern: "**/*"
use PhoenixHtmlSanitizer, :basic_html use PhoenixHtmlSanitizer, :basic_html
@ -62,7 +62,7 @@ defmodule Content do
def channel do def channel do
quote do quote do
use Phoenix.Channel use Phoenix.Channel
import Content.Gettext import Legendary.Content.Gettext
end end
end end
@ -74,11 +74,11 @@ defmodule Content do
# Import basic rendering functionality (render, render_layout, etc) # Import basic rendering functionality (render, render_layout, etc)
import Phoenix.View import Phoenix.View
import CoreWeb.Helpers import Legendary.CoreWeb.Helpers
import Content.ErrorHelpers import Legendary.Content.ErrorHelpers
import Content.Gettext import Legendary.Content.Gettext
alias Content.Router.Helpers, as: Routes alias Legendary.Content.Router.Helpers, as: Routes
end end
end end

View file

@ -1,8 +1,8 @@
defmodule Content.UserSocket do defmodule Legendary.Content.UserSocket do
use Phoenix.Socket use Phoenix.Socket
## Channels ## Channels
# channel "room:*", Content.RoomChannel # channel "room:*", Legendary.Content.RoomChannel
# Socket params are passed from the client and can # Socket params are passed from the client and can
# be used to verify and authenticate a user. After # be used to verify and authenticate a user. After
@ -27,7 +27,7 @@ defmodule Content.UserSocket do
# Would allow you to broadcast a "disconnect" event and terminate # Would allow you to broadcast a "disconnect" event and terminate
# all active sockets and channels for a given user: # all active sockets and channels for a given user:
# #
# Content.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{}) # Legendary.Content.Endpoint.broadcast("user_socket:#{user.id}", "disconnect", %{})
# #
# Returning `nil` makes this socket anonymous. # Returning `nil` makes this socket anonymous.
@impl true @impl true

View file

@ -1,10 +1,9 @@
defmodule Content.CommentController do defmodule Legendary.Content.CommentController do
use Content, :controller use Legendary.Content, :controller
alias Content alias Legendary.Content.Comments
alias Content.Comments alias Legendary.Content.Post
alias Content.Post alias Legendary.Content.Repo
alias Content.Repo
import Ecto.Query import Ecto.Query

View file

@ -1,7 +1,7 @@
defmodule Content.FeedsController do defmodule Legendary.Content.FeedsController do
use Content, :controller use Legendary.Content, :controller
alias Content.{Posts} alias Legendary.Content.{Posts}
plug :put_layout, false when action in [:preview] plug :put_layout, false when action in [:preview]

View file

@ -1,5 +1,5 @@
defmodule Content.PostPasswordController do defmodule Legendary.Content.PostPasswordController do
use Content, :controller use Legendary.Content, :controller
def create(conn, %{"post_password" => post_password}) do def create(conn, %{"post_password" => post_password}) do
conn = put_session(conn, "post_password", post_password) conn = put_session(conn, "post_password", post_password)

View file

@ -1,7 +1,7 @@
defmodule Content.PostsController do defmodule Legendary.Content.PostsController do
use Content, :controller use Legendary.Content, :controller
alias Content.{Options, Posts} alias Legendary.Content.{Options, Posts}
plug :put_layout, false when action in [:preview] plug :put_layout, false when action in [:preview]
@ -83,7 +83,7 @@ defmodule Content.PostsController do
router = router =
case conn do case conn do
%{private: %{phoenix_router: router}} -> router %{private: %{phoenix_router: router}} -> router
_ -> Content.Router _ -> Legendary.Content.Router
end end
# The static page we're looking for is missing, so this is just a 404 # The static page we're looking for is missing, so this is just a 404

View file

@ -1,7 +1,7 @@
defmodule Content.SitemapController do defmodule Legendary.Content.SitemapController do
use Content, :controller use Legendary.Content, :controller
alias Content.{Posts, Repo, Terms} alias Legendary.Content.{Posts, Repo, Terms}
import Ecto.Query import Ecto.Query

View file

@ -1,4 +1,4 @@
defmodule Content.Endpoint do defmodule Legendary.Content.Endpoint do
use Phoenix.Endpoint, otp_app: :content use Phoenix.Endpoint, otp_app: :content
def init(_, config) do def init(_, config) do
@ -17,7 +17,7 @@ defmodule Content.Endpoint do
signing_salt: "wfYQp84C" signing_salt: "wfYQp84C"
] ]
socket "/socket", Content.UserSocket, socket "/socket", Legendary.Content.UserSocket,
websocket: true, websocket: true,
longpoll: false longpoll: false
@ -58,5 +58,5 @@ defmodule Content.Endpoint do
plug Plug.Head plug Plug.Head
plug Plug.Session, @session_options plug Plug.Session, @session_options
plug Pow.Plug.Session, otp_app: :content plug Pow.Plug.Session, otp_app: :content
plug Content.Router plug Legendary.Content.Router
end end

View file

@ -1,11 +1,11 @@
defmodule Content.Gettext do defmodule Legendary.Content.Gettext do
@moduledoc """ @moduledoc """
A module providing Internationalization with a gettext-based API. A module providing Internationalization with a gettext-based API.
By using [Gettext](https://hexdocs.pm/gettext), By using [Gettext](https://hexdocs.pm/gettext),
your module gains a set of macros for translations, for example: your module gains a set of macros for translations, for example:
import Content.Gettext import Legendary.Content.Gettext
# Simple translation # Simple translation
gettext("Here is the string to translate") gettext("Here is the string to translate")

View file

@ -1,6 +1,6 @@
defmodule Content.Router do defmodule Legendary.Content.Router do
use Content, :router use Legendary.Content, :router
alias AuthWeb.Plugs.{RequireAdmin} alias Legendary.AuthWeb.Plugs.{RequireAdmin}
pipeline :browser do pipeline :browser do
plug :accepts, ["html"] plug :accepts, ["html"]
@ -22,5 +22,5 @@ defmodule Content.Router do
plug Pow.Plug.RequireAuthenticated, error_handler: Pow.Phoenix.PlugErrorHandler plug Pow.Plug.RequireAuthenticated, error_handler: Pow.Phoenix.PlugErrorHandler
end end
use Content.Routes use Legendary.Content.Routes
end end

View file

@ -1,4 +1,4 @@
defmodule Content.Routes do defmodule Legendary.Content.Routes do
defmacro __using__(_opts \\ []) do defmacro __using__(_opts \\ []) do
quote do quote do
pipeline :feed do pipeline :feed do
@ -8,21 +8,21 @@ defmodule Content.Routes do
plug :put_secure_browser_headers plug :put_secure_browser_headers
end end
scope "/", Content do scope "/", Legendary.Content do
pipe_through([:browser, :require_auth, :require_admin]) pipe_through([:browser, :require_auth, :require_admin])
put "/posts/preview", PostsController, :preview put "/posts/preview", PostsController, :preview
post "/posts/preview", PostsController, :preview post "/posts/preview", PostsController, :preview
end end
scope "/", Content do scope "/", Legendary.Content do
pipe_through :feed # Use the default browser stack pipe_through :feed # Use the default browser stack
get "/category/:category/feed.rss", FeedsController, :index, as: :category_feed get "/category/:category/feed.rss", FeedsController, :index, as: :category_feed
get "/feed.rss", FeedsController, :index, as: :index_feed get "/feed.rss", FeedsController, :index, as: :index_feed
end end
scope "/", Content do scope "/", Legendary.Content do
pipe_through :browser # Use the default browser stack pipe_through :browser # Use the default browser stack
resources "/comments", CommentController, as: :comment, only: [:create, :delete, :update] resources "/comments", CommentController, as: :comment, only: [:create, :delete, :update]

View file

@ -1,4 +1,4 @@
defmodule Content.Telemetry do defmodule Legendary.Content.Telemetry do
@moduledoc """ @moduledoc """
Collects metrics for the application and allows them to be transmitted using the Telemetry framework. Collects metrics for the application and allows them to be transmitted using the Telemetry framework.
""" """
@ -52,7 +52,7 @@ defmodule Content.Telemetry do
[ [
# A module, function and arguments to be invoked periodically. # A module, function and arguments to be invoked periodically.
# This function must call :telemetry.execute/3 and a metric must be added above. # This function must call :telemetry.execute/3 and a metric must be added above.
# {Content, :count_users, []} # {Legendary.Content, :count_users, []}
] ]
end end
end end

View file

@ -3,8 +3,8 @@
<channel> <channel>
<title><%= title(@view_module, @view_template, assigns) %></title> <title><%= title(@view_module, @view_template, assigns) %></title>
<description><%= excerpt(@view_module, @view_template, assigns) %></description> <description><%= excerpt(@view_module, @view_template, assigns) %></description>
<link><%= Content.Router.Helpers.url(CoreWeb.Endpoint) %></link> <link><%= Legendary.Content.Router.Helpers.url(Legendary.CoreWeb.Endpoint) %></link>
<atom:link href="<%= Content.Router.Helpers.url(CoreWeb.Endpoint) %><%= @feed_url %>" rel="self" type="application/rss+xml" /> <atom:link href="<%= Legendary.Content.Router.Helpers.url(Legendary.CoreWeb.Endpoint) %><%= @feed_url %>" rel="self" type="application/rss+xml" />
<%= for post <- @posts do %> <%= for post <- @posts do %>
<item> <item>

View file

@ -1,5 +1,5 @@
<div> <div>
<%= Enum.map(Content.Comments.children(@parent_id, @post.comments), fn comment -> %> <%= Enum.map(Legendary.Content.Comments.children(@parent_id, @post.comments), fn comment -> %>
<div class="rounded shadow bg-gray-200 px-4 py-6 my-6"> <div class="rounded shadow bg-gray-200 px-4 py-6 my-6">
<div class="flex pb-6 items-center"> <div class="flex pb-6 items-center">
<img class="w-10 h-10 rounded-full mr-2" src="<%= comment.author_email |> gravatar_url_for_email %>" /> <img class="w-10 h-10 rounded-full mr-2" src="<%= comment.author_email |> gravatar_url_for_email %>" />

View file

@ -9,7 +9,7 @@
</div> </div>
<div class="Article-content <%= if @post.format, do: @post.format.slug %> e-content"> <div class="Article-content <%= if @post.format, do: @post.format.slug %> e-content">
<%= render "thumb.html", post: @post, thumbs: @thumbs %> <%= render "thumb.html", post: @post, thumbs: @thumbs %>
<%= @post |> Content.Post.content_page(@page) |> process_content |> raw %> <%= @post |> Legendary.Content.Post.content_page(@page) |> process_content |> raw %>
</div> </div>
<%= render "pagination.html", conn: @conn, post: @post, current_page: @page %> <%= render "pagination.html", conn: @conn, post: @post, current_page: @page %>
</article> </article>

View file

@ -9,7 +9,7 @@
<div class="Article-content <%= if post.format, do: post.format.slug %> e-content"> <div class="Article-content <%= if post.format, do: post.format.slug %> e-content">
<%= render "thumb.html", post: post, thumbs: @thumbs %> <%= render "thumb.html", post: post, thumbs: @thumbs %>
<div class="Article-content-words"> <div class="Article-content-words">
<%= raw post |> Content.Post.content_page(1) |> Content.Post.before_more |> process_content |> raw %> <%= raw post |> Legendary.Content.Post.content_page(1) |> Legendary.Content.Post.before_more |> process_content |> raw %>
<%= if post.content =~ "<!--more-->" do %> <%= if post.content =~ "<!--more-->" do %>
<p> <p>
<%= link "Keep Reading", to: Routes.posts_path(@conn, :show, post) %> <%= link "Keep Reading", to: Routes.posts_path(@conn, :show, post) %>
@ -18,14 +18,14 @@
<%= render "pagination.html", conn: @conn, post: post %> <%= render "pagination.html", conn: @conn, post: post %>
</div> </div>
</div> </div>
<%= case post.categories || [] do %> <%= case post.categories || [] do %>
<% [] -> %> <% [] -> %>
<%= "" %> <%= "" %>
<% categories -> %> <% categories -> %>
<div class="flex pt-6"> <div class="flex pt-6">
<h3 class="text-xl mr-4">Categories</h3> <h3 class="text-xl mr-4">Categories</h3>
<%= for term <- categories do %> <%= for term <- categories do %>
<%= link term.name, to: Routes.category_path(@conn, :index_posts, term.slug), class: "rounded-full bg-gray-300 px-4 py-1 mr-2" %> <%= link term.name, to: Routes.category_path(@conn, :index_posts, term.slug), class: "rounded-full bg-gray-300 px-4 py-1 mr-2" %>
<% end %> <% end %>
@ -37,10 +37,10 @@
<nav class="max-w-xl mx-auto flex justify-center"> <nav class="max-w-xl mx-auto flex justify-center">
<div class="flex shadow rounded"> <div class="flex shadow rounded">
<%= paginator(1..@last_page, @page, fn first..last, page -> <%= paginator(1..@last_page, @page, fn first..last, page ->
link page, link page,
to: paginated_posts_path(@conn, @category, page), to: paginated_posts_path(@conn, @category, page),
style: "min-width: 3.5rem", style: "min-width: 3.5rem",
class: "#{if page == @page, do: "font-bold"} text-center flex-1 border bg-gray-100 hover:bg-gray-300 text-gray-500 p-4 #{group_rounding_class(first..last, page)}" class: "#{if page == @page, do: "font-bold"} text-center flex-1 border bg-gray-100 hover:bg-gray-300 text-gray-500 p-4 #{group_rounding_class(first..last, page)}"
end) end)
%> %>
</div> </div>

View file

@ -1,8 +1,8 @@
<%= if Content.Post.paginated_post?(@post) do %> <%= if Legendary.Content.Post.paginated_post?(@post) do %>
<nav class="paginator"> <nav class="paginator">
Page: Page:
<%= Enum.map( <%= Enum.map(
1..Content.Post.content_page_count(@post), 1..Legendary.Content.Post.content_page_count(@post),
fn page -> fn page ->
if assigns[:current_page] == nil || assigns[:current_page] != page do if assigns[:current_page] == nil || assigns[:current_page] != page do
link page, to: Routes.paged_post_path(@conn, :show, @post, page) link page, to: Routes.paged_post_path(@conn, :show, @post, page)

View file

@ -9,14 +9,14 @@
</div> </div>
<div class="<%= if @post.format, do: @post.format.slug %> e-content py-12 Article-content"> <div class="<%= if @post.format, do: @post.format.slug %> e-content py-12 Article-content">
<%= render "thumb.html", post: @post, thumbs: @thumbs %> <%= render "thumb.html", post: @post, thumbs: @thumbs %>
<%= @post |> Content.Post.content_page(@page) |> process_content |> raw %> <%= @post |> Legendary.Content.Post.content_page(@page) |> process_content |> raw %>
<%= case @post.categories || [] do %> <%= case @post.categories || [] do %>
<% [] -> %> <% [] -> %>
<%= "" %> <%= "" %>
<% categories -> %> <% categories -> %>
<div class="flex pt-6"> <div class="flex pt-6">
<h3 class="text-xl font-bold mr-4">Categories</h3> <h3 class="text-xl font-bold mr-4">Categories</h3>
<%= for term <- categories do %> <%= for term <- categories do %>
<%= link term.name, to: Routes.category_path(@conn, :index_posts, term.slug), class: "rounded-full bg-gray-300 px-4 py-1 mr-2" %> <%= link term.name, to: Routes.category_path(@conn, :index_posts, term.slug), class: "rounded-full bg-gray-300 px-4 py-1 mr-2" %>
<% end %> <% end %>

View file

@ -1,6 +1,6 @@
<%= case @thumbs[@post.id] do %> <%= case @thumbs[@post.id] do %>
<% thumb = %Content.Post{} -> %> <% thumb = %Legendary.Content.Post{} -> %>
<%= if thumb |> Content.Attachment.vertical?() do %> <%= if thumb |> Legendary.Content.Attachment.vertical?() do %>
<div class="post-thumbnail post-thumbnail--vertical"> <div class="post-thumbnail post-thumbnail--vertical">
<%= img_tag thumb.guid %> <%= img_tag thumb.guid %>
</div> </div>

View file

@ -1,3 +1,3 @@
defmodule Content.AdminHomeView do defmodule Legendary.Content.AdminHomeView do
use Content, :view use Legendary.Content, :view
end end

View file

@ -1,3 +1,3 @@
defmodule Content.AdminPostsView do defmodule Legendary.Content.AdminPostsView do
use Content, :view use Legendary.Content, :view
end end

View file

@ -1,4 +1,4 @@
defmodule Content.ErrorHelpers do defmodule Legendary.Content.ErrorHelpers do
@moduledoc """ @moduledoc """
Conveniences for translating and building error messages. Conveniences for translating and building error messages.
""" """
@ -39,9 +39,9 @@ defmodule Content.ErrorHelpers do
# should be written to the errors.po file. The :count option is # should be written to the errors.po file. The :count option is
# set by Ecto and indicates we should also apply plural rules. # set by Ecto and indicates we should also apply plural rules.
if count = opts[:count] do if count = opts[:count] do
Gettext.dngettext(Content.Gettext, "errors", msg, msg, count, opts) Gettext.dngettext(Legendary.Content.Gettext, "errors", msg, msg, count, opts)
else else
Gettext.dgettext(Content.Gettext, "errors", msg, opts) Gettext.dgettext(Legendary.Content.Gettext, "errors", msg, opts)
end end
end end
end end

View file

@ -1,5 +1,5 @@
defmodule Content.ErrorView do defmodule Legendary.Content.ErrorView do
use Content, :view use Legendary.Content, :view
# If you want to customize a particular status code # If you want to customize a particular status code
# for a certain format, you may uncomment below. # for a certain format, you may uncomment below.

View file

@ -1,10 +1,10 @@
defmodule Content.FeedsView do defmodule Legendary.Content.FeedsView do
use Content, :view use Legendary.Content, :view
use Phoenix.HTML use Phoenix.HTML
alias Phoenix.HTML alias Phoenix.HTML
alias Phoenix.HTML.Tag alias Phoenix.HTML.Tag
import Content.LayoutView, only: [title: 3, excerpt: 3] import Legendary.Content.LayoutView, only: [title: 3, excerpt: 3]
def gravatar_url_for_email(email) do def gravatar_url_for_email(email) do
email email
@ -38,7 +38,7 @@ defmodule Content.FeedsView do
def post_topmatter(conn, post) do def post_topmatter(conn, post) do
author = author =
post.author || post.author ||
%Auth.User{ %Legendary.Auth.User{
email: "example@example.org", email: "example@example.org",
display_name: "Anonymous", display_name: "Anonymous",
homepage_url: "#" homepage_url: "#"

View file

@ -1,5 +1,5 @@
defmodule Content.LayoutView do defmodule Legendary.Content.LayoutView do
use Content, :view use Legendary.Content, :view
def feed_tag(conn, view_module, view_template, assigns) do def feed_tag(conn, view_module, view_template, assigns) do
~E""" ~E"""
@ -12,40 +12,40 @@ defmodule Content.LayoutView do
""" """
end end
def title(Content.PostsView, "index.html", assigns) do def title(Legendary.Content.PostsView, "index.html", assigns) do
"Page #{assigns.page} | #{title(nil, nil, nil)}" "Page #{assigns.page} | #{title(nil, nil, nil)}"
end end
def title(Content.FeedsView, "index.rss", %{category: category}) when not(is_nil(category)) do def title(Legendary.Content.FeedsView, "index.rss", %{category: category}) when not(is_nil(category)) do
"#{category} | #{title(nil, nil, nil)}" "#{category} | #{title(nil, nil, nil)}"
end end
def title(Content.PostsView, "show.html", assigns) do def title(Legendary.Content.PostsView, "show.html", assigns) do
(assigns.post.title |> HtmlSanitizeEx.strip_tags()) <> " | " <> title(nil, nil, nil) (assigns.post.title |> HtmlSanitizeEx.strip_tags()) <> " | " <> title(nil, nil, nil)
end end
def title(_, _, _), do: I18n.t! "en", "site.title" def title(_, _, _), do: Legendary.I18n.t! "en", "site.title"
def excerpt(Content.PostsView, "show.html", assigns) do def excerpt(Legendary.Content.PostsView, "show.html", assigns) do
assigns.post.excerpt assigns.post.excerpt
|> HtmlSanitizeEx.strip_tags() |> HtmlSanitizeEx.strip_tags()
end end
def excerpt(Content.FeedsView, "index.rss", %{category: category}) when not(is_nil(category)) do def excerpt(Legendary.Content.FeedsView, "index.rss", %{category: category}) when not(is_nil(category)) do
"#{category} | #{excerpt(nil, nil, nil)}" "#{category} | #{excerpt(nil, nil, nil)}"
end end
def excerpt(_, _, _), do: I18n.t! "en", "site.excerpt" def excerpt(_, _, _), do: Legendary.I18n.t! "en", "site.excerpt"
def corresponding_feed_url(conn, _, _, %{category: nil}) do def corresponding_feed_url(conn, _, _, %{category: nil}) do
Content.Router.Helpers.index_feed_url(conn, :index) Legendary.Content.Router.Helpers.index_feed_url(conn, :index)
end end
def corresponding_feed_url(conn, Content.PostsView, "index.html", %{category: category}) do def corresponding_feed_url(conn, Legendary.Content.PostsView, "index.html", %{category: category}) do
Content.Router.Helpers.category_feed_url(conn, :index, category) Legendary.Content.Router.Helpers.category_feed_url(conn, :index, category)
end end
def corresponding_feed_url(conn, _, _, _) do def corresponding_feed_url(conn, _, _, _) do
Content.Router.Helpers.index_feed_url(conn, :index) Legendary.Content.Router.Helpers.index_feed_url(conn, :index)
end end
end end

View file

@ -1,3 +1,3 @@
defmodule Content.MenusView do defmodule Legendary.Content.MenusView do
use Content, :view use Legendary.Content, :view
end end

View file

@ -1,3 +1,3 @@
defmodule Content.PageView do defmodule Legendary.Content.PageView do
use Content, :view use Legendary.Content, :view
end end

View file

@ -1,9 +1,9 @@
defmodule Content.PostsView do defmodule Legendary.Content.PostsView do
use Content, :view use Legendary.Content, :view
use Phoenix.HTML use Phoenix.HTML
import Plug.Conn import Plug.Conn
alias Content.Comment alias Legendary.Content.Comment
alias Content.Post alias Legendary.Content.Post
alias Phoenix.HTML alias Phoenix.HTML
alias Phoenix.HTML.Tag alias Phoenix.HTML.Tag
@ -59,7 +59,7 @@ defmodule Content.PostsView do
def post_topmatter(conn, post) do def post_topmatter(conn, post) do
author = author =
post.author || post.author ||
%Auth.User{ %Legendary.Auth.User{
email: "example@example.org", email: "example@example.org",
display_name: "Anonymous", display_name: "Anonymous",
homepage_url: "#" homepage_url: "#"

View file

@ -1,3 +1,3 @@
defmodule Content.SitemapView do defmodule Legendary.Content.SitemapView do
use Content, :view use Legendary.Content, :view
end end

View file

@ -1,10 +1,12 @@
defmodule Content.MixProject do defmodule Legendary.Content.MixProject do
use Mix.Project use Mix.Project
@version "2.1.3"
def project do def project do
[ [
app: :content, app: :content,
version: "0.1.0", version: @version,
build_path: "../../_build", build_path: "../../_build",
config_path: "../../config/config.exs", config_path: "../../config/config.exs",
deps_path: "../../deps", deps_path: "../../deps",
@ -25,7 +27,7 @@ defmodule Content.MixProject do
# Type `mix help compile.app` for more information. # Type `mix help compile.app` for more information.
def application do def application do
[ [
mod: {Content.Application, []}, mod: {Legendary.Content.Application, []},
extra_applications: [:logger, :runtime_tools, :sitemap] extra_applications: [:logger, :runtime_tools, :sitemap]
] ]
end end

View file

@ -1,4 +1,4 @@
defmodule Content.Repo.Migrations.CreateSchema do defmodule Legendary.Content.Repo.Migrations.CreateSchema do
use Ecto.Migration use Ecto.Migration
def change do def change do

View file

@ -1,4 +1,4 @@
defmodule Content.Repo.Migrations.AddObanJobsTable do defmodule Legendary.Content.Repo.Migrations.AddObanJobsTable do
use Ecto.Migration use Ecto.Migration
def up do def up do

View file

@ -5,7 +5,7 @@
# Inside the script, you can read and write to any of your # Inside the script, you can read and write to any of your
# repositories directly: # repositories directly:
# #
# Content.Repo.insert!(%Content.SomeSchema{}) # Legendary.Content.Repo.insert!(%Legendary.Content.SomeSchema{})
# #
# We recommend using the bang functions (`insert!`, `update!` # We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong. # and so on) as they will fail if something goes wrong.

View file

@ -1,7 +1,7 @@
defmodule Content.AttachmentTest do defmodule Legendary.Content.AttachmentTest do
use Content.DataCase use Legendary.Content.DataCase
alias Content.{Attachment, Postmeta, Posts, Repo} alias Legendary.Content.{Attachment, Postmeta, Posts, Repo}
@create_attrs %{ @create_attrs %{
id: 123, id: 123,
@ -22,7 +22,7 @@ defmodule Content.AttachmentTest do
value: "a:2:{s:5:\"width\";i:640;s:6:\"height\";i:480;}" value: "a:2:{s:5:\"width\";i:640;s:6:\"height\";i:480;}"
} |> Repo.insert() } |> Repo.insert()
Content.Post Legendary.Content.Post
|> preload([:metas]) |> preload([:metas])
|> Repo.get!(attachment.id) |> Repo.get!(attachment.id)
end end
@ -35,14 +35,14 @@ defmodule Content.AttachmentTest do
key: "attachment_metadata", key: "attachment_metadata",
value: "a:2:{s:5:\"width\";i:480;s:6:\"height\";i:640;}" value: "a:2:{s:5:\"width\";i:480;s:6:\"height\";i:640;}"
} |> Repo.insert() } |> Repo.insert()
Content.Post Legendary.Content.Post
|> preload([:metas]) |> preload([:metas])
|> Repo.get!(attachment.id) |> Repo.get!(attachment.id)
end end
def fixture(:unknown_dimensions) do def fixture(:unknown_dimensions) do
{:ok, attachment} = Posts.create_posts(@create_attrs) {:ok, attachment} = Posts.create_posts(@create_attrs)
Content.Post Legendary.Content.Post
|> preload([:metas]) |> preload([:metas])
|> Repo.get!(attachment.id) |> Repo.get!(attachment.id)
end end

View file

@ -1,7 +1,7 @@
defmodule Content.CommentmetaTest do defmodule Legendary.Content.CommentmetaTest do
use Content.DataCase use Legendary.Content.DataCase
alias Content.{Commentmeta, Repo} alias Legendary.Content.{Commentmeta, Repo}
test "can save a new commentmeta" do test "can save a new commentmeta" do
%Commentmeta{} %Commentmeta{}

View file

@ -1,7 +1,7 @@
defmodule Content.CommentsTest do defmodule Legendary.Content.CommentsTest do
use Content.DataCase use Legendary.Content.DataCase
alias Content.{Comment, Comments, Repo} alias Legendary.Content.{Comment, Comments, Repo}
alias Ecto.Changeset alias Ecto.Changeset
def fixture(:parent_comment) do def fixture(:parent_comment) do

View file

@ -1,7 +1,7 @@
defmodule Content.LinkTest do defmodule Legendary.Content.LinkTest do
use Content.DataCase use Legendary.Content.DataCase
alias Content.{Link, Repo} alias Legendary.Content.{Link, Repo}
test "can save a new link" do test "can save a new link" do
%Link{} %Link{}

View file

@ -1,7 +1,7 @@
defmodule Content.MarkupFieldTest do defmodule Legendary.Content.MarkupFieldTest do
use Content.DataCase use Legendary.Content.DataCase
import Content.MarkupField import Legendary.Content.MarkupField
import Phoenix.HTML, only: [safe_to_string: 1] import Phoenix.HTML, only: [safe_to_string: 1]
import Phoenix.HTML.Form, only: [form_for: 3] import Phoenix.HTML.Form, only: [form_for: 3]

View file

@ -1,7 +1,7 @@
defmodule Content.OptionTest do defmodule Legendary.Content.OptionTest do
use Content.DataCase use Legendary.Content.DataCase
alias Content.{Option, Repo} alias Legendary.Content.{Option, Repo}
test "can save a new link" do test "can save a new link" do
%Option{} %Option{}

View file

@ -1,7 +1,7 @@
defmodule Content.OptionsTest do defmodule Legendary.Content.OptionsTest do
use Content.DataCase use Legendary.Content.DataCase
alias Content.{Option, Options, Repo} alias Legendary.Content.{Option, Options, Repo}
def fixture(:option) do def fixture(:option) do
%Option{} %Option{}

View file

@ -1,7 +1,7 @@
defmodule Content.PostmetaTest do defmodule Legendary.Content.PostmetaTest do
use Content.DataCase use Legendary.Content.DataCase
alias Content.{Postmeta, Repo} alias Legendary.Content.{Postmeta, Repo}
test "can save a new postmeta" do test "can save a new postmeta" do
%Postmeta{} %Postmeta{}

View file

@ -1,7 +1,7 @@
defmodule Content.PostsTest do defmodule Legendary.Content.PostsTest do
use Content.DataCase use Legendary.Content.DataCase
alias Content.{Post, Posts, Repo} alias Legendary.Content.{Post, Posts, Repo}
setup do setup do
admin_only_post = admin_only_post =

Some files were not shown because too many files have changed in this diff Show more