Settings

v0.0.1

Settings hold the choices that apply to a whole Mishka CMS installation or to one site: the site title, the languages, maintenance mode, sign-in limits, email, captcha, the sidebar and more. This page lists every setting key with its tab, its group, its default and whether it is global or per site. To change a setting, open Settings at the bottom of the admin sidebar.

How the Settings screen works

The screen has one tab for each area. A master admin picks the scope in the select at the top of the screen: Global, or one of the sites. The select has no visible label, and a screen reader announces it as "Settings for". A site admin sees a badge such as Editing: this site in its place and always edits their own site. Press Save Changes to store the tab. Press Reset to Defaults to fill the tab with the defaults below before you save.

the General tab signed in as a master, with the scope select set to Global, the tab list on the left and the Save Changes button visible

The Settings screen with the General tab open in the Global scope.

A setting shows a badge for its reach: Global, This site or Just for you. A setting that a site may not change is read-only in the site's view, or missing from it. A tab with nothing to show to the account is not drawn.

Reach

The Reach column of the tables below uses these values.

ReachMeaning
Global, site can overrideThe Global value is the default for every site. A site can set its own value, and a site that does not uses the Global one.
Global and site, each its ownEvery scope sets its own value and never takes the Global one. Email and captcha settings work this way, so a site never sends mail or asks a captcha with another site's key.
Global and site, either turns it onThe Global and the site value are combined. A site can add to a Global on but cannot undo it.
Global onlyOne value for every site. A site sees it read-only.
Master onlyOne value for every site. Only the Global view shows it, and a site admin does not see it.
Site onlyEach site sets its own. The Global view does not show it.
Per userEach admin sets their own, and only that admin sees it.

A read for a site uses the site's value, then the Global value, then the default. The exceptions are the settings that are each its own, which skip the Global value, and the ones where either turns it on.

Writing a setting takes admin:dashboard:setting, unless the setting names another permission. Every dashboard admin can open the screen, and it shows the tabs and fields that the account can write. See Permission names.

Types

TypeInput
stringOne line of text.
textSeveral lines of text.
booleanA switch.
integerA number. A value outside the minimum or maximum is clamped to it.
selectOne value from a fixed list.
listValues separated by commas. Each is trimmed, and blanks and repeats are dropped.
secretA key. It is stored sealed and never shown again. A stored key shows Saved, ends in … with its last four characters and a Remove button. With no key the field shows Not set.
imageA path on the site, or an http or https address, from Media or typed. Empty means none.

Tabs

The core tabs come in this order: General, Notifications, Security, SEO and Email. The tabs that plugins and extensions register follow them, and Preferences is always last. A site shows only the tabs its installed extensions add.

TabWhat it holds
GeneralBasic system settings: the site's name and pictures, languages, maintenance mode.
NotificationsWhich alerts the site sends and how long they are kept.
SecuritySign-in limits, closing sign-in or registration, two-step sign-in, captcha and embeds.
SEOSearch engines, robots.txt, the sitemap and share cards.
EmailThe provider, the sender, a test email and the email history.
BlogSettings of the blog extension.
DocumentsSettings of the document extension.
NewsletterSettings of the newsletter extension: the confirmation page, sign-up limits and the Resend connection.
SidebarThe order of the admin navigation and which entries show.
Share cardsThe label, pitch and chips of the share cards that a plugin draws from settings. This tab shows only where such a plugin is installed.
PreferencesYour personal settings. Only you see these. This tab is always last.

General

KeyLabelGroupTypeDefaultReach
site.titleSite titleNonestringMishkaCMSGlobal, site can override
site.logoSite logoNoneimageEmptyGlobal, site can override
site.faviconFaviconNoneimageEmptyGlobal, site can override
site.languagesLanguagesNonelistenGlobal, site can override
site.language_urlsLanguage in addressesNoneselect: prefix_others, prefix_allprefix_othersGlobal, site can override
site.allowed_languagesLanguages sites may publishNonelistEmptyMaster only
site.required_languagesLanguages every site publishesNonelistEmptyMaster only
cms.offlineTake this site offline (maintenance mode). In the Global view: Take every site offline (maintenance mode)NonebooleanOffGlobal and site, either turns it on
cms.maintenance_messageMaintenance messageNonetextWe are currently undergoing maintenance. Please check back soon.Global, site can override
dashboard.widget.recent-activity.countRecent activity: Entries to showDashboard widgetsinteger, 3 to 206Per user

For site.language_urls, prefix_others gives the first language no prefix, as in /blog and /fa/blog. prefix_all gives every language a prefix, as in /en/blog and /fa/blog. A site can save only the languages that site.allowed_languages permits when it is not empty, and its list always includes the languages in site.required_languages. See Set a site's languages and language URLs.

A site is offline when its own cms.offline is on or the Global one is on. Signing in stays open so an admin can still get in. A site whose error pages include an Offline entry shows that page instead of the maintenance message.

