Améliorer ActivityPub, RSS, Fédiverse
8 bouts de code pour enrichir des fonctionnalités de partage sur le Fédiverse et l'Indieweb
Mode d’emploi et précautions à prendre
ous êtes libre d’utiliser ces « bouts de code » sur votre site WordPress, de les adapter, de les transformer, de les partager. Certains éléments peuvent avoir été inspirés par des ressources découvertes sur des forums ou par l’intelligence artificielle ou des conseils. Leur insertion peut s’effectuer en utilisant une extension comme WP Code ou selon vos compétences et selon le type de code via l’éditeur de styles du site ou votre base.php.
Le site ne peut être tenu pour responsable de l’utilisation de ces « bouts de code » qui selon votre configuration ou les interactions avec d’autres éléments de code présents sur votre site pourraient engendrer des dysfonctionnements. Cette importation par copier-coller s’effectue sous votre responsabilité. Pour information le thème de ce site est basé sur Twenty Twenty-Five. Le CMS WordPress est à jour avec la dernière version disponible.
Ces bout de code ont été créés pour enrichir une fonctionnalité du site sans devoir faire appel à une extension dédiée.
Pourquoi ces « bouts de code » ?
Le site est relié au Fédiverse notamment via l’extension ActivityPub. Il promeut également le recours aux flux RSS. Il est également compatible avec l’esprit Indieweb (publier sur son propre site, syndiquer ailleurs) dont la démarche est de partager le contenu notamment sur les réseaux choisis en conservant leur maîtrise.
Ces bouts de code visent à résoudre des problèmes de nature différente :
Attention, ils sont configurés pour ce site, donc il faudra pour chaque cas, renseigner les coordonnées de votre propre site en lieu et place de mes données !
8 bouts de code
- 1. Enlever le faux positif pour le cron d'Activity Pub
- 2. Imposer un résumé des contenus partagés sur le Fédiverse
- 3. Créer une hcard
- 4. Partager un article vers les réseaux sociaux sans extension, ni cookie
- 5. Gravatar / confirmer la balise
- 6. Fichier JSON Person
- 7. Flux RSS complet
- 8. Fil Mastodon
Les codes
Type de Code
Copier-coller le code, le modifier si besoin (notamment si présence de liens)
1. Enlever le faux positif pour le cron d’Activity Pub
En effet, les tâches cron sont gérées au niveau de l’hébergeur et non de WordPress, c’est plus efficace, mais l’extension ne le comprend pas et génère une erreur.
PHP
add_filter( 'site_status_tests', function ( $tests ) {
unset( $tests['direct']['activitypub_test_wp_cron'] );
return $tests;
}, 20 );
2. Imposer un résumé des contenus partagés sur le Fédiverse
Afficher le contenu complet d’un article surtout s’il est long peut être dissuasif et n’incite pas à se rendre sur le site pour y lire d’autres contenus. Le but de ce bout de code est d’imposer un résume sur toute instance du Fédiverse.
PHP
add_filter( 'activitypub_the_content', 'vb_activitypub_extrait_seul', 10, 2 );
function vb_activitypub_extrait_seul( $content, $post = null ) {
// Ne touche qu'aux articles, jamais aux commentaires/webmentions/messages friends
if ( ! ( $post instanceof WP_Post ) ) {
return $content;
}
$extrait = get_the_excerpt( $post );
if ( empty( $extrait ) ) {
return $content;
}
$lien = get_permalink( $post );
return '<p>' . esc_html( $extrait ) . '</p><p><a href="' . esc_url( $lien ) . '">Lire la suite sur le site</a></p>';
}
3. Créer une hcard
C’est un peu la carte d’identité qui permettra d’identifier l’auteur et le site notamment selon les standards de l’Indieweb. Attention, il faut bien renseigner vos propres données !
Extrait HTML
<!— h-card minimal IndieWeb —>
<aside class="h-card" aria-label="Informations d'auteur (IndieWeb)" style="position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);border:0;">
<a class="p-name u-url" href="https://vincentbreton.fr/">Vincent Breton</a>
<span class="p-role">Auteur et poète</span>
<span class="p-note">Auteur du site vincentbreton.fr. Journal, poésie et fiction.</span>
<a class="u-email" href="mailto:site@vincentbreton.fr">site@vincentbreton.fr</a>
<span class="p-locality">Salvagnac-Cajarc</span>,
<span class="p-region">Occitanie</span>,
<span class="p-country-name">France</span>
<a class="u-url" rel="me" href="https://vincentbreton.fr/@vbreton">Fediverse</a>
<a class="u-url" rel="me" href="https://piaille.fr/@VincentBreton">Mastodon</a>
<a class="u-url" rel="me" href="https://friendica.mesnumeriques.fr/profile/vincentbreton">Friendica</a>
<a class="u-url" rel="me" href="https://codeberg.org/VincentBreton-auteur">Codeberg</a>
<span class="p-category">Auteur Poète</span>
</aside>
4. Partager un article vers les réseaux sociaux sans extension, ni cookie
Via une page qui ne fait que relayer. Fonctionne avec le Fédiverse et Bluesky. Code du bouton de partage sous les articles.
/**
* Bouton ShareOpenly — partage Fediverse / Bluesky
* Affiché après le contenu des articles uniquement
*/
function vincentbreton_share_fediverse( $content ) {
if ( ! is_singular( 'post' ) || ! in_the_loop() ) {
return $content;
}
$url = rawurlencode( get_permalink() );
$title = rawurlencode( get_the_title() );
$share_url = "https://shareopenly.org/share/?url={$url}&text={$title}";
$button = '
<div class="share-fediverse">
<a class="share-fediverse__link" href="' . esc_url( $share_url ) . '" target="_blank" rel="noopener noreferrer">
<svg aria-hidden="true" width="16" height="16" viewBox="0 0 18 18"
fill="none" xmlns="http://www.w3.org/2000/svg"
class="share-fediverse__icon">
<path fill-rule="evenodd" clip-rule="evenodd"
d="M9 1.5a7.5 7.5 0 1 0 0 15A7.5 7.5 0 0 0 9 1.5zm0
2a5.5 5.5 0 1 1 0 11A5.5 5.5 0 0 1 9 3.5zm0
2a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7zm3
3.5a3 3 0 0 1-3 3V9a0 0 0 0 0 0 0h3z"
fill="currentColor"/>
</svg>
Si vous appréciez, partagez sur le Fediverse ou Bluesky, Merci !
</a>
</div>';
return $content . $button;
}
add_filter( 'the_content', 'vincentbreton_share_fediverse' );
5. Gravatar / confirmer la balise
Si vous avez un compte Gravatar lié au site. Nota : je n’utilise pas Gravatar mais une image locale pour plus de légèreté. Mettez votre propre compte !
PHP
add_action('wp_head', function() {
echo '<link rel="me" href="https://gravatar.com/vincentbretoncfc9a0ed52" />';
});
6. Fichier JSON Person
Fiche d’identité lisible par les machines pour le Fédiverse (complète d’une certaine façon la hcard). Cela permet aux moteurs de recherche de comprendre que votre site appartient à une personne précise et de mieux présenter vos informations. Les réseaux sociaux décentralisés peuvent reconnaître votre site comme un compte que l’on peut suivre.
HTML
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Vincent Breton",
"url": "https://vincentbreton.fr/",
"image": "https://vincentbreton.fr/wp-content/uploads/2026/09/vincent-breton-auteur-poete.webp",
"jobTitle": "Auteur et poète",
"description": "Auteur du site vincentbreton.fr. Écrit un journal, de la poésie et de la fiction. Vit en Occitanie.",
"homeLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"addressRegion": "Occitanie",
"addressCountry": "FR"
}
},
"sameAs": [
"https://vincentbreton.fr/author/vbreton",
"https://piaille.fr/@VincentBreton",
"https://gravatar.com/vincentbretoncfc9a0ed52",
"https://codeberg.org/VincentBreton-auteur",
"https://github.com/vincentbreton-auteur"
]
}
</script>
7. Flux RSS complet
Pour les personnes qui voudraient lire l’article complet dans leur lecteur de flux RSS, je ne le propose pas par défaut pour inciter à se rendre plutôt sur le site.
PHP
// Si on est sur la page avec le slug "flux-rss-complet", générer le flux complet
add_action('template_redirect', function() {
if (is_page('flux-rss-complet')) {
// Définir l’en-tête RSS
header('Content-Type: application/rss+xml; charset=' . get_option('blog_charset'));
$charset = get_option('blog_charset');
$blog_name = get_bloginfo('name');
$blog_url = get_bloginfo('url');
$blog_description = get_bloginfo('description');
$blog_language = get_bloginfo('language');
// Commence le flux RSS
echo '<?xml version="1.0" encoding="' . $charset . '"?>';
echo '<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">';
echo '<channel>';
echo '<title>' . $blog_name . '</title>';
echo '<link>' . $blog_url . '</link>';
echo '<description>' . $blog_description . '</description>';
echo '<language>' . $blog_language . '</language>';
// Boucle des 10 derniers articles
$query = new WP_Query(array(
'post_type' => 'post',
'posts_per_page' => 10
));
while ($query->have_posts()) {
$query->the_post();
echo '<item>';
echo '<title>' . get_the_title_rss() . '</title>';
echo '<link>' . get_permalink() . '</link>';
echo '<pubDate>' . mysql2date('r', get_post_time('Y-m-d H:i:s', true)) . '</pubDate>';
echo '<guid>' . get_permalink() . '</guid>';
echo '<content:encoded><![CDATA[' . get_the_content_feed('rss2') . ']]></content:encoded>';
echo '</item>';
}
wp_reset_postdata();
echo '</channel>';
echo '</rss>';
exit; // stoppe WordPress pour ne pas afficher la page normale
}
});
8. Fil Mastodon
Comme je possède également un compte personnel Mastodon, une page diffuse le flux des messages que je publie sur ce compte. Je ne la mets plus en avant préférant promouvoir le compte du site sur le Fédiverse. On peut modifier le style, la couleur etc.
PHP
/**
* Fil Mastodon - Vincent Breton
* WPCode - Type: PHP
* Styles uniquement page ID 30129
*/
function vb_get_mastodon_posts( $limit = 10 ) {
$account_id = '110972899561318470';
$transient_key = 'mastodon_feed_vb';
$cached = get_transient( $transient_key );
if ( false !== $cached ) {
return $cached;
}
$url = 'https://piaille.fr/api/v1/accounts/' . $account_id . '/statuses?limit=' . intval( $limit ) . '&exclude_replies=true&exclude_reblogs=false';
$response = wp_remote_get( $url, array(
'timeout' => 15,
'sslverify' => true,
'headers' => array( 'Accept' => 'application/json' ),
) );
if ( is_wp_error( $response ) ) {
return false;
}
$posts = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! empty( $posts ) && is_array( $posts ) ) {
set_transient( $transient_key, $posts, 1800 );
}
return $posts;
}
function vb_mastodon_feed_shortcode( $atts ) {
$atts = shortcode_atts( array( 'limit' => 10 ), $atts, 'mastodon_feed' );
$posts = vb_get_mastodon_posts( intval( $atts['limit'] ) );
if ( empty( $posts ) || ! is_array( $posts ) ) {
return '<div class="mastodon-feed-error"><p>Impossible de charger le fil Mastodon pour le moment.</p></div>';
}
$html = '<div class="mastodon-feed">';
foreach ( $posts as $post ) {
$is_reblog = ! empty( $post['reblog'] );
$display = $is_reblog ? $post['reblog'] : $post;
$html .= '<article class="mastodon-post' . ( $is_reblog ? ' is-reblog' : '' ) . '">';
if ( $is_reblog ) {
$html .= '<div class="reblog-label">🔁 Reposté depuis ';
$html .= '<a href="' . esc_url( $post['reblog']['account']['url'] ) . '" target="_blank" rel="noopener noreferrer">';
$html .= esc_html( $post['reblog']['account']['display_name'] );
$html .= '</a></div>';
}
$date = new DateTime( $post['created_at'] );
$date->setTimezone( new DateTimeZone( wp_timezone_string() ) );
$html .= '<div class="post-header"><time datetime="' . esc_attr( $post['created_at'] ) . '">';
$html .= date_i18n( 'j F Y à G\hi', $date->getTimestamp() );
$html .= '</time></div>';
$html .= '<div class="post-content">' . wp_kses_post( $display['content'] ) . '</div>';
if ( ! empty( $display['media_attachments'] ) ) {
$html .= '<div class="post-media">';
foreach ( $display['media_attachments'] as $media ) {
if ( isset( $media['type'] ) && $media['type'] === 'image' ) {
$alt = isset( $media['description'] ) ? $media['description'] : '';
$html .= '<img src="' . esc_url( $media['url'] ) . '" alt="' . esc_attr( $alt ) . '" loading="lazy">';
}
}
$html .= '</div>';
}
$html .= '<div class="post-footer">';
$html .= '<a href="' . esc_url( $display['url'] ) . '" target="_blank" rel="noopener noreferrer">Voir sur Mastodon →</a>';
$html .= '</div>';
$html .= '</article>';
}
$html .= '</div>';
return $html;
}
add_shortcode( 'mastodon_feed', 'vb_mastodon_feed_shortcode' );
function vb_mastodon_feed_styles() {
if ( ! is_page( 30129 ) ) {
return;
}
echo '<style>
.mastodon-feed{display:grid;gap:2rem;max-width:800px;margin:0 auto}
.mastodon-post{background:#f8f9fa;border-left:4px solid #d63031;padding:1.5rem;border-radius:8px;box-shadow:0 2px 4px rgba(0,0,0,.05)}
.post-header time{color:#111;font-size:.9rem;font-weight:500}
.post-content{margin:1rem 0;line-height:1.6}
.post-content p{margin-bottom:.8rem}
.post-content p:last-child{margin-bottom:0}
.post-content a{color:#6364ff;text-decoration:underline}
.post-media{margin:1rem 0;display:grid;gap:.5rem}
.post-media img{max-width:100%;height:auto;border-radius:4px;box-shadow:0 2px 8px rgba(0,0,0,.1)}
.post-footer{margin-top:1rem;padding-top:1rem;border-top:1px solid #dee2e6}
.post-footer a{color:#d63031;text-decoration:none;font-size:.9rem;font-weight:500}
.post-footer a:hover{text-decoration:underline}
.reblog-label{font-size:.85rem;color:#666;margin-bottom:.75rem}
.reblog-label a{color:#d63031;text-decoration:none;font-weight:500}
.is-reblog{border-left-color:#6364ff}
.mastodon-feed-error{padding:1rem;background:#fff3cd;border:1px solid #ffc107;border-radius:4px;color:#856404}
@media(max-width:768px){.mastodon-post{padding:1rem}}
</style>
';
}
add_action( 'wp_head', 'vb_mastodon_feed_styles' );Did you enjoy this article?
Recommend it — Standard Reader surfaces well-loved writing to more readers across the network.