ElementorexCms.Source.Query (ElementorexCms v0.2.0)

Copy Markdown View Source

What a loop asks a source for (ElementorexCms.Source.list/2):

  • limit and offset
  • order_by - the key of a sortable field (nil: the source's own order) and order - :asc or :desc
  • filters - %{field: key, op: op, value: value} maps, all of which must match. op is one of "eq", "neq", "contains", "gt", "gte", "lt", "lte", "set" (has a value) or "unset"; value is the text typed in the editor or by a visitor (cast it to the type of the field). Visitors' filters also use "in" (value is a list: any of them) and "custom" (a filter of the source with logic of its own, see ElementorexCms.Source.Field)
  • search - nil or %{text: text, fields: keys}: records with the text in any of those fields (the search box of the visitors' filters)
  • exclude - ids (ElementorexCms.Source.id/1) to leave out, e.g. the item a page is about, in a list of related items

Sources backed by a database turn it into a query (see ElementorexCms.Source.Ecto); sources that keep their items in a list can use run/3.

Summary

Functions

How many records kept in memory match the filters and exclude of the query, its limit and offset aside: what ElementorexCms.Source.count/2 returns (a loop with numbered pages needs it).

Whether a value matches a filter operator and the expected text: what run/4 checks for each filter. Numbers compare as numbers, the rest as text without case.

Operators a designer chooses from (visitors' filters also send "in" and "custom").

Applies the query to records kept in memory: filters, search, exclude, order and page. value reads a field of a record (fn record, key -> ... end) and id its id (default: the "id"/:id key). "custom" filters are left to the source: apply them to the records before.

The distinct values of a field among records kept in memory, with how many records have each, in order: what ElementorexCms.Source.values/2 returns (the options of a filter).

Types

t()

@type t() :: %ElementorexCms.Source.Query{
  exclude: [String.t()],
  filters: [
    %{field: String.t(), op: String.t(), value: String.t() | [String.t()]}
  ],
  limit: pos_integer(),
  offset: non_neg_integer(),
  order: :asc | :desc,
  order_by: String.t() | nil,
  search: %{text: String.t(), fields: [String.t()]} | nil
}

Functions

count(query, records, value, id \\ nil)

@spec count(t(), [term()], (term(), String.t() -> term()), (term() -> term()) | nil) ::
  non_neg_integer()

How many records kept in memory match the filters and exclude of the query, its limit and offset aside: what ElementorexCms.Source.count/2 returns (a loop with numbered pages needs it).

def count(query, _context) do
  Query.count(query, MyApp.Team.members(), &Map.get(&1, String.to_existing_atom(&2)))
end

match_value?(actual, op, expected)

@spec match_value?(term(), String.t(), term()) :: boolean()

Whether a value matches a filter operator and the expected text: what run/4 checks for each filter. Numbers compare as numbers, the rest as text without case.

iex> ElementorexCms.Source.Query.match_value?(0, "lte", "0")
true
iex> ElementorexCms.Source.Query.match_value?("Shoes", "eq", "shoes")
true

ops()

@spec ops() :: [String.t()]

Operators a designer chooses from (visitors' filters also send "in" and "custom").

run(query, records, value, id \\ nil)

@spec run(t(), [term()], (term(), String.t() -> term()), (term() -> term()) | nil) ::
  [term()]

Applies the query to records kept in memory: filters, search, exclude, order and page. value reads a field of a record (fn record, key -> ... end) and id its id (default: the "id"/:id key). "custom" filters are left to the source: apply them to the records before.

def list(query, _context) do
  Query.run(query, MyApp.Team.members(), &Map.get(&1, String.to_existing_atom(&2)))
end

values(records, key, value)

@spec values([term()], String.t(), (term(), String.t() -> term())) :: [
  {term(), pos_integer()}
]

The distinct values of a field among records kept in memory, with how many records have each, in order: what ElementorexCms.Source.values/2 returns (the options of a filter).

iex> records = [%{c: "b"}, %{c: "a"}, %{c: "b"}, %{c: nil}]
iex> ElementorexCms.Source.Query.values(records, "c", &Map.get(&1, String.to_existing_atom(&2)))
[{"a", 1}, {"b", 2}]