vaersaagod / toolmate
Is that a tool in your pocket, or are you just happy to see me, mate?
Installs: 1 355
Dependents: 0
Suggesters: 0
Security: 0
Stars: 3
Watchers: 5
Forks: 1
Open Issues: 1
Type:craft-plugin
Requires
- php: ^8.0
- craftcms/cms: ^3.1.0|^4.0.0-beta.1|^5.0.0-beta.1
- matthiasmullie/minify: ^1.3.0
- voku/html-min: ^4.4.0
README
Is that a tool in your pocket, or are you just happy to see me, mate!
Requirements
This plugin requires Craft CMS 3.1.0 or later.
Installation
To install the plugin, either install it from the plugin store, or follow these instructions:
- Install with composer via
composer require vaersaagod/toolmate
from your project directory. - Install the plugin in the Craft Control Panel under Settings → Plugins, or from the command line via
./craft install/plugin toolmate
.
Configuring
ToolMate can be configured by creating a file named toolmate.php
in your Craft config folder,
and overriding settings as needed.
publicRoot [string]
Default: @webroot
Sets the public webroot that is used by inline and stamp on servers
where $_SERVER['DOCUMENT_ROOT']
and @webroot
is incorrect.
enableMinify [bool]
Default: true
Enables/disables all minifying.
embedCacheDuration [int|string|bool|null]
Default: null
The number of seconds to cache responses from craft.toolmate.getVideoEmbed()
.
If set to null
, the core cacheDuration
setting is used.
If set to false
responses are not cached.
If set to 0
, cached responses will be stored indefinitely.
See craft\helpers\ConfigHelper::durationInSeconds()
for a list of supported value types.
embedCacheDurationOnError [int|string|bool|null]
Default: 300
(5 minutes)
The number of seconds to cache responses from craft.toolmate.getVideoEmbed()
when there is an error (i.e. a valid embed code could not be returned).
If set to null
, the default value (300
, 5 minutes) is used.
If set to false
, error responses are not cached.
If set to 0
, error response caches will be stored indefinitely.
See craft\helpers\ConfigHelper::durationInSeconds()
for a list of supported value types.
csp [array|null]
Default null
Configure the Content-Security-Policy header set by Toolmate. Some useful tips:
- Avoid using
unsafe-inline
andunsafe-eval
policies, especially for thescript-src
directive. CSP nonces should ideally be used for inline script or style tags, see thecspNonce()
Twig function. - Nonces and
unsafe-inline
cannot be combined. Toolmate works around this to avoid CSP errors, but TLDR; is that you don't need to set nonces if you're also usingunsafe-inline
. - CSP nonces generated by
cspNonce()
are safe to put inside{% cache %}
tags - To enable data-URLs, add a
data:
policy to the relevant directives - For CP requests, Toolmate will always add the necessary
unsafe-inline
andunsafe-eval
policies, because the CP isn't possible to use without.
csp[enabled] [bool]
Default false
If set to false
, the CSP header will not be sent for any requests.
csp[enabledForCp] [bool]
Default false
If set to false
, the CSP header will only be sent for site requests.
csp[reportOnly] [bool]
Default false
If set to true
, the CSP header will be sent, but not enforced (i.e. dry-run mode). Useful for testing policies.
csp[directives] [array]
See https://content-security-policy.com/, and the example config below.
Example CSP configuration:
'csp' => [ 'enabled' => true, 'enabledForCp' => false, 'reportOnly' => false, 'directives' => [ 'defaultSrc' => [ "'self'", ], 'scriptSrc' => [ "'self'", "'unsafe-inline'", ], // Sources for stylesheets 'styleSrc' => [ "'self'", "'unsafe-inline'", ], // Sources for images 'imgSrc' => [ "'self'", 'https://some-project.imgix.net', 'data:' ], // Sources for iframes 'frameSrc' => [ "'self'", 'https://www.youtube.com https://player.vimeo.com https://www.facebook.com https://www.googletagmanager.com https://bid.g.doubleclick.net', ], // Domains that are allowed to iframe this site 'frameAncestors' => [ "'self'", ], 'baseUri' => [ "'none'", ], 'connectSrc' => [], 'fontSrc' => [ //"'self'", ], 'objectSrc' => [], 'mediaSrc' => [], 'sandbox' => [], 'reportUri' => [], 'childSrc' => [], 'formAction' => [], 'reportTo' => [], 'workerSrc' => [], 'manifestSrc' => [], 'navigateTo' => [], ], ],
Template variables
craft.toolmate.inline(filename [, remote=false])
{{ craft.toolmate.inline('/assets/critical.css') }}
craft.toolmate.stamp(filename [, mode = 'file', type = 'ts'])
{# /assets/bundle.1522425799.js #}
{{ craft.tool.stamp('/assets/bundle.js') }}
{# /assets/1522425799/bundle.js #}
{{ craft.tool.stamp('/assets/bundle.js', 'folder') }}
{# /assets/5140247221/bundle.js #}
{{ craft.tool.stamp('/assets/bundle.js', 'folder', 'hash') }}
{# /assets/bundle.js?ts=1522425799 #}
{{ craft.tool.stamp('/assets/bundle.js', 'query') }}
{# 1522425799 #}
{{ craft.tool.stamp('/assets/bundle.js', 'tsonly') }}
craft.toolmate.setCookie(params [, secure = false])
{% do craft.toolmate.setCookie({ name: 'testing', value: 'Just testing!' }) %}
{% do craft.toolmate.setCookie({ name: 'testingsecure', value: { lorem: 'ipsum', dolor: 'sit amet' } }, true) %}
{% set params = {
name: 'cookiename',
value: 'thevalue',
expire: 0,
path: '/',
domain: '',
secure: false,
httpOnly: false,
sameSite: null,
} %}
{% do craft.toolmate.setCookie(params) %}
craft.toolmate.getCookie(name [, secure = false])
{{ craft.toolmate.getCookie('testing') }}
{{ dump(craft.toolmate.getCookie('testingsecure', true)) }}
craft.toolmate.getVideoEmbed(url [, params = []])
{% set videoEmbed = craft.toolmate.getVideoEmbed(videoUrl, {
youtube_enablejsapi: 1,
youtube_rel: 0,
youtube_showinfo: 0,
youtube_controls: 1,
youtube_autoplay: 0,
youtube_modestbranding: 1,
youtube_playsinline: 0,
vimeo_byline: 0,
vimeo_title: 0,
vimeo_autoplay: 0,
vimeo_portrait: 0
}) %}
Twig tags
minify
<style>
{% minify css %}
.lorem {
width: 200px;
}
.ipsum {
padding: 0px;
}
{% endminify %}
</style>
<script>
{% minify js %}
var myFunction = function () {
console.log('Some inline JS');
}
{% endminify %}
</script>
{% minify html %}
<div>
<p>Some html</p>
</div>
{% endminify %}
Twig functions
inline(filename [, remote=false])
See craft.toolmate.inline
.
stamp(filename [, mode = 'file', type = 'ts'])
See craft.toolmate.stamp
.
setCookie(params [, secure = false])
See craft.toolmate.setCookie
.
getCookie(name [, secure = false])
See craft.toolmate.getCookie
.
getVideoEmbed(url [, params = []])
See craft.toolmate.getCookie
.
cspNonce(directive, [, asAttribute = false, hash = true])
Output a CSP nonce. Example:
<script nonce="{{ cspNonce('script-src') }}"> console.log('Hello world'); </script>
<style nonce="{{ cspNonce('style-src') }}"> body { ... } </style>
{% js 'foo.js' with { nonce: cspNonce('script-src') } %}
Price, license and support
The plugin is released under the MIT license. It's made for Værsågod and friends, and no support is given. Submitted issues are resolved if it scratches an itch.
Changelog
See CHANGELOG.MD.
Credits
Brought to you by Værsågod
Icon designed by Freepik from Flaticon.