Giantpaper.org

Tag: meta

Has nothing to do with the company owning Facebook. šŸ˜¤ These are posts related to Giantpaper.

  • Giantpaper on the Fediverse: Back and Better than Ever!

    Giantpaper on the Fediverse: Back and Better than Ever!

    Ever since the Great Federating of Giantpaper, I’ve been thinking about how I would get Activitypub to correctly display the different types of blog posts I have set up. Ex: this post, which looked like this on Mastodon:

    Or this one, which turned into this:

    There were some things I learned about WP posts ending up on the Fediverse through this plugin:

    • Custom fields (like those generated by Advanced Custom Fields) don’t get included, so links from my linklog posts won’t appear (which is why this post was posted as a micropost instead of a linkpost)
    • Most HTML gets stripped out by some Fedi services like Mastodon, which is why videos weren’t appearing on microposts

    The Activitypub plugin has a setting for tweaking the template that gets used for federation:

    …but there’s no template tag for custom fields (and no way to not have the plugin render video URLs as video embeds).

    Enter Filters

    I saw that there was a PR for making the post template filterable, that was upcoming for v2.0.0. And against my judgement, I jumped at it when it released, thinking there would be some sort of documentation for the new filters, but NOPE. I didn’t even know what the filter was called!! šŸ˜¬ I did see the addition of a new filter name in v2.0.0.0, which is what I thought it was going to be, but actually trying to use it to filter stuff got me the dreaded “Your author URL does not return valid JSON for application/activity+json. Please check if your hosting supports alternate Accept headers.” error in WordPress’s Site Health page. And also I (somehow) found that outputting the contents of $template from the first parameter that it was actually meant to alter the post template (from the screenshot above with the [ap_....] tags), but I’m trying to figure out how to modify the HTML output of [ap_content]. So that wasn’t it.

    I saw that the plugin repo has a discussion board! And that people actually use said discussion board! I searched “filters” and found “Modifying ActivityPub posts via WordPress filter? #228“. Trying to add a filter for activitypub_post got me an error. So that wasn’t it either.

    (FYI, the filter name wasn’t what I was looking for, but I did find a Very Important Piece of info in the linked thread that helped me debug my code later. More on that later.)

    AND THEN, the search bar at the top, I searched for apply_filters (because if there’s a new way to filter content, it for sure would be added to the code via apply_filters()):

    searching for apply_filters() on Github automattic/wordpress-activitypub

    And there it was: Line 623 in includes/transformer/class-post.php:

    Screenshot showing activitypub_the_content being applied

    After some trial and error, I fiiiiiiiinally got it to work. šŸ˜©

    screenshot showing Now or Never by Audiomachine on Mastodon

    Behind the Scenes!

    Here is my (very unofficial) documentation for this:

    /**
     *
     * @param string  $content The outputted HTML of [ap_content]
     * @param WP_Post $post    The post object -- see https://developer.wordpress.org/reference/classes/wp_post/ and https://developer.wordpress.org/reference/functions/get_post/ for more info
     *
     */
    add_filter('activitypub_the_content', function($content, $post){
    
      // add code here
    
      return $content
    
    }, 100, 2);

    First the videos…

    This is just some normal non-WP specific code. So if you’re already familiar with PHP, you might already know this. But to make sure your videos show up in your fediposts:

      // Remove iframes from Youtube videos
      $content = preg_replace(
        "#<figure[^>]+><div[^>]+><iframe.+ src=\"https://www\.youtube\.com/embed/(.+)\?[^\"]+\".+></iframe></div></figure>#",
        "<p><a href=\"https://youtube.com/watch?v=\\1\">https://youtube.com/watch?v=\\1</a></p>",
        $content
      );
      // Remove iframes from Vimeo videos
      $content = preg_replace(
        "#<figure[^>]+><div[^>]+><iframe.+ src=\"https://player\.vimeo.com/video/(.+)\?[^\"]+\".+></iframe></div></figure>#",
        "<p><a href=\"https://vimeo.com/\\1\">https://vimeo.com/\\1</a></p>",
        $content
      );

    You’re basically removing the iframes and surrounding <figure> and <div> tags from around the videos and reformatting the embed URLs (inside the src="" attribute) back to their web accessible URLs (so https://www.youtube.com/embed/t476sB13EOg ā†’ https://www.youtube.com/watch?v=t476sB13EOg). And then linking to themselves, which will make Mastodon (and maybe other fediservers) think “oh hey, this is a link, let’s put up a preview”, and embeds the video.

    So from this:

    <figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper"><iframe loading="lazy" title="The Prince of Peace" width="500" height="375" src="https://www.youtube.com/embed/AQZqaz10TOM?feature=oembed" frameborder="0" allow="web-share" allowfullscreen></iframe></div></figure>

    To this:

    <p><a href="https://youtube.com/watch?v=AQZqaz10TOM">https://youtube.com/watch?v=AQZqaz10TOM</a></p>

    And the links!

    This uses some more WP-specific PHP to detect what post you’re displaying, but here’s what I have:

    // Linklog -- prepend external link to post
    $href = get_field('external_url', $post->ID);
    if (has_category('linklog', $post)) {
      $content = '<p><a href="' .$href. '">' .$href. '</a></p>' . $content;
    }

    All together now:

    add_filter('activitypub_the_content', function($content, $post){
    	// Remove iframes from Youtube videos
    	$content = preg_replace(
    		"#<figure[^>]+><div[^>]+><iframe.+ src=\"https://www\.youtube\.com/embed/(.+)\?[^\"]+\".+></iframe></div></figure>#",
    		"<p><a href=\"https://youtube.com/watch?v=\\1\">https://youtube.com/watch?v=\\1</a></p>",
    		$content
    	);
    	// Remove iframes from Vimeo videos
    	$content = preg_replace(
    		"#<figure[^>]+><div[^>]+><iframe.+ src=\"https://player\.vimeo.com/video/(.+)\?[^\"]+\".+></iframe></div></figure>#",
    		"<p><a href=\"https://vimeo.com/\\1\">https://vimeo.com/\\1</a></p>",
    		$content
    	);
    
    	// Linklog -- prepend external link to post
    	$href = get_field('external_url', $post->ID);
    	if (has_category('linklog', $post)) {
    		$content = '<p><a href="' .$href. '">' .$href. '</a></p>' .$content;
    	}
    	return $content;
    }, 100, 2);

    Edit

    Updated code to handle syntax highlighting better (it looks REEEALLY bad on Mastodon).

    Edit #2

    Mastodon does not apply monospace fonts to <pre>. TIL

    Edit #3

    Fixed syntax error in the last code snippet. Getting PHP and Javascript mixed up.

  • Giantpaper.org…Federated!!

    Giantpaper.org…Federated!!

    I’ve finally done it. šŸ˜¬ Ever since I heard that it was possible to federate WordPress blogs, I’ve been interested in having GPORG join the fediverse. For me, it wasn’t just plug ‘n play, because of my setup (Litespeed Web Server, with a cache plugin + Cloudflare). WordPress’s site health thing kept saying:

    Your author URL does not return valid JSON for application/activity+json. Please check if your hosting supports alternate Accept headers.

    Apparently, you can test whether or not these accept headers are working by entering in the command line:

    curl -I https://test.giantpaper.org/author/giantpaper/ -H "Accept: application/activity+json"

    With the https://test.giantpaper.org/author/giantpaper/ being the URL to your author page. It’s supposed to bring up a normal HTML page just as you designed it when viewed in the browser, but when entered in the command line with the accept header, it’s supposed to return JSON. For me, it was returning as text/html, which is what the problem was.

    Here’s what I did. Hopefully it’ll help someone else.

    Caches

    Every tutorial or fix I saw online was either for Apache or nginx, but I’m using Litespeed. Supposedly, caches aren’t supposed to butt heads with the Activitypub plugin, but there were some exceptions (some people found it started working after they disabled plugins like Jetpack). I figured out I could bypass the cache by adding https://test.giantpaper.org/author/giantpaper/ to the exclude list. Only problem is that the cache would also be bypassed if the page were accessed in browser which I didn’t want.

    There seems to be only other article I saw online about Litespeed + WP Activitypub issues. Fixing OpenLiteSpeed Caching for ActivityPub on WordPress [Archived] (you basically need to add a rewrite rule to your .htaccess file). I THINK this helped.

    index.php

    I’m using my own version of Sage and found that the accept header thing works if I had the default Twentytwentyfour theme activated. I found that the correct JSON code was returning with my own custom theme, but it had the surrounding <html> and <body> tags, as well as everything in the <head> tag everything outside the #app container, which what I have in my index.php file for the theme. I think it had something to do with all of this code being in the index.php file (normally this would be in the header.php and footer.php files). Wasn’t sure how to not make it do that other than:

    <?php
    if($_SERVER['HTTP_ACCEPT'] == 'application/activity+json' || preg_match("#^/(.+)/activitypub/?$#", $_SERVER['REQUEST_URI'])) {
    	header("Content-Type: application/activity+json; charset=UTF-8;");
    	echo view(app('sage.view'), app('sage.data'))->render();
    	die();
    }
    ?>

    (The $_SERVER['HTTP_ACCEPT'] == 'application/activity+json' tells the server to only bring up this code if the content-type is set to application/activity+json. Since the content-type of WordPress posts & pages are almost always text/html when viewed in a browser, you won’t be smacked with a big wall of weird-looking code when trying look at your own author page.)

    I put this at the very top of my index.php file. If you do:

    curl https://test.giantpaper.org/author/giantpaper/ -H "Accept: application/activity+json"

    You should see a big wall of confusing looking code (compressed JSON). This is what you want.

    Cloudflare (optional?)

    I’m not sure if this was necessary, because supposedly the rewrite rule from the Caches section would’ve taken care of this, but I did the previous two items and it still wasn’t working. So in Cloudflare, under Caching > Cache Rules, I added a new rule:

    • URI Path: Not sure if it really needed to be URI Path or if URI or URI Full would’ve sufficed. Obviously if you use URI Full, you need to include the domain name + protocol (https://…).
    • Request Headers: In the blank field after Request Headers, put content-type. Field #3, put as equals. Field #4 as application/activity+json

    Browser Cache TTL

    I found I had to leave the Browser TTL as 4 hours (which I think is the default):

    Disclaimer

    Earlier, whenever I clear the site cache, I notice I would get the same message in Site Health:

    Your author URL does not return valid JSON for application/activity+json. Please check if your hosting supports alternate Accept headers.

    And doing:

    curl https://test.giantpaper.org/author/giantpaper/ -H "Accept: application/activity+json"

    Followed by:

    curl -I https://test.giantpaper.org/author/giantpaper/ -H "Accept: application/activity+json"

    In this exact order fixes it. Why? I don’t know.

    Sidenote: I updated something on the site and cleared the cache. I don’t get this message anymore. Why? I don’t know.

    Sometimes you might notice that the error message won’t go away after doing any of the above. I THINK the Site Health checker just needs time to check again (a half an hour? An hour?). I’m not sure if it’s a cache problem.

    What it doesn’t do

    • If you have custom fields on your theme, you won’t be able to include them in fedi posts. Hopefully that will change in the future, because my linklog posts make so sense without the external URL.
    • This is completely separate from Lemmy or Mastodon, and there’s no way to connect your existing accounts with your newly federated WordPress site. It creates a completely separate profile on all supported fedinetworks.
    • Looks like it doesn’t support kbin yet. Kbin is still new and doesn’t have an API released at the moment (this is being worked on), so…yeah.
    • Any new posts you create will federate, but it won’t pull over pre-federation posts. It’s most like email than say RSS.

    Conclusion

    Aaaaaand I think that’s it. I think it still might be indexing everywhere, but you can search for [email protected] in your fedi instance (it’s definitely on mastodon.social*). Comments on GPORG are disabled, so I dunno what will happen if someone responds on Mastodon, but it won’t show up here (since comments aren’t even supported on this theme).

    *If you’re not signed into mastodon.social, it’ll just redirect to the author page on giantpaper.org.

  • Experimenting with federation

    Experimenting with federation

    beakers and a flask on a table

    If you’re seeing this on the Fediverse, hiiiii. šŸ‘‹

    (FYI, that meta tag? It’s about GPORG, NOT Facebook’s parent company. Not everything is about Zuck. šŸ˜¤)

  • GPORG Version Whatever.1

    GPORG Version Whatever.1

    Just like with a lot of video games these days, there’s the initial release that everyone’s hyped about. Then as you’re playing it, you discover some glaringly obvious, annoying bugs that should’ve been fixed during playtesting. This was the case!

    Fixed:

    • MOBILEā€”Not being able scroll all the way down on the main menu.
    • MOBILEā€”Tweaked the main menu so the close animation is smoother.

    I’ve made some improvements!

    • I’ve semi-decorated the front page with Christmas (changed the hero image) so I decided to go all the way and change the colors to be more holidayish.
    • I’ve added shortlinks!
      screenshot showing off GPORG's new shortlinks
      WordPress already has support for shortlinks, but they’re just the default /?p=[post ID] which is the permalink structure of posts & pages if pretty permalinks are disabled. Shortlinks are available on all posts except the linklog, since the “permalink” is kind of supposed to be the external URL anyway (and there’s no way to shorten that with the plugin).