Page fields

v0.0.1

This page lists every field of a page in Mishka CMS: its label on the form, the name it is stored under, its default and the rules the CMS holds it to. For the steps that use them, see Build a page in the visual editor. The full page form is a Mishka Gervaz form, and the trimming and length limits on its text fields are GuardedStruct derives on the page record.

Where the fields appear

  • Pages list, + Add Page menu: Create with the full form and Fill in the form, then open the editor show all fields. The second opens the visual editor after it saves.
  • Pages list, View, Configuration tab: all fields except Site. The pencil icon, Edit, on the row opens the same tab.
  • Visual editor, page settings, General tab: Title, Path, This page shows each, Layout and Permissions. The SEO tab is a separate form. See Set a page's SEO and share card.
  • The editor's Name your page dialog asks for Title and Path, plus Site for a master, and saves the page as inactive.

the Configuration tab of a page opened with Edit, with Title and Path at the top and Section, Format, Priority, Language, Language Group, Active and Precompile below them

The Configuration tab holds the whole page form.

Name and address

FieldStored asTypeDefaultRules
TitletitleTextNoneRequired. 1 to 200 characters, trimmed. What the page is called in its own language.
PathpathTextNoneRequired. See “Path rules” below. Unique within the site.
Sitesite_idSearchNoneA master only, when creating. Required. A page belongs to one site for good.

Layout, records and access

FieldStored asTypeDefaultRules
Layoutlayout_idSearchNo LayoutA layout of the page's site, or a shared one.
This page shows eachextra["record"]ChoiceCustom page: one page, one addressThe kinds of record that installed extensions offer, grouped by extension. The extension then fills the page's SEO, and the record's own permissions apply.
PermissionspermissionsSearch, severalEmptyPermission names that may open the page. Each is trimmed and lowercased, and repeats are dropped. Empty means everyone. Leave it empty on a page that shows records.

Settings

FieldStored asTypeDefaultRules
SectionsectionTextNoneA free label, such as blog or docs. The list shows it under the path.
FormatformatChoiceHEExHEEx, EEx or Markdown.
PrioritypriorityNumber00 to 100. Breaks a tie between two patterns that match an address equally well. The higher number wins.
LanguagelanguageComboboxenA language code, lowercased, up to 10 characters, such as fa or pt-br. The help line under the field reads “Add this code under Settings → Languages as well, or its URL answers 404.” Add the code to the site's Languages setting as well.
Language Grouplanguage_group_idSearchNew Language Group (auto-generate)The group of editions the page belongs to. Choices are the pages of the same site, shown as name and language. A page that names none starts a group of its own. One page per language in a group.
ActiveactiveSwitchOnOnly active pages are compiled and routed.
PrecompileprecompileSwitchOffOn compiles the page when the application starts. Off compiles it on first use.

Content and SEO

FieldStored asTypeDefaultRules
TemplatetemplateText areaAn empty starterAt least 3 characters once stored. A blank template on create is replaced by one empty container. On update, a blank template is refused.
DescriptiondescriptionTextNoneUp to 500 characters. Shown by search engines and link previews.
SEO Tagsseo_tagsListEmptySee “SEO tag entries” below. A title replaces the page's title. Meta and link tags each replace the default with the same name. A value may name a variable such as {{page.title}}.
Schema (JSON)schemaListEmptyStructured data objects, such as [{"@type": "WebPage", "name": "My Page"}]. Empty uses the default WebPage.

Data and code

FieldStored asTypeDefaultRules
Content (JSON)contentJSON object{}Dynamic content data for the page.
Extra (JSON)extraJSON object{}Metadata. The CMS reads the keys in “Keys of Extra” below.
State (starting assigns)stateListEmptySee “State entries” below. Holds Elixir.
Events (handle_event)eventsListEmptySee “Event and info entries” below. Holds Elixir.
Infos (handle_info)infosListEmptySee “Event and info entries” below. Holds Elixir.
Resource Linksresource_linksListEmptySee “Resource link entries” below.
Helper FunctionshelpersListEmptySee “Helper entries” below. Holds Elixir.
File UploadsuploadsListEmptySee “Upload entries” below. The box sits after all the others.

Path rules

  • Starts with / and is 1 to 255 characters long.
  • Holds only letters, digits and the characters - _ / . : *.
  • Holds no .. and no //.
  • A segment that starts with :, such as :lang or :slug, is a capture. A segment that starts with *, such as *rest, takes the rest of the address.
  • A capture named lang must match one of the site's languages.
  • Between two patterns that match, the one with fewer captures wins. A literal path wins over any pattern.

