rasteiner / k3-whenquery

Conditionally show fields and sections. Better.
MIT License
64 stars 1 forks source link

k3-whenquery

Conditionally show fields and sections. Better.

Installation

Download

Download and copy this repository to /site/plugins/k3-whenquery.

Git submodule

git submodule add https://github.com/rasteiner/k3-whenquery.git site/plugins/k3-whenquery

Composer

composer require rasteiner/k3-whenquery

Use

Add a whenQuery property to your fields and sections. The expression in this query will be evaluated in real time in the browser to hide the section or field when it evaluates to a falsy value.

title: Woofler page

fields:
  foosables:
    type: select
    label: Foosables
    options:
      gerryconas: Gerryconas
      peterwands: Peterwands
      perlskippies: Perl Skippies

  barsters:
    type: range
    label: Barsters

  warning:
    type: info
    label: Woofling warning
    text: Having more than 30 Barsters is **not recommended** while wooffling Gerryconas.
    theme: negative
    whenQuery: foosables = 'gerryconas' && barsters > 30   

Expression Language Syntax

There are no assignments and function calls (it's meant to be as harmless as possible). Since there are no assignments, = is an equality comparison (there is no ==).

Supported operators

Member Access is always "optional": it does never throw an error if you access a property of undefined; it just evaluates to undefined. In short, . behaves like javascript's ?. and a[something] behaves like a?.[something].

The search operator =~ is a multifunction tool: it behaves differently depending on the type of its operands:

There's also support for String, Number, Boolean (true, false), Object and Array literals.

Array operators

General syntax:

Array operators are made of 3 parts:

  1. In the left the array they operate on
  2. after :: the name of the operation
  3. between the parentheses the expression that is evaluated for each array item.

Inside of the parentheses, the symbol $ represents the "current" item.

Example
fields:
  blocks:
    type: blocks

  imagesEncouragement:
    type: info
    label: Nice job!
    text: Good! You have at least 13 images in this post. This will be a **great** post.
    theme: positive
    whenQuery: blocks ::count($.type = 'image') >= 13

Array reducers

Array reducers are functions that take an array and return a single value. They can be used to aggregate values in an array. The syntax is similar to the array operators, but ::reduce(expr, ?initial) accepts an optional initial value. If no initial value is provided, the first item of the array is used. Inside of the parentheses, the symbol $ represents the "current" item, while $1 represents the return value of the "previous" iteration (aka the "accumulator"). The array is always traversed left to right.

Example
fields:
  percentages:
    type: structure
    fields:
      percent:
        type: number
        after: "%"

  percentagesEncouragement:
    type: info
    label: Math GENIUS!
    text: Great job! The sum of all percentages is exactly 100%.
    theme: positive
    whenQuery: percentages ::reduce($1 + $.percent, 0) = 100

An example usage without an initial value:

    whenQuery: percentages ::map($.percent) ::reduce($1 + $) = 100

Variables lookup

Content variables

By default, any valid identifier refers to the "current" fieldset. This means that page fields could be shadowed by other fields with the same name in a structure or block, when the query is executed in such structure or block. If no field is found in the current fieldset, the query is evaluated in the page fields.

Model variables

The Site, Pages, Files and Users are "models". Other than content, they also have other properties that might be useful in a query. These properties are accessible by prepending an underscore (_) to their name, when (and only when) the query is being executed inside of their respective View.

The accessible Site properties are:

The accessible Page properties are:

The accessible User properties are:

The accessible File properties are:

Example
fields:
    date:
        type: date

    dateInfo:
        type: info
        label: Heads up!
        text: This page is listed, its date will be ignored for sorting.
        theme: positive
        whenQuery: date && _status = 'listed'

Known issues