View Source CFSync (CFSync v0.8.0)
CFSync is an Elixir client for Contentful sync API.
features
Features
- Provides functions to extract field values from Contentful entries JSON payloads.
- Maps Contenful entries, assets, and links to Elixir structs. Using structs is better for readability, performance and reliability.
- Maps RichText data to Elixir structs.
- Keeps a cache of your entries and assets in a ETS table. This allows for fast (way faster than rest API calls) and concurrent reads.
- Keeps this cache up to date by regularly fetching changes from Contentful sync API
installation
Installation
Add :cf_sync to your mix.exs dependencies.
def deps do
[
{:cf_sync, "~> 0.1.0"},
]
end
basic-usage
Basic usage
# Define your fields mappings, one per content-type
defmodule MyApp.PageFields do
@behaviour CFSync.Entry.Fields
import CFSync.Entry.Extractors
defstruct :name, :body, :author
# See CFSync.Entry.Extractors for extract_* documentation
def new(data) do
%__MODULE__{
name: extract_binary(data, "name"),
body: extract_richtext(data, "body"),
author: extract_link(data, "author"),
}
end
end
# Define a mapping to map Contentful "contentType" ids to an atom name and a fields struct:
entries_mapping = %{
# "page" key is the content_type ID as configured in Contentful
"page" => %{
content_type: :page,
fields_module: MyApp.PageFields,
},
"author" => %{
content_type: :author,
fields_module: MyApp.AuthorFields,
}
# ...
}
# Start a CFSync process
{:ok, pid} =
CFSync.start_link(
MyApp.MyCFSync,
"Your_contentful_space_id",
"Your_contentful_delivery_api_token",
entries_mapping
)
# Use it
store = CFSync.from(MyApp.MyCFSync)
entry = CFSync.get_entry(store, "entry_id")
# entry ->
%CFSync.Entry{
id: "entry_id",
content_type: :page,
space_id: "your_space_id",
fields: %MyApp.PageFields{
name: "Lorem ipsum",
body: %CFSync.RichText{ #... },
author: %CFSync.Link{
id: "autor_id",
#... },
# ...
}
}
author = CFSync.get_link_target(store, entry.fields.author)
# author ->
%CFSync.Entry{
id: "author_id",
content_type: :author,
fields: %MyApp.AuthorFields{
# ...
}
}!! Put your API token and space_id in your ENV, NOT in your code.
You should start the CFSync process in a supervision tree.
Link to this section Summary
Functions
Get the CFSync store for name. Use the name your provided to start_link/4.
Get the asset specified by id from the CFSync store store.
Returns a list containg all assets from the CFSync store store.
Returns a list containg all entries from the CFSync store store.
Returns a list containg all entries of specified content_type from the CFSync store store.
Get the entry specified by id from the CFSync store store.
Resolves link in the CFSync store store and returns the corresponding asset or entry.
Phoenix.Component that renders RichText.
Starts CFSync GenServer
Link to this section Types
@opaque store()
Reference to a CFSync store.
Link to this section Functions
Get the CFSync store for name. Use the name your provided to start_link/4.
store = CFSync.from(MyApp.MyCFSync)
get_entries(store)
get_entry(store, "an_entry_id")
# ...
@spec get_asset(store(), binary()) :: nil | CFSync.Asset.t()
Get the asset specified by id from the CFSync store store.
Returns nil if the asset is not found.
@spec get_assets(store()) :: [CFSync.Asset.t()]
Returns a list containg all assets from the CFSync store store.
See get_entries/1 about performance.
@spec get_entries(store()) :: [CFSync.Entry.t()]
Returns a list containg all entries from the CFSync store store.
This function will retrieve ALL entries currently stored in the store's ETS table and deep copy them to the current process. Using this on a large Contentful space will be slow. If you want to retrieve all the entries to filter them, consider using something like memoize to cache the results.
@spec get_entries_for_content_type(store(), atom()) :: [CFSync.Entry.t()]
Returns a list containg all entries of specified content_type from the CFSync store store.
See get_entries/1 about performance.
@spec get_entry(store(), binary()) :: nil | CFSync.Entry.t()
Get the entry specified by id from the CFSync store store.
@spec get_link_target(store(), CFSync.Link.t()) :: nil | CFSync.Entry.t() | CFSync.Asset.t()
Resolves link in the CFSync store store and returns the corresponding asset or entry.
Returns nil if link target is not not found.
@spec rich_text(map()) :: Phoenix.LiveView.Rendered.t()
Phoenix.Component that renders RichText.
You can pass these assigns: content: the %RichText{} struct to render class: a class attribute that will be added to root element of rendered HTML delegate: a module with custom components to use for rendering
Delegate and class are optional. To use delegate module, see RichTextRenderer and RichTextRendererTest modules
@spec start_link(atom(), String.t(), String.t(), map(), keyword()) :: :ignore | {:error, any()} | {:ok, pid()}
Starts CFSync GenServer
Should be started in a supervision tree
nameis an atom to reference this CFSync process. Use the samenameinfrom/1to query entries.space_idis your Contentful space's IDdelivery_tokenis your Contentful API tokencontent_typesis a map describing how to map Contentful entries to elixir structs. See module doc.
options
Options
:locale- The locale you want to fetch from Contentful. Defaults to"en-US":root_url- Default is"https://cdn.contentful.com/":initial_sync_interval- The server will wait for this interval between two page requests during initial sync. Defaults to 30 milliseconds.:delta_sync_interval- The server will wait for this interval between two sync requests. Defaults to 5000 milliseconds. You can use a shorter delay to get updates faster, but you will be rate limited by Contentful if you set it too short.:invalidation_callbacks- List of 0-arity anonymous functions that will be called after each sync operation that actually adds, updates or deletes some entries.