Created
June 12, 2022 15:56
-
-
Save snarfed/e068890d95b0c1057fa93fd2edb9f2b2 to your computer and use it in GitHub Desktop.
snarfed.org custom theme functions.php, based on Ryu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Customizations for snarfed.org on top of the Ryu WordPress theme. | |
* Not (yet) a full child theme. | |
* Public domain. | |
* | |
* To log: dlog("xyz") | |
* Defined below. Wraps error_log(). Writes to wp-content/debug.log | |
* | |
* Requires WP_DEBUG and WP_DEBUG_LOG to be true in wp-config.php. Details: | |
* http://www.stumiller.me/sending-output-to-the-wordpress-debug-log/ | |
* http://codex.wordpress.org/Debugging_in_WordPress | |
* | |
* to fix semantic-linkbacks breakage until WP 4.2, do this: | |
* update wp_comments set comment_type=NULL where comment_id=2586829; | |
*/ | |
/* uncomment to turn on WP Super Cache debug log file in | |
* wp-content/cache/supercache. */ | |
/* global $wp_super_cache_debug; */ | |
/* $wp_super_cache_debug = true; */ | |
/* Max media upload size. */ | |
@ini_set('upload_max_size', '128M'); | |
@ini_set('post_max_size', '128M'); | |
function dlog($msg) { | |
if ( is_array( $msg ) || is_object( $msg ) ) { | |
error_log( print_r( $msg, true ) ); | |
} else { | |
error_log( $msg ); | |
} | |
} | |
/* Require WordPress.com login, which includes 2FA. */ | |
add_filter( 'jetpack_remove_login_form', '__return_true' ); | |
/* Change email address that WordPress emails me *from*. It defaults to | |
* wordpress@snarfed.org, but when Google sees emails from a domain without | |
* DKIM, SPF, etc set up, it eventually distrusts that domain and starts showing | |
* "Suspicious link - This link leads to an untrusted site" whenever anyone | |
* clicks on any link to that domain, which is obviously bad. | |
* | |
* https://gsuiteupdates.googleblog.com/2017/05/making-email-safer-with-Gmail-click-time-security-checks.html | |
* https://productforums.google.com/forum/#!topic/gmail/qg7rTa5B7ZA | |
* https://productforums.google.com/forum/#!topic/gmail/dK0da2oRnrE | |
*/ | |
function snarfed_sender_email( $original_email_address ) { | |
return 'wordpress@ryanbarrett.org'; | |
} | |
add_filter( 'wp_mail_from', 'snarfed_sender_email' ); | |
/* The Syndication Links plugin's stylesheet includes genericons etc, which I | |
* already have, and I style the links myself, so ditch its style. | |
*/ | |
remove_action('wp_enqueue_scripts', array('Syn_Config', 'enqueue_scripts')); | |
/* Disable XML-RPC. */ | |
add_filter( 'xmlrpc_enabled', '__return_false' ); | |
remove_action( 'wp_head', 'rsd_link' ); | |
/* Jetpack Markdown: Enable by default for posts and pages. | |
* https://jetpack.com/support/markdown/#using-the-markdown-block | |
* https://jetpack.com/support/markdown/#cpt | |
*/ | |
function snarfed_markdown_everywhere() { | |
add_post_type_support( 'post', 'wpcom-markdown' ); | |
add_post_type_support( 'page', 'wpcom-markdown' ); | |
} | |
add_action('init', 'snarfed_markdown_everywhere'); | |
/* Jetpack Markdown: Don't make newlines meaningful. */ | |
function wpautop_no_linebreaks( $content ) { | |
$content = wpautop( $content, false ); | |
// maybe try to deal with trailing spaced newlines? | |
return $content; | |
} | |
remove_filter( 'the_content', 'wpautop' ); | |
add_filter( 'the_content', 'wpautop_no_linebreaks' ); | |
/* Filter for normal comments. Just remove the dash before "via ..." | |
*/ | |
function snarfed_cite($text) { | |
return str_replace("<p><small>— <cite>", "<cite>", | |
str_replace("</cite></small></p>", "</cite>", $text)); | |
} | |
add_filter('semantic_linkbacks_cite', 'snarfed_cite'); | |
/* Allow categories and tags on pages as well as posts. | |
*/ | |
function snarfed_tags_categories_on_pages() { | |
register_taxonomy_for_object_type( 'category', 'page' ); | |
register_taxonomy_for_object_type( 'post_tag', 'page' ); | |
} | |
add_action( 'init', 'snarfed_tags_categories_on_pages' ); | |
/* Clear a post/page's cache when it receives a webmention. | |
*/ | |
function snarfed_webmention_clear_cache($comment_ID) { | |
clean_post_cache(get_comment($comment_ID)->comment_post_ID); | |
// wp_cache_post_change stores the last seen post ID in a static local var, | |
// and short circuits if it's the same as last call. so set it to a different | |
// id first. (417 is /2003-06-29_blogtastic on both snarfed and localhost.) | |
$GLOBALS["super_cache_enabled"] = 1; | |
wp_cache_post_change(417); | |
wp_cache_post_change(get_comment($comment_ID)->comment_post_ID); | |
} | |
add_action('webmention_post', 'snarfed_webmention_clear_cache'); | |
/* Don't let webmentions get marked as spam. | |
*/ | |
function unspam_webmentions($approved, $commentdata) { | |
return ($commentdata['comment_type'] == 'webmention' || | |
get_comment_meta($commentdata['comment_ID'], 'semantic_linkbacks_type', true) | |
) ? 1 : $approved; | |
} | |
add_filter('pre_comment_approved', 'unspam_webmentions', '99', 2); | |
/* | |
* Don't show the "Send me a WebMention" form below the comment form. | |
*/ | |
// function snarfed_nothing($template_file) { | |
// return NULL; | |
// } | |
// add_filter('webmention_comment_form', 'snarfed_nothing'); | |
/* Automatically mark comments that end in a 32-digit hex string as spam. | |
* | |
* https://snarfed.org/wordpress-mini-spam-filter-for-comments-ending-in-32-hex-characters | |
*/ | |
function spam_32_hex_chars($approved, $commentdata) { | |
$text = trim(wp_strip_all_tags($commentdata['comment_content'], true)); | |
return preg_match('|[0-9a-f]{32}$|', $text) ? 'spam' : $approved; | |
} | |
add_filter('pre_comment_approved', 'spam_32_hex_chars', '99', 2); | |
/* Capture the output from a PHP file in a string. Taken verbatim from the PHP | |
* docs for include(). Used in header.php. | |
* | |
* If needed, we can use this to capture and process *all* output: | |
* http://www.dagondesign.com/articles/wordpress-hook-for-entire-page-using-output-buffering/ | |
*/ | |
function get_include_contents($filename) { | |
ob_start(); | |
include $filename; | |
$contents = ob_get_contents(); | |
ob_end_clean(); | |
return $contents; | |
} | |
/* Make Jetpack's Publicize opt in per post, instead of automatic and opt out. | |
*/ | |
add_filter('publicize_checkbox_default', '__return_false'); | |
/* Make Jetpack's Photon image CDN (used in its Tiled Galleries feature) handle | |
* connecting to us over SSL. Details: | |
* https://wordpress.org/support/topic/tiled-gallery-fetching-full-size-images-resizing-in-browser?replies=3#post-7214361 | |
* | |
* Theoretically no longer needed; Photon now supports HTTPS by default: | |
* http://jetpack.me/2016/01/20/39-sitemaps-skype-sharing/ | |
* | |
* ...but it broke on https://snarfed.org/2016-02-25_17194 when i tried removing it. | |
*/ | |
add_filter( 'jetpack_photon_reject_https', '__return_false' ); | |
/* Don't render featured images. I only use them for Twitter cards and Open | |
* Graph (Facebook) tags. | |
*/ | |
function snarfed_hide_featured_image ($html) { | |
return ''; //preg_replace('/(width|height)="\d+"\s/', "", $html); | |
} | |
add_filter( 'post_thumbnail_html', 'snarfed_hide_featured_image' ); | |
function snarfed_social_image_default ($url) { | |
if ( is_singular() ) { | |
global $post; | |
$matches = []; | |
if ( preg_match( "/< *img *[^>]+src *= *[\"']([^\"']+)/", | |
$post->post_content, $matches ) ) { | |
$url = $matches[1]; | |
if ( substr( $url, 0, 4 ) == 'http' ) { | |
return $url; | |
} else if ( substr( $url, 0, 2 ) == '//' ) { | |
return 'https:' . $url; | |
} else { | |
return get_home_url( NULL, $url ); | |
} | |
} | |
} | |
// default | |
return get_home_url( NULL, '/iraq_square.jpg' ); | |
} | |
add_filter( 'jetpack_open_graph_image_default', 'snarfed_social_image_default' ); | |
add_filter( 'jetpack_twitter_cards_image_default', 'snarfed_social_image_default' ); | |
/* Don't put u-photo on Jetpack lazy loaded image placeholders. | |
* https://jetpack.com/support/lazy-images/ | |
* https://developer.jetpack.com/hooks/jetpack_lazy_images_new_attributes/ | |
*/ | |
function snarfed_no_uphoto_lazy_images($attrs) { | |
$classes = explode(' ', $attrs['class']); | |
$attrs['class'] = implode(' ', array_filter($classes, function($cls) { | |
return $cls != 'photo' && $cls != 'u-photo'; | |
})); | |
// dlog($attrs); | |
return $attrs; | |
} | |
add_filter( 'jetpack_lazy_images_new_attributes', 'snarfed_no_uphoto_lazy_images' ); | |
/* WordPress 4.5 dropped the JPG quality of thumbnails to 82%, which makes them | |
* look blurry. Bump that back up. | |
* https://make.wordpress.org/core/2016/02/22/proposal-increase-the-default-image-compression-in-wordpress/ | |
*/ | |
function snarfed_better_quality_thumbnails($arg) { | |
return 90; | |
} | |
add_filter('jpeg_quality', 'snarfed_better_quality_thumbnails'); | |
/* Redirect image attachment pages to parent post. | |
* https://www.wpexplorer.com/disable-image-page/ | |
*/ | |
function snarfed_redirect_attachment_page() { | |
if ( is_attachment() ) { | |
global $post; | |
if ( $post && $post->post_parent ) { | |
wp_redirect( esc_url( get_permalink( $post->post_parent ) ), 301 ); | |
exit; | |
} else { | |
wp_redirect( esc_url( home_url( '/' ) ), 301 ); | |
exit; | |
} | |
} | |
} | |
add_action( 'template_redirect', 'snarfed_redirect_attachment_page' ); | |
/* Override and disable previous and next post links entirely. */ | |
function ryu_content_nav($nav_id) { | |
} | |
/** | |
* Override entry meta to add last modified time and microformats2 classes. | |
* | |
* Ryu doesn't have any filters or hooks for customizing this, so I had to copy | |
* and modify ryu_[get_]entry_meta() from ryu/inc/template-tags.php. :/ | |
*/ | |
function ryu_entry_meta() { | |
echo ryu_get_entry_meta(); | |
} | |
function ryu_get_entry_meta() { | |
$val = sprintf(__( | |
'<span class="entry-date">' . | |
'<a class="u-url" href="%1$s" title="%2$s" rel="bookmark">' . | |
'<time class="dt-published" datetime="%3$s">%4$s</time></a>' . | |
'%5$s</span>', 'ryu'), | |
esc_url(get_permalink()), | |
esc_attr(get_the_time()), | |
/* 'c' is the ISO 8601 format specifier, but it ignores WordPress's | |
* time zone and blindly uses GMT. DATE_W3C gets the time zone right. | |
* http://freetheweb.tumblr.com/post/11431306520/wordpress-obtaining-timezone-accurate-iso-8601-strings | |
*/ | |
esc_attr(get_the_date(DATE_W3C)), | |
esc_html(get_the_date()), | |
function_exists('get_syndication_links') ? get_syndication_links( null ) : ''); | |
if ('page' == get_post_type() && get_the_date() != get_the_modified_date()) { | |
$val = $val . sprintf(__( | |
'<span class="entry-modified-date">updated ' . | |
'<a class="u-url" href="%1$s" title="%2$s" rel="bookmark">' . | |
'<time class="dt-updated" datetime="%3$s">%4$s' . | |
'</time></a></span>', 'ryu'), | |
esc_url(get_permalink()), | |
esc_attr(get_the_modified_time()), | |
esc_attr(get_the_modified_date(DATE_W3C)), | |
esc_html(get_the_modified_date())); | |
} | |
$val = $val . sprintf(__( | |
'<span class="author p-author h-card vcard"> %1$s' . | |
'<a class="u-url url fn n p-name" href="%2$s" title="%3$s" rel="author">' . | |
'%4$s</a></span>', 'ryu'), | |
get_avatar(get_the_author_meta("ID"), 96, '', '', array( 'class' => 'u-photo' )), | |
esc_url(get_the_author_meta('user_url')), | |
esc_attr(get_the_author()), | |
get_the_author()); | |
return $val; | |
} | |
/** | |
* Suppress title (p-name) in replies etc so post type discovery thinks they're notes. | |
*/ | |
function snarfed_no_title_in_notes($title) { | |
if (is_singular() && !is_admin() && | |
(has_category('reply') || | |
has_category('like') || | |
has_category('repost') || | |
has_category('rsvp'))) { | |
return NULL; | |
} | |
return $title; | |
} | |
add_filter('the_title', 'snarfed_no_title_in_notes'); | |
/** | |
* Override comment to tweak author and date. | |
* | |
* ...just like entry meta, above. Ryu doesn't have any filters or hooks for | |
* customizing this, so I had to copy and modify ryu_comment() from | |
* ryu/inc/template-tags.php. :/ | |
*/ | |
function ryu_comment( $comment, $args, $depth ) { | |
$GLOBALS['comment'] = $comment; | |
switch ( $comment->comment_type ) : | |
case 'pingback' : | |
case 'trackback' : | |
?> | |
<li class="post pingback"> | |
<p><?php _e( 'Pingback:', 'ryu' ); ?> <?php comment_author_link(); ?></p> | |
<?php | |
break; | |
default : | |
?> | |
<li <?php comment_class(); ?> id="li-comment-<?php comment_ID(); ?>"> | |
<article id="comment-<?php comment_ID(); ?>" class="comment"> | |
<div class="comment-meta commentmetadata comment-author"> | |
<span class="comment-author-avatar"><?php echo get_avatar( $comment, 48 ); ?></span> | |
<div class="vcard h-card p-author"> | |
<?php printf( '<cite class="fn theme-genericon">%s</cite>', get_comment_author_link() ); ?> | |
</div><!-- .comment-author .vcard --> | |
<div class="comment-date"> | |
<a href="<?php echo esc_url( get_comment_link( $comment->comment_ID ) ); ?>" | |
title="<?php echo get_comment_time(); ?>"> | |
<time class="dt-published" datetime="<?php comment_time( 'c' ); ?>"> | |
<?php echo get_comment_date(); ?> | |
</time> | |
</a> | |
</div><!-- .comment-date --> | |
</div><!-- .comment-meta .commentmetadata --> | |
<div class="comment-content"> | |
<?php comment_text(); ?> | |
</div> | |
</article><!-- #comment-## --> | |
<?php | |
break; | |
endswitch; | |
} | |
/** | |
* Remove some parts of wordpress-uf2 that I do myself above. | |
*/ | |
remove_filter( 'the_author', 'uf2_the_author', 99, 1 ); | |
/** | |
* Load enqueued scripts in the footer to speed up page load. | |
* Stolen from http://www.kevinleary.net/move-javascript-bottom-wordpress/ | |
* | |
* Disabled because this includes stylesheets, and if they're in the footer, the | |
* page initially loads with blank style (ie ugly) before the stylesheets load | |
* and kick in. | |
*/ | |
/* | |
function snarfed_footer_enqueue_scripts() { | |
remove_action('wp_head', 'wp_print_scripts'); | |
remove_action('wp_head', 'wp_print_head_scripts', 9); | |
remove_action('wp_head', 'wp_enqueue_scripts', 1); | |
add_action('wp_footer', 'wp_print_scripts', 5); | |
add_action('wp_footer', 'wp_enqueue_scripts', 1); | |
add_action('wp_footer', 'wp_print_head_scripts', 9); | |
} | |
add_action('after_setup_theme', 'snarfed_footer_enqueue_scripts'); | |
*/ | |
/** Include my JavaScript files. | |
*/ | |
function snarfed_scripts() { | |
wp_enqueue_script('snarfed-fragmention', | |
get_stylesheet_directory_uri() . '/fragmention.js', | |
false, '1.0', true); | |
} | |
add_action('wp_enqueue_scripts', 'snarfed_scripts'); | |
/** IndieWeb Press This tweaks. | |
*/ | |
function snarfed_press_this_tweak() { | |
?> | |
<script type='text/javascript'> | |
function press_this_tweak() { | |
/* map type to wordpress category id */ | |
var categories = { | |
'like': '27', | |
'reply': '23', | |
'repost': '28', | |
'rsvp': '29', | |
// I currently show checkins on the front page. | |
// 'checkin': 23 | |
}; | |
/* get 'type' query param. default to 'reply'. */ | |
var type = 'reply'; | |
var params = window.location.search.substr(1).split('&'); | |
for (var i = 0; i < params.length; i++) { | |
var parts = params[i].split('='); | |
if (parts[0] == 'type') { | |
type = parts[1]; | |
break; | |
} | |
} | |
var cats = document.getElementsByClassName('category'); | |
for (i = 0; i < cats.length; i++) { | |
if (cats[i].attributes['data-term-id'].value == categories[type]) { | |
cats[i].classList.add('selected'); | |
} else { | |
cats[i].classList.remove('selected'); | |
} | |
} | |
var content = document.getElementById('pressthis'); | |
content.onchange = content.oninput = content.onfocus = function(event) { | |
// Tag Gina in checkins by default. | |
if (type == 'checkin') { | |
content.value = content.value.replace( | |
'with <a class="h-card" href=""></a>', | |
'with <a class="h-card" href="https://www.facebook.com/gina.rossman.50">Gina Barrett</a>.'); | |
} | |
// Use Bridgy Fed for Mastodon etc domains. | |
for (const pattern of [ | |
'//counter.social/', | |
'//friends.nico/', | |
'//lgbt.io/', | |
'//mastodon.', | |
'//mstdn.', | |
'//octodon.', | |
'//pawoo.net/', | |
'//toot.cafe/', | |
]) { | |
console.log('examining ' + pattern); | |
if (content.value.indexOf(pattern) >= 0 && | |
content.value.indexOf('fed.brid.gy') == -1) { | |
var text = (type == 'like' || type == 'repost') ? 'via Bridgy Fed' : ''; | |
content.value += ' <cite class="via">[' + text + '](https://fed.brid.gy/)</cite>'; | |
break; | |
} | |
} | |
}; | |
content.onchange(); | |
// press-this.js's window.onload runs after onchange() above, and overwrites | |
// our changes, and i can't find any other event handler that will trigger | |
// after that automatically, so hack it with a timer. :/ | |
window.setTimeout(content.onchange, 1000); | |
} | |
window.addEventListener('load', press_this_tweak, false); | |
</script> | |
<?php | |
} | |
add_action('admin_print_scripts-press-this.php', 'snarfed_press_this_tweak', 11); | |
/* Allow comments on pages by default. WordPress 4.3 switched the default off: | |
* https://make.wordpress.org/core/2015/07/06/comments-are-now-turned-off-on-pages-by-default/ | |
*/ | |
function snarfed_comments_on_pages($status, $post_type, $comment_type) { | |
return 'open'; | |
} | |
add_filter('get_default_comment_status', 'snarfed_comments_on_pages', 10, 3); | |
/** Reply contexts via LinkPreview. | |
*/ | |
function snarfed_embed_reply_context_script() { | |
if (has_category('reply')) { | |
$content = 'replying to:'; | |
} else if (has_category('repost')) { | |
$content = ''; | |
} else { | |
return; | |
} | |
?> | |
<script type='text/javascript'> | |
function embed_reply_contexts() { | |
var classes = ['u-in-reply-to', 'u-repost-of', 'u-quotation-of']; | |
for (i in classes) { | |
var origs = document.getElementsByClassName(classes[i]); | |
for (j = 0; j < origs.length; j++) { | |
if (origs[j].href.indexOf("twitter.com/") >= 0 || | |
origs[j].href.indexOf("facebook.com/") >= 0 || | |
origs[j].href.indexOf("plus.google.com/") >= 0 || | |
origs[j].href.indexOf("instagram.com/") >= 0) { | |
continue; | |
} | |
origs[j].insertAdjacentHTML('afterend', ` | |
<div class="box" style="margin-top: 1em"> | |
<a id="lp-url" href=""> | |
<img id="lp-image" style="float: right" src=""> | |
<div class="is-clipped"> | |
<h3 id="lp-title"></h3> | |
<p><em id="lp-description"></em></p> | |
</div> | |
</a> | |
</div>`); | |
fetch('https://api.linkpreview.net', { | |
method: 'POST', | |
mode: 'cors', | |
body: JSON.stringify({ | |
key: '38cfb05179d598106ac12fe584811681', | |
q: origs[j].href, | |
}), | |
}) | |
.then(res => res.json()) | |
.then(response => { | |
document.getElementById('lp-title').innerHTML = response.title | |
document.getElementById('lp-description').innerHTML = response.description | |
document.getElementById('lp-image').src = response.image | |
document.getElementById('lp-url').href = response.url | |
}); | |
} | |
} | |
} | |
window.addEventListener('load', embed_reply_contexts, false); | |
</script> | |
<?php | |
} | |
add_action('wp_footer', 'snarfed_embed_reply_context_script'); | |
/* Used once on snarfed.org, 2017-11-20, to upgrade MySQL tables' charset and | |
* collation from utf8 to utf8mb4 to fix showing emoji beyond BMP in comments. | |
* From https://gist.github.com/FlorianBrinkmann/c3f57dd7c26328d7b4de04e696091eee | |
* Background in https://make.wordpress.org/core/2015/04/02/the-utf8mb4-upgrade/ | |
* and etc/wordpress_emoji_mysql_utf8mb4. | |
*/ | |
// function update_db_to_utf8mb4() { | |
// if (!isset($_GET['update-utf8bm4'])) { | |
// return; | |
// } | |
// require_once( ABSPATH . 'wp-admin/includes/upgrade.php'); | |
// /** WordPress Administration API */ | |
// require_once(ABSPATH . 'wp-admin/includes/admin.php'); | |
// /** WordPress Schema API */ | |
// require_once(ABSPATH . 'wp-admin/includes/schema.php'); | |
// $tables = $wpdb->tables('all'); | |
// if (!wp_should_upgrade_global_tables()) { | |
// $global_tables = $wpdb->tables('global'); | |
// $tables = array_diff_assoc($tables, $global_tables); | |
// } | |
// foreach ($tables as $table) { | |
// maybe_convert_table_to_utf8mb4($table); | |
// } | |
// } | |
// add_action('wp_loaded', 'update_db_to_utf8mb4'); | |
/* Return 404s appropriately. Don't redirect to a similar existing URL. | |
*/ | |
add_filter('redirect_canonical', 'snarfed_no_redirect_on_404'); | |
function snarfed_no_redirect_on_404($redirect_url) | |
{ | |
if (is_404()) { | |
return false; | |
} | |
return $redirect_url; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment