Skip to content

Commit 1714d6e

Browse files
authored
Adding new snippet for block- and javascript-less rendering of Fediverse Reactions (#2958)
1 parent 293cb1b commit 1714d6e

File tree

4 files changed

+160
-0
lines changed

4 files changed

+160
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: added
3+
4+
Add snippet for blockless fediverse reactions

snippets/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Think of snippets as a testing ground, similar to WordPress' [feature plugin](ht
1111
| [Bot Account](bot-account/) | Marks ActivityPub profiles as bot/automated accounts, displaying a "BOT" badge in the Fediverse. |
1212
| [FediBlog Tag](fediblog-tag/) | Automatically adds the `FediBlog` tag to standard format blog posts. |
1313
| [Locale from Tags](locale-from-tags/) | Sets a post's ActivityPub language based on post tags matching language codes. |
14+
| [Blockless ActivityPub](blockless-activitypub/) | Fediverse reactions without all that frontend-rendered but JavaScript-heavy blocks magic. |
1415

1516
## How to Use
1617

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Blockless ActivityPub
2+
3+
This snippet for ActivityPub allows showing the **Fediverse reactions** even on a theme that does not support blocks and aims to **remove the need for all that JavaScript** that comes with front-end rendered blocks.
4+
5+
Additionally it will also **disable "remote-reply"** which handles the federation of local comments on Fediverse reactions, but which also requires JavaScript to be downloaded and executed.
6+
7+
## Installation
8+
9+
Copy this folder to `wp-content/plugins/` and activate **Blockless ActivityPub** from the WordPress admin, or copy `blockless-activitypub.php` to `wp-content/mu-plugins/` for automatic activation.
10+
11+
## Requirements
12+
13+
- WordPress 5.9+
14+
- PHP 7.4+
15+
- [ActivityPub](https://wordpress.org/plugins/activitypub/) plugin
16+
17+
## Origin
18+
19+
Based on a [blog post by Frank Goosssens (aka Futtta and OptimizingMatters)](https://blog.futtta.be/2026/02/12/wordpress-activitypub-plugin-what-about-performance//).
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
/**
3+
* Plugin Name: Blockless ActivityPub
4+
* Plugin URI: https://github.com/Automattic/wordpress-activitypub
5+
* Description: Make activitypub blockless and use less JS
6+
* Version: 0.3
7+
* Requires at least: 5.2
8+
* Requires PHP: 7.2
9+
* Author: Frank Goossens
10+
* Author URI: https://blog.futtta.be/2026/02/12/wordpress-activitypub-plugin-what-about-performance/
11+
* License: GPL v2 or later
12+
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
13+
* Requires Plugins: activitypub
14+
*
15+
* @package Activitypub
16+
*/
17+
18+
namespace Activitypub\Snippets;
19+
20+
// Exit if accessed directly.
21+
if ( ! defined( 'ABSPATH' ) ) {
22+
exit;
23+
}
24+
25+
// Don't do 'remote reply' by removing the filter.
26+
\add_action(
27+
'template_redirect',
28+
function () {
29+
\remove_filter(
30+
'comment_reply_link',
31+
array( \Activitypub\Comment::class, 'comment_reply_link' ),
32+
10
33+
);
34+
}
35+
);
36+
37+
// This could be useful at some point.
38+
// phpcs:ignore Squiz.Commenting.InlineComment.InvalidEndChar
39+
// \add_filter( 'activitypub_site_supports_blocks', '__return_false', 8 );
40+
41+
// Render fediverse reactions server-side.
42+
\add_action(
43+
'comments_template',
44+
function () {
45+
$post_id = \get_the_ID();
46+
$totalreactioncount = 0;
47+
$reactions = array();
48+
49+
// Get all reactions per type of reaction.
50+
foreach ( array( 'like', 'repost', 'quote' ) as $reactiontype ) {
51+
$args = array(
52+
'post_id' => $post_id,
53+
'type' => $reactiontype,
54+
'status' => 'approve',
55+
'parent' => 0,
56+
);
57+
58+
// Fetch results and store in array per reactiontype.
59+
$query = new \WP_Comment_Query();
60+
$reactions[ $reactiontype ] = $query->query( $args );
61+
62+
// Keep track of total number of reactions to show in the title.
63+
$totalreactioncount += count( $reactions[ $reactiontype ] );
64+
}
65+
66+
// Bail if none found.
67+
if ( 0 === $totalreactioncount ) {
68+
return;
69+
}
70+
71+
// Start output, including styles.
72+
echo '<style>
73+
div#fedifeedback{
74+
padding-bottom:44px;
75+
}
76+
div.fedireactiontyperow{
77+
display: flex;
78+
margin-bottom: 10px;
79+
}
80+
span.fedireactioncounter{
81+
margin-left:30px;
82+
}
83+
img.fedifacelet{
84+
width:32px;
85+
height:32px;
86+
border-radius:50%;
87+
border: 3px black;
88+
position: relative;
89+
top: 0;
90+
transition: transform ease 0.5s;
91+
-moz-force-broken-image-icon: 1;
92+
overflow: hidden;
93+
}
94+
img.fedifacelet:hover{
95+
transform: scale(1.77);
96+
}
97+
</style>
98+
<div id="fedifeedback">';
99+
100+
printf( '<h2>%d Fediverse reactions</h2>', \absint( $totalreactioncount ) );
101+
102+
// Iterate through the array for each reactiontype (like, repost, quote).
103+
foreach ( $reactions as $reactiontype => $reactionlist ) {
104+
if ( empty( $reactionlist ) ) {
105+
continue;
106+
}
107+
108+
// Output avatars for this reactiontype.
109+
echo '<div class="fedireactiontyperow">';
110+
foreach ( $reactionlist as $reaction ) {
111+
\printf(
112+
'<a href="%1$s"><img class="fedifacelet" src="%2$s" alt="%3$s" title="%3$s" /></a>',
113+
\esc_url( $reaction->comment_author_url ),
114+
\esc_url( \get_avatar_url( $reaction ) ),
115+
\esc_html( $reaction->comment_author )
116+
);
117+
}
118+
119+
// Ugly shortcut for plurals, no multilang yet either.
120+
$reactioncount = count( $reactionlist );
121+
if ( $reactioncount > 1 ) {
122+
$reactiontype .= 's';
123+
}
124+
125+
\printf(
126+
'<span class="fedireactioncounter">%d %s</span></div>',
127+
\absint( $reactioncount ),
128+
\esc_html( $reactiontype )
129+
);
130+
}
131+
132+
echo '</div>';
133+
},
134+
10,
135+
0
136+
);

0 commit comments

Comments
 (0)