cearls / timberland

A modern WordPress theme using Timber, Advanced Custom Fields Pro, Vite, Tailwind and Alpine.js
MIT License
78 stars 19 forks source link

Blocks not displaying on pages #34

Closed mattverb closed 1 month ago

mattverb commented 7 months ago

I'm trying to create a new block within the theme folder but it's not being registered on the front-end when I load it in via Guttenberg. The example blocks loads into the site no issue, but registering new blocks just seems to not work at all.

It's worth noting that the block is registered in ACF, and can assign fields to the block.

Theme's functions.php

<?php
/**
 * @package WordPress
 * @subpackage Timberland
 * @since Timberland 1.2.0
 */

require_once dirname(__DIR__) . '/vendor/autoload.php';

Timber\Timber::init();
Timber::$dirname = [ 'views', 'blocks' ];
Timber::$autoescape = false;

class Timberland extends Timber\Site
{
    public function __construct()
    {
        add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']);
        add_action('after_setup_theme', [$this, 'theme_supports']);
        add_filter('timber/context', [$this, 'add_to_context']);
        add_filter('timber/twig', [$this, 'add_to_twig']);
        add_action('block_categories_all', [$this, 'block_categories_all']);
        add_action('acf/init', [$this, 'acf_register_blocks']);
        //add_filter('allowed_block_types', [$this, 'allowed_block_types']);
        add_action('enqueue_block_editor_assets', [$this, 'enqueue_block_editor_assets']);

        parent::__construct();
    }

    public function add_to_context($context)
    {
        $context['site'] = $this;
        $context['menu'] = Timber::get_menu('Main');
        $context['quick_links'] = Timber::get_menu('Quick Links');
        $context['patient_resources'] = Timber::get_menu('Patient Resources');
        $context["options"] = get_fields("options");

        // Require block functions files
        foreach (glob(dirname(__FILE__) . "/blocks/*/functions.php") as $file) {
            require_once $file;
        }

        return $context;
    }

    public function add_to_twig($twig)
    {
        return $twig;
    }

    public function theme_supports()
    {
        add_theme_support('automatic-feed-links');
        add_theme_support(
            'html5',
            [
                'comment-form',
                'comment-list',
                'gallery',
                'caption'
            ]
        );
        add_theme_support('menus');
        add_theme_support('post-thumbnails');
        add_theme_support('title-tag');
        add_theme_support('editor-styles');
        add_editor_style('assets/build/editor-style.css');
    }

    public function enqueue_scripts()
    {
        wp_dequeue_style('wp-block-library');
        wp_dequeue_style('wp-block-library-theme');
        wp_dequeue_style('wc-block-style');
        wp_dequeue_script('jquery');

        $mixPublicPath = get_template_directory() . '/assets/build';

        wp_enqueue_style('style', get_template_directory_uri() . '/assets/build' . $this->mix("/app.css", $mixPublicPath));
        wp_enqueue_script('app', get_template_directory_uri() . '/assets/build' . $this->mix("/app.js", $mixPublicPath), array(), '', true);
    }

    public function block_categories_all($categories)
    {
        return array_merge([['slug' => 'custom', 'title' => __('Custom')]], $categories);
    }

    public function acf_register_blocks()
    {
        $blocks = [];

        foreach (new DirectoryIterator(dirname(__FILE__) . '/blocks') as $dir) {
            if ($dir->isDot()) continue;

            if (file_exists($dir->getPathname() . '/block.json')) {
                $blocks[] = $dir->getPathname();
            }
        }

        asort($blocks);

        foreach ($blocks as $block) {
            register_block_type($block);
        }
    }

    public function allowed_block_types()
    {
        $allowed_blocks = [
            'core/columns'
        ];

        foreach (new DirectoryIterator(dirname(__FILE__) . '/blocks') as $dir) {
            $allowed_blocks[] = 'acf/' . $dir;
        }

        return $allowed_blocks;
    }

    public function enqueue_block_editor_assets()
    {
        //wp_enqueue_style('prefix-editor-font', '//fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap');
        wp_enqueue_script('app', get_template_directory_uri() . '/assets/build/app.js');
    }

    public function mix($path, $manifestDirectory = '')
    {
        static $manifest;

        if (!$manifest) {
            if (!file_exists($manifestPath = $manifestDirectory . '/mix-manifest.json')) {
                throw new Exception('The Mix manifest does not exist.');
            }
            $manifest = json_decode(file_get_contents($manifestPath), true);
        }

        if (strpos($path, '/') !== 0) {
            $path = "/{$path}";
        }

        if (!array_key_exists($path, $manifest)) {
            throw new Exception(
                "Unable to locate Mix file: {$path}. Please check your webpack.mix.js output paths and try again."
            );
        }

        return $manifest[$path];
    }
}

new Timberland();

