Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ikeikeikeike/sitesx

A Phoenix SubDomainer which makes subdomain using DigitalOcean, Cloudflare, etc. API and contains convenient view helper interface along with Plug and Ecto.
https://github.com/ikeikeikeike/sitesx

cloudflare digitalocean ecto helper phoenix plug subdomain

Last synced: 14 days ago
JSON representation

A Phoenix SubDomainer which makes subdomain using DigitalOcean, Cloudflare, etc. API and contains convenient view helper interface along with Plug and Ecto.

Awesome Lists containing this project

README

        

# Sitesx

[![Build Status](http://img.shields.io/travis/ikeikeikeike/sitesx.svg?style=flat-square)](http://travis-ci.org/ikeikeikeike/sitesx)
[![Ebert](https://ebertapp.io/github/ikeikeikeike/sitesx.svg)](https://ebertapp.io/github/ikeikeikeike/sitesx)
[![Hex version](https://img.shields.io/hexpm/v/sitesx.svg "Hex version")](https://hex.pm/packages/sitesx)
[![Inline docs](https://inch-ci.org/github/ikeikeikeike/sitesx.svg)](http://inch-ci.org/github/ikeikeikeike/sitesx)
[![Lisence](https://img.shields.io/hexpm/l/ltsv.svg)](https://github.com/ikeikeikeike/sitesx/blob/master/LICENSE)

A Phoenix SubDomainer which makes subdomain using DigitalOcean, Cloudflare, etc. API and contains convenient view helper interface along with Plug and Ecto

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed as:

1. Add `sitesx` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[{:sitesx, "~> 0.10"}]
end
```

2. Ensure `sitesx` is started before your application:

```elixir
def application do
[applications: [:sitesx]]
end
```

3. Sitesx needs to add a migration:

```elixir
defmodule MyApp.Repo.Migrations.CreateSite do
use Ecto.Migration

def change do
create table(:sites) do
add :name, :string
add :dns, :boolean, default: false

timestamps()
end
create index(:sites, [:name], unique: true)
create index(:sites, [:dns])

end
end
```

4. After definition, needs to add a model:

```elixir
defmodule MyApp.Site do
use MyApp.Web, :model

schema "sites" do
field :name, :string
field :dns, :boolean

timestamps()
end

def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:name dns])
|> validate_required([:name])
|> unique_constraint(:name)
end
end
```

~~Mix commands `mix sitesx.gen.model` or `mix sitesx.gen.schema` will be able to generate No.3 and No.4 instead of define manually.~~

```shell
$ mix sitesx.gen.model # Until phoenix v1.2.x
$ mix sitesx.gen.schema # Phoenix v1.3.x
```

5. Stores Sitesx model into private on Plug struct.

A `Sitesx.Plug` module extracts domain information from request URL or `sub` queryparameter.

Plug in Router

```elixir
defmodule MyApp.Router do
use MyApp.Web, :router

pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers

plug Sitesx.Plug
end
end
```

or

Plug in Controller

```elixir
defmodule MyApp.MyController do
use MyApp.Web, :controller

plug Sitesx.Plug
end
```

6. Configuration

`Cloudflare`

```elixir
config :sitesx,
otp_app: MyApp,
domain: "example.com",
ensure_domain_interval: 300,
dns: [
provider: :cloudflare,
auth_email: "[email protected]",
auth_key: "hash-key1",
zone_identifier: "hash-key1",
]
```

`Digitalocean`

```elixir
config :sitesx,
otp_app: MyApp,
domain: "example.com",
request_options: [hackney: [pool: :cloudflare]],
dns: :digitalocean
```

###### `Sitesx.App`, Configuration from mix config and environment variable.

hexdocs: https://hexdocs.pm/sitesx/Sitesx.App.html

## Customization

Obviously, those definition are still not enough to work on development. Therefore it will be changed is better that have `1:N` relation between one of a model and `Site` model.

```elixir
defmodule MyApp.Entry do
use MyApp.Web, :model

schema "entries" do
belongs_to :site, MyApp.Site
field :title, :string
field :content, :string

timestamps()
end
end
```

And then

```elixir
defmodule MyApp.Site do
use MyApp.Web, :model

schema "sites" do
has_many :entries, MyApp.Entry
field :name, :string
field :dns, :boolean

timestamps()
end
end
```

## Usage

#### Create a record

Create `subdomain1` as `CNAME record` to DNS Provider which will be stored on Cloudflare or Digitalocean. And also will be stores that into database, too.

```elixir
{_, site} = Sitesx.Q.get_or_create("subdomain1")
Repo.insert_or_update(entry, %{site_id: site.id})
```

#### Generate a URL

Import module

```elixir
# web/web.ex
defmodule MyApp.Web do
def view do
quote do
use Phoenix.View, root: "web/templates"
...
...
...
import Sitesx.Helpers
end
end
end
```

Then call function

```elixir
subdomain_url(@conn, "entry.latest")
#-> Ensured domain: http://subdomain1.example.com/entries/latest
#-> Not ensured domain: http://example.com/entries/latest?sub=subdomain1

subdomain_url("subdomain2", @conn, "page.index")
#-> Ensured domain: http://subdomain2.example.com/entries/latest
#-> Not ensured domain: http://example.com/entries/latest?sub=subdomain2
```

## Documentation

#### `Sitesx.Domain` manages DNS record which has `detect`, `extract`, `create` method.

hexdocs: https://hexdocs.pm/sitesx/Sitesx.Domain.html

#### `Sitesx.Helpers`. Generate URL with subdomain for controller or templates along with [Phoenix.HTML.SimplifiedHelpers.URL](https://hexdocs.pm/phoenix_html_simplified_helpers/1.1.1/Phoenix.HTML.SimplifiedHelpers.URL.html)

hexdocs: https://hexdocs.pm/sitesx/Sitesx.Helpers.html

#### `Sitesx.Plug`. Stores Sitesx model into private on Plug struct.

hexdocs: https://hexdocs.pm/sitesx/Sitesx.Plug.html

#### `Sitesx.Q`. Ecto Query Helper along with Sitesx.Plug

hexdocs: https://hexdocs.pm/sitesx/Sitesx.Q.html

#### `Sitesx.App`, Configuration from mix config and environment variable.

hexdocs: https://hexdocs.pm/sitesx/Sitesx.App.html

#### Documentation

hexdocs: https://hexdocs.pm/sitesx