Security

Embeds

KeyLabelTypeDefaultReach
security.frame_originsSites pages may embedlist of https originsEmptyGlobal, site can override

Sign-in limits

Each limit counts per site, and the masters are counted together. Every one has a minimum of 1.

KeyLabelTypeDefaultReach
security.sign_in_per_accountSign-in attempts per account (per 15 minutes)integer10Master only
security.sign_in_per_ipSign-in attempts per IP address (per 5 minutes)integer30Master only
security.reset_request_per_accountPassword reset requests per account (per hour)integer3Master only
security.reset_request_per_ipPassword reset requests per IP address (per hour)integer10Master only
security.magic_link_per_accountSign-in link requests per account (per hour)integer3Master only
security.magic_link_per_ipSign-in link requests per IP address (per hour)integer10Master only
security.register_per_ipNew accounts per IP address (per hour)integer10Master only
security.change_password_per_accountPassword change attempts per account (per 15 minutes)integer10Master only
security.totp_per_accountAuthenticator codes per account (per 5 minutes)integer5Master only

Two-step sign-in

KeyLabelTypeDefaultReach
security.two_step.every_siteTwo-step sign-in for admins on every siteselect: sites (Each site decides), off, optional, recommended, requiredsitesMaster only
security.two_stepTwo-step sign-in for this site's adminsselect: off, optional, recommended, requiredoptionalSite only

A master's choice for every site comes first. With sites, each site's own choice applies, and the master site's applies to masters. See Secure sign-in.

Closed and Still allowed

KeyLabelGroupTypeDefaultReach
auth.sign_in.closedClose sign-in. In the Global view: Close sign-in on every siteClosedbooleanOffGlobal and site, either turns it on
auth.sign_in.sign_outSign out who is signed in. In the Global view: Sign out who is signed in on every siteClosedbooleanOffGlobal and site, either turns it on
auth.register.closedClose registration. In the Global view: Close registration on every siteClosedbooleanOffGlobal and site, either turns it on
auth.reset.closedClose password reset. In the Global view: Close password reset on every siteClosedbooleanOffGlobal and site, either turns it on
auth.magic_link.closedClose sign-in links. In the Global view: Close sign-in links on every siteClosedbooleanOffGlobal and site, either turns it on
auth.allowed_permissionsPermissions that still get inStill allowedlist of permission names*Global, site can override
auth.allowed_emailsAccounts that still get inStill allowedlist of email addressesEmptyGlobal, site can override

Masters can always sign in, at /auth?master_user=true (see the documentation). While a way in is closed, whoever holds one of the permissions in auth.allowed_permissions, or is listed in auth.allowed_emails, still gets through. Registration also admits the listed addresses.

Captcha

Every captcha setting is each scope's own. The JSON API never asks a captcha. A provider's own fields show only while that provider is chosen.

KeyLabelGroupTypeDefaultReach
security.captcha.providerCaptchaCaptchaselect: none, turnstile, recaptcha, hcaptchanoneGlobal and site, each its own
security.captcha.check_domainRefuse a check solved on another addressCaptchaboolean. Shown while a provider is chosen.OnGlobal and site, each its own
security.captcha.turnstile.site_keyTurnstile site keyCloudflare TurnstilestringEmptyGlobal and site, each its own
security.captcha.turnstile.secret_keyTurnstile secret keyCloudflare TurnstilesecretEmptyGlobal and site, each its own
security.captcha.recaptcha.versionreCAPTCHA kindGoogle reCAPTCHAselect: v2 (the "I'm not a robot" box), v3 (invisible, by score)v2Global and site, each its own
security.captcha.recaptcha.site_keyreCAPTCHA site keyGoogle reCAPTCHAstringEmptyGlobal and site, each its own
security.captcha.recaptcha.secret_keyreCAPTCHA secret keyGoogle reCAPTCHAsecretEmptyGlobal and site, each its own
security.captcha.recaptcha.min_scoreLowest v3 score let through (out of 100)Google reCAPTCHAinteger, 1 to 100. Shown while the kind is v3.50Global and site, each its own
security.captcha.hcaptcha.site_keyhCaptcha site keyhCaptchastringEmptyGlobal and site, each its own
security.captcha.hcaptcha.secret_keyhCaptcha secret keyhCaptchasecretEmptyGlobal and site, each its own

Notifications

KeyLabelGroupTypeDefaultReach
notify.cms_core.user.permissions_changedNotify admins when a user's permissions changeEventsbooleanOnGlobal, site can override
notify.cms_core.page_comment.mentionedNotify people named in a review noteEventsbooleanOnGlobal, site can override
notify.retention_read_daysDelete read notifications after (days)Retentioninteger30Global only
notify.retention_max_daysDelete all notifications after (days)Retentioninteger180Global only

Email

The tab also holds Send a test email, which sends through the provider of the scope in view, and Email history. A provider's own fields show only while that provider is chosen. A site that has no provider sends no email. The Email tab shows a red dot until the sender and the provider are set. See Send email from your site.