SEO tag entries

BoxStored asRules
TagtagRequired. title, meta or link.
AttributesattrsRequired. A JSON object, such as {"name": "description"}.
ContentcontentText, optional.

State entries

BoxStored asRules
Assign NamenameRequired. Starts with a lowercase letter or _, then letters, digits or _. Does not start with __. Used once in the list. Not a name the runtime owns, such as page, flash, socket, uploads or current_user.
First ValuecodeRequired. An Elixir expression. It runs once for each visitor when the page mounts.

Event and info entries

FieldBoxStored asRules
Events (handle_event)Event NamenameRequired. The event the template sends, such as click or submit.
Events (handle_event)Event CodecodeRequired. Elixir that runs on the socket.
Infos (handle_info)Info NamenameRequired. The message the page handles.
Infos (handle_info)Info CodecodeRequired. Elixir that runs on the socket.

Helper entries

BoxStored asRules
Function NamenameRequired.
ArgumentsargsComma-separated names. Empty makes a function with no arguments.
Function BodycodeRequired. Elixir.

Upload entries

Each entry becomes one allow_upload/3 that the page registers when a visitor opens it. Use the name in a file field as upload={@uploads.<name>}.

BoxStored asDefaultRules
Upload NamenameNoneRequired. Two entries with one name keep the first.
Accepted TypesacceptAnyComma-separated types, such as image/*, .pdf.
Maximum Filesmax_entries1At most 10.
Maximum Size (bytes)max_file_size8000000At most 20000000.
Upload Immediatelyauto_uploadOffA switch.

Keys of Extra

KeyValueWhat it does
recordText, such as blog:postSet by This page shows each. Names the kind of record each address of the page shows.
serves_all_languagestrueThe page answers every language of its site. Needs :lang in the path, or the CMS refuses the page.
visitors_onlytrueThe page opens only for a visitor who is not signed in. A signed-in visitor goes to the site root.
signed_in_onlytrueThe page opens only for a signed-in visitor. Anyone else goes to the sign-in page.
auth_roleText, such as sign_inMarks a sign-in page. Like visitors_only, it keeps the page out of search indexes unless its SEO tags say otherwise.
provisioned_by, provisioned_versionTextWritten by the installer and by extensions to say who gave the site the page, and at which version.

Stored without a box

Stored asWhat it holds
nameThe page's key, made from Title on create. 3 to 200 characters. If a page on any site already holds the name, the CMS adds -2, -3 and so on, so a second site's Pricing page is named pricing-2. A name that a caller passes, as the API and the installer do, has to be free only on its own site.
preview_tokenAn unguessable token for the shareable preview address. Made on create.
inserted_at, updated_atWhen the page was created and last changed.
archived_atWhen the page was archived. An archived page cannot be edited.

Rules and messages

RuleMessage
The path starts with /Path must start with '/'
The path is at most 255 charactersPath must be at most 255 characters
The path has no ..Path must not contain '..' (directory traversal)
The path has no //Path must not contain '//' (empty path segment)
The path uses allowed charactersPath may only contain letters, digits, and the characters - _ / . : *
The path is unique within the sitePage path must be unique within a site.
The name is unique within the sitePage name must be unique within a site.
One page per language in a groupA page with this language already exists in this language group.
No other active page answers an address of an active pageThe page “<title>” at <path> already answers at <address>.
serves_all_languages needs :langOnly a path with :lang in it can answer every language. Add :lang to the path, or let the page answer its own language.
A saved template is not blankTemplate cannot be empty.
An archived page is not editedCannot edit archived page. Please unarchive it first.
A state name is a free assign name<name> is an assign the runtime already sets; choose another name.
Every state entry has a nameEvery state entry needs a name.
A state name is used onceThe state names <name> twice; each name is one assign.

The CMS also checks that the template, events, infos, state and helpers compile before it stores them, and puts the error under the box it came from. The layout and the language group must belong to the page's site, and a layout may be a shared one.

Who can write

  • On the dashboard, admin:dashboard:runtime:page or admin:dashboard:code. On the admin API, admin:api:runtime:page or admin:api:code. A wildcard that covers one of them also works.
  • Any account with a permission under the surface can read pages. A site account reads only its own site's pages.
  • A deployment can turn off code that the server runs with config :mishka_cms_core, :page_code, :off. Then no one can add Elixir to Events, Infos, State or Helper Functions, or type a template by hand, a master included. Code already stored keeps compiling.