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}
/>
);
}