KeyLabelGroupTypeDefaultReach
mailer.providerEmail providerDeliveryselect: none, resend, and dev_mailbox where the deployment enables itnone. A development configuration defaults to dev_mailbox.Global and site, each its own
mailer.resend.api_keyResend API keyResendsecretNot setGlobal and site, each its own
mailer.fromOutgoing email "from" addressSenderstringEmpty. An empty value sends from noreply@ the site's own domain.Global and site, each its own
mailer.from_nameSender nameSenderstringEmpty. An empty value uses the site's title.Global and site, each its own
mailer.reply_toReply-to addressSenderstringEmptyGlobal and site, each its own
mailer.history_daysKeep the email history for (days)Historyinteger, 1 to 36530Master only

SEO

KeyLabelGroupTypeDefaultReach
seo.robots.extraExtra robots.txt rulesNonetextEmptyGlobal, site can override
seo.sitemap.pathsExtra sitemap addressesNonelist. Each starts with /.EmptySite only
share_cards.workersShare-card workersShare cardsinteger, 0 to 41Master only

The tab also holds the Share cards panel for whoever may change the site logo. It has the Redraw all share cards button and a Redraw these row for each extension that draws cards. See Set a page's SEO and share card.

Blog and Documents

Each extension adds its own tab. The tab holds the two switches that every extension has, its notification toggles and the settings of its dashboard widgets. The two switches use the key prefix mishka_blog on the Blog tab and mishka_document on the Documents tab.

KeyTabLabelGroupTypeDefaultReach
mishka_blog.installedBlogSet up at versionNonestring, read-onlyBlank until the installer has set the site upSite only
mishka_blog.activeBlogActive on this siteNonebooleanOnSite only
notify.blog.post.publishedBlogNotify blog admins when a post is publishedNotificationsbooleanOnGlobal, site can override
dashboard.widget.blog-bloggers.countBlogBloggers: Bloggers to rankDashboard widgetsinteger, 3 to 125Per user
dashboard.widget.blog-recent-posts.countBlogRecent posts: Posts to showDashboard widgetsinteger, 1 to 124Per user
dashboard.widget.blog-comments-moderation.countBlogComments to moderate: Comments to showDashboard widgetsinteger, 1 to 103Per user
dashboard.widget.blog-drafts-scheduled.countBlogDrafts & scheduled: Posts to listDashboard widgetsinteger, 1 to 124Per user
dashboard.widget.blog-top-posts.countBlogTop posts: Posts to rankDashboard widgetsinteger, 3 to 125Per user
mishka_document.installedDocumentsSet up at versionNonestring, read-onlyBlank until the installer has set the site upSite only
mishka_document.activeDocumentsActive on this siteNonebooleanOnSite only
dashboard.widget.doc-recent.countDocumentsRecent documents: Documents to showDashboard widgetsinteger, 1 to 125Per user
dashboard.widget.doc-open-issues.countDocumentsOpen issues: Issues to listDashboard widgetsinteger, 1 to 125Per user
dashboard.widget.doc-version-activity.countDocumentsVersion activity: Versions to showDashboard widgetsinteger, 3 to 3012Per user

A widget setting is labelled with the title of the widget followed by the name of the setting. The key dashboard.widget.<widget id>.count is the same value the gear on the dashboard card sets.

The switch <app>.active hides the extension's menu and stops its pages being served on the site when it is off. Nothing is deleted. The <app>.installed key is written by the installer, and an admin cannot edit it.

Preferences

These settings are yours alone. Each is stored under the key with ::u:: and your user id added. A widget setting from another tab is also yours alone.

KeyLabelGroupTypeDefaultReach
notify.pref.cms_core.user.permissions_changedUser permission changesNotificationsbooleanOnPer user
notify.pref.cms_core.page_comment.mentionedBeing named in a review noteNotificationsbooleanOnPer user
notify.pref.blog.post.publishedNew posts publishedNotificationsbooleanOnPer user

Keys the CMS stores outside the Settings screen

The visual editor and the dashboard use these keys. They have no field on the Settings screen. The editor reads and writes the studio.* keys for the site it is open on. A site's value wins, and the Global value is the fallback.

KeyUsed byDefault
studio.dark_pairStudio switch Generate dark pairOff
studio.sync_tokensStudio switch Sync tokens across sitesOff
studio.lock_tokensStudio switch Lock tokensOff
studio.registry_sourceThe registry source in the Studioregistry.mishka.tools
studio.license_tokenThe license token field in the StudioEmpty
studio.applied_presetThe preset the Studio marks as appliedNone
builder:preset:<component>The preset choices of one componentNone
dashboard.layout.<user id>The dashboard layout of one adminNone

Writing a studio.* or builder:preset:* key takes any permission that opens a builder, such as admin:dashboard:runtime:page or admin:dashboard:code.