function acf_block_render_callback($block, $content) {
    $context = Timber::context();
    $context['post'] = Timber::get_post();
    $context['block'] = $block;
    $context['fields'] = get_fields();
    $template = $block['path'] . '/index.twig';

    Timber::render($template, $context);
}

// Remove ACF block wrapper div
function acf_should_wrap_innerblocks($wrap, $name) {
    // if ( $name == 'acf/test-block' ) {
    //     return true;
    // }
    return false;
}

add_filter('acf/blocks/wrap_frontend_innerblocks', 'acf_should_wrap_innerblocks', 10, 2);

Hero Block index.twig:

{#
/**
 * Block Name: Hero Block
 */
#}

<section class="py-64">
    <div class="container">
        <h1>{{ fields.heading }}</h1>
    </div>
</section>

block.json:

{
    "apiVersion": 2,
    "name": "acf/hero",
    "title": "Hero",
    "description": "",
    "category": "custom",
    "acf": {
      "mode": "preview",
      "renderCallback": "acf_block_render_callback"
    },
    "supports": {
      "align": false,
      "jsx": false
    },
    "example": {
      "attributes": {
        "mode": "preview",
        "data": {
          "is_preview": true
        }
      }
    }
  }

Page.twig

{% extends "base.twig" %}

{% block content %}
    {{ post.content }}
{% endblock %}
mattverb commented 7 months ago

Further to this, I have enabled WP Debug & Logging and these are the errors I am getting:

[26-Jan-2024 12:25:03 UTC] [ Timber ] Error loading your template files: C:/laragon/www/liverpool-womens-hospital/wp-content/themes/liverpool-womens/theme/blocks/hero/index.twig. Make sure one of these files exists.

[26-Jan-2024 12:25:03 UTC] [ Timber ] Error loading your template files: C:/laragon/www/liverpool-womens-hospital/wp-content/themes/liverpool-womens/theme/blocks/example-hero/index.twig. Make sure one of these files exists.

[26-Jan-2024 12:25:03 UTC] [ Timber ] Error loading your template files: C:/laragon/www/liverpool-womens-hospital/wp-content/themes/liverpool-womens/theme/blocks/example/index.twig. Make sure one of these files exists.

When clicking on the file locations however, they do exist and are the correct path? Very confused why they wouldn't be loading in.

cearls commented 7 months ago

Hi! I'm pretty sure this has to do with paths on Windows, but I don't have a Windows machine to test it. I'll see what I can find out and try to have something for you to test.

mattverb commented 7 months ago

Hi! I'm pretty sure this has to do with paths on Windows, but I don't have a Windows machine to test it. I'll see what I can find out and try to have something for you to test.

Thank you! I've tried both relative and non-relative URLs. It's very strange, I use a very similar setup on another theme (adapted version of Timber Starter Theme) and have no issues. If we could get this working that would be amazing, your theme setup is much cleaner & more reliable than the one I'm currently using.

mattverb commented 6 months ago

Hi @cearls is there any update on this at all?

cearls commented 5 months ago

Hi @mattverb, can you try replacing the following function in functions.php with the code I've included below? I'm hoping the use of DIRECTORY_SEPARATOR will make it compatible with Windows.

public function acf_register_blocks()
{
    $blocks = [];

    foreach (new DirectoryIterator(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'blocks') as $dir) {
        if ($dir->isDot()) continue;

        if (file_exists($dir->getPathname() . DIRECTORY_SEPARATOR . 'block.json')) {
            $blocks[] = $dir->getPathname();
        }
    }

    asort($blocks);

    foreach ($blocks as $block) {
        register_block_type($block);
    }
}
calico-digital commented 5 months ago

I've run into this issue when transferring a site to hosting (a couple of times), in that instance it's an issue with open basedir so you might want to look into that. In my instance, I had to open up open_basedir to get the templates to load.

chiisai-kaeru commented 1 month ago

Hi everybody! I'm trying out timberland on a Windows machine using Laragon, and I've recently came across this issue, timber won't load the index.twig template file. It has something to do with Timber and Windows file paths, I managed to get it working changing the acf_block_render_callback on functions.php to the code below:

function acf_block_render_callback( $block, $content ) {
    $context           = Timber::context();
    $context['post']   = Timber::get_post();
    $context['block']  = $block;
    $context['fields'] = get_fields();

    $slug = str_replace( 'acf/', '', $block['name'] );
    $template = 'blocks/' . $slug . '/index.twig';

    Timber::render( $template, $context );
}
zync09 commented 1 month ago

Had the same issue too on laragon on windows. Submitted a pull request with a relative fix for path.

cearls commented 1 month ago

Thanks @chiisai-kaeru and @zync09! I'll review the PR and get it merged.

chiisai-kaeru commented 1 month ago

You're welcome @cearls, and thanks to @zync09 also!