0

I created a Wordpress Plugin to display Events.

The plugin is developed via Wordpress Block and works fine. The url to the detail page is http://localhost:4444/?slug=02-12-2024_artist_name

To make it better readable, the url should look like http://localhost:4444/event/02-12-2024_artist_name

I added this code to my plugin.php script

add_action('init',  function () {
    add_rewrite_rule('event/([a-z0-9-]+)[/]?$', 'index.php?slug=$matches[1]', 'top');
    add_rewrite_tag('%slug%', '([^&]+)');
    error_log("Rewrite rules added");
});

add_filter('query_vars', function ($query_vars) {
    $query_vars[] = 'slug';
    return $query_vars;
});

But the rewrite doesn´t work correctely and i get a 404 "page not found".

I tried to implement the render.php a second time (first time is via block.json), but I think it´s not the right way, cause I didn´t get my attributes

add_filter('template_include', function ($template) {
    if (get_query_var('slug') == false || get_query_var('slug') == '') {
        require_once plugin_dir_path(__FILE__) . 'src/render.php';
        return $template;
    }
});

Addition how I create the event:

class Blocks
{
    public static function init()
    {
        // Block-Registrierung
        add_action('init', [__CLASS__, 'promotion_block_init']);
    }

    // Block initialisieren und Bootstrap laden
    public static function promotion_block_init()
    {
        // Register the block from the build directory
        register_block_type(plugin_dir_path(__FILE__) . '../build');
        // Optionale Einbindung von Bootstrap
        wp_register_style('bootstrap_handle', 'https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css');
    }
}

block.json in the plugins root

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "copilot/promotion",
    "version": "3.0.0",
    "title": "Copilot Promotion",
    "category": "widgets",
    "icon": "star-empty",
    "description": "Ausspielen deiner Events aus co*pilot",
    "supports": {
        "html": false
    },
    "attributes": {
        "isArchive": {
            "type": "boolean",
            "default": false
        },
        "useFaceDetection": {
            "type": "boolean",
            "default": false
        },
        "selectedPagination": {
            "type": "string",
            "default": "20"
        },
        "selectedTemplate": {
            "type": "string",
            "default": "list"
        }
    },
    "textdomain": "copilot",
    "editorScript": "file:./index.js",
    "editorStyle": "file:./index.css",
    "style": [
        "file:./style-index.css",
        "file:./style-view.css",
        "bootstrap_handle"
    ],
    "render": "file:./render.php",
    "viewScript": "file:./view.js"
}

<?php

$slug = "";
if (isset($_GET["copilot-slug"]) && preg_match("/^[A-Za-z0-9\-\+_]+$/", $_GET["copilot-slug"])) {
    $slug = $_GET["copilot-slug"];
}

if (!function_exists('render_copilot_block')) {
    function render_copilot_block($attributes, $slug)
    {
        $unique_id = uniqid('copilot-render-');
        $selectedTemplate = isset($attributes['selectedTemplate']) ? $attributes['selectedTemplate'] : 'list';
        $selectedPagination = isset($attributes['selectedPagination']) ? $attributes['selectedPagination'] : '20';
        $useFaceDetection = isset($attributes['useFaceDetection']) ? $attributes['useFaceDetection'] : 'false';
        $isArchive = isset($attributes['isArchive']) ? $attributes['isArchive'] : 'false';
        $pluginPath = plugins_url('', __FILE__) . "/../";

        echo '
        <div 
            id="' . esc_attr($unique_id) . '"
            class="w-100 copilot-render"
            data-copilotpluginpath="' . $pluginPath . '" 
            data-copilotslug="' . esc_attr($slug) . '" 
            data-copilottemplate="' . esc_attr($selectedTemplate) . '" 
            data-copilotpagination="' . esc_attr($selectedPagination) . '" 
            data-copilotusefacedetection="' . esc_attr($useFaceDetection) . '" 
            data-copilotisarchive="' . esc_attr($isArchive) . '" 
        ></div>
        ';
    }
}

render_copilot_block($attributes, $slug);

The view.tsx

// @ts-ignore
import domReady from "@wordpress/dom-ready";
import { createRoot } from "react-dom/client";
// @ts-ignore
import "./style.scss";

// @ts-ignore
import Banner from "./components/Banner";
import Events from "./components/Events";
import SingleEvent from "./components/SingleEvent";

domReady(() => {
    const copilotContainers = document.querySelectorAll(".copilot-render");

    // Loop through each element
    copilotContainers.forEach((container) => {
        const element = container as HTMLElement;
        const uniqueId = element.id;

        if (uniqueId) {
            const root = createRoot(element);
            root.render(<View attributes={element.dataset as Attributes} />);
        }
    });
});

type Attributes = {
    copilotslug: string;
    copilotpagination: string;
    copilottemplate: string;
    copilotpluginpath: string;
    copilotusefacedetection: string;
    copilotisarchive: string;
};

function View({ attributes }: { attributes: Attributes }) {
    const {
        copilotslug,
        copilottemplate,
        copilotpagination,
        copilotpluginpath,
        copilotusefacedetection,
        copilotisarchive,
    } = attributes;

    const useFaceDetection = copilotusefacedetection === "1";
    const isArchive = copilotisarchive === "1";

    if (copilottemplate === "banner") {
        return <Banner useFaceDetection={useFaceDetection} />;
    }

    if (copilotslug) {
        return <SingleEvent slug={copilotslug} />;
    }

    return (
        <Events
            selectedpagination={parseInt(copilotpagination)}
            isArchive={isArchive}
        />
    );
}
4
  • 1
    how is created this url with "slug" ? if it's a wordpress page or a custom post type, a pretty url already exists.
    – mmm
    Commented Dec 1 at 12:38
  • The url is created in my plugin this is the existing path to the the event detail page localhost:4444/?slug=02-12-2024_artist_name Commented Dec 5 at 14:28
  • edit your question to show us the code you use to create the events.
    – mmm
    Commented Dec 5 at 20:21
  • I added the complete workflow Commented Dec 11 at 14:48

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.