Filters

The plugin exposes WordPress filters to let the developer alter specific data.

wordless_pug_configuration

wordless/helpers/pug/wordless_pug_options.php
<?php

class WordlessPugOptions {
    public static function get_options() {
        $wp_debug = defined('WP_DEBUG') ? WP_DEBUG : false;
        return apply_filters( 'wordless_pug_configuration', [
            'expressionLanguage' => 'php',
            'extension' => '.pug',
            'cache' => Wordless::theme_temp_path(),
            'strict' => true,
            'debug' => $wp_debug,
            'enable_profiler' => false,
            'error_reporting' => E_ERROR | E_USER_ERROR,
            'keep_base_name' => true,
            'paths' => [Wordless::theme_views_path()],
            'mixin_keyword' => ['mixin','component'],
        ]);
    }
}

Usage example

<?php
add_filter('wordless_pug_configuration', 'custom_pug_options', 10, 1);

function custom_pug_options(array $options): array {
    $options['expressionLanguage'] = 'js';

    return $options;
}

wordless_acf_gutenberg_blocks_views_path

wordless/helpers/acf_gutenberg_block_helper.php
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  function _acf_block_render_callback( $block ) {
    $slug = str_replace('acf/', '', $block['name']);

    // The filter must return a string, representing a folder relative to `views/`
    $blocks_folder = apply_filters('wordless_acf_gutenberg_blocks_views_path', 'blocks/');

    $admin_partial_filename = Wordless::theme_views_path() . "/{$blocks_folder}/admin/_{$slug}";

    if (
      file_exists( "{$admin_partial_filename}.html.pug" ) ||
      file_exists( "{$admin_partial_filename}.pug" ) ||
      file_exists( "{$admin_partial_filename}.html.php" ) ||
      file_exists( "{$admin_partial_filename}.php" )
    ) {
        $admin_partial = "{$blocks_folder}/admin/{$slug}";
    } else {
        $admin_partial = "{$blocks_folder}/{$slug}";
    }

Usage example

<?php
add_filter('wordless_acf_gutenberg_blocks_views_path', 'custom_blocks_path', 10, 1);

function custom_blocks_path(string $path): string {
    return 'custom_path';
}

This way Wordless will search for blocks’ partials in views/custom_path/block_name.html.pug so you can use render_partial('custom_path/block_name') to render them in your template.

The default path is blocks/.

Note

The path will be always relative to views/ folder

Actions

wordless_component_validation_exception

wordless/helpers/component_helper.php
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
        try {
            $this->setProperties();
            $this->validate();
        } catch (ComponentValidationException $e) {
            if ( 'production' === ENVIRONMENT ) {
                do_action('wordless_component_validation_exception', $e);
                // Would be nice to have an exception collector in your callback, e.g. Sentry:
                //
                // function yourhandler(\Wordless\ComponentValidationException $e) {
                //      if ( function_exists( 'wp_sentry_safe' ) ) {
                //          wp_sentry_safe( function ( \Sentry\State\HubInterface $client ) use ( $e ) {
                //                         $client->captureException( $e );
                //                     } );
                //      }
                // }
                // add_action('wordless_component_validation_exception', 'yourhandler', 10, 1)
            } else {
                render_error('Component validation error', $e->getMessage());
            }

When an object of class Wordless\Component fails its validation, it will throw an exception only if ENVIRONMENT is not production. When in production nothing will happen, in order to be unobstrusive and not breaking the site to your users. The developer will still see specific excpetion happening.

You can customize the behaviour by adding your action as documented in the code.

What we like to do is to add here a notification to our Sentry account (thanks to https://github.com/stayallive/wp-sentry/ plugin)