Advanced Custom Fields + Emojis
The challenge: Figure out why Advanced Custom Fields in wordpress didn't save emojis.
The stakeholder: My fun SEO coworker who wants to shove emojis into ld+json for the chance at ranking higher in google search results.
This was a fun problem to work on. I've had an growing interest in SEO for a while now. While I prefer generating ld+json on the component level when I can, sometimes the SEO's want a lot more control. How much control they get is contingent on the tools we provide for them. I this case it was a simple textarea ACF field.
The problem?: ACF fields don't currently handle special characters very well -- that goes for things like ™ or 🤡.
The approach: My search led me to two paths. The first path was changing the formatting rules of the entire database. This is a site with a long history and hundreds of posts. Not gonna take that risk just to shove a fire extinguisher emoji into some ld+json. The other option is to take the data before it's saved, encode it into a format that will retain the emoji, then decode it once again when we need to get that data back (so the clown looks like a clown and not a bunch of garble).
The solution: In a nutshell, we need to accomplish 3 things:
1) Encode before ACF Saves
The stakeholder: My fun SEO coworker who wants to shove emojis into ld+json for the chance at ranking higher in google search results.
This was a fun problem to work on. I've had an growing interest in SEO for a while now. While I prefer generating ld+json on the component level when I can, sometimes the SEO's want a lot more control. How much control they get is contingent on the tools we provide for them. I this case it was a simple textarea ACF field.
The problem?: ACF fields don't currently handle special characters very well -- that goes for things like ™ or 🤡.
The approach: My search led me to two paths. The first path was changing the formatting rules of the entire database. This is a site with a long history and hundreds of posts. Not gonna take that risk just to shove a fire extinguisher emoji into some ld+json. The other option is to take the data before it's saved, encode it into a format that will retain the emoji, then decode it once again when we need to get that data back (so the clown looks like a clown and not a bunch of garble).
The solution: In a nutshell, we need to accomplish 3 things:
- Encode before ACF saves
- Decode before ACF fetches that data for viewing in the admin panel (so my SEO's don't have a heart attack)
- Decode before ACF fetches that data for the final output on the page
1) Encode before ACF Saves
add_action('acf/save_post', 'encode_emoji_schema');
function encode_emoji_schema( $post_id ) {
$schema_field = get_field_object('page_schema', $post_id)['key'];
// Check if a specific value was updated
if( isset($_POST['acf'][$schema_field] ) {
$_POST['acf'][$schema_field] = urlencode( $_POST['acf'][$schema_field] );
}
};
Breakdown:
- add_action(); // interrupt WP render to do a thing
- acf/save_post; // ACF specific hook, fires when saving ACF
- get_field_object(); // ACF function
- $_POST; superglobal PHP array of variables being POSTed
- urlencode(); // replaces all non-alphanumeric chars with encoded junk
2) Decode for the Admin Output
add_filter('acf/prepare_field/name=page_schema', 'admin_emoji_decode', 5);
function admin_emoji_decode( $field ) {
$field['value'] = stripslashes( urldecode( $field['value'] ) );
return $field;
}
Breakdown:
- add_filter(); // alter existing data
- acf/prepare_field/name=page_schema // Alter data prior to rendering within a form (cms)
- $field;
- stripslashes(); // remove quotes from
- urldecode(); // reverse encoding
3) Decode for the Page Output
add_filter('acf/load_value/name=page_schema', 'render_emoji_decode', 5);
function render_emoji_decode( $value ) {
$value = stripslashes( urldecode( $value ) );
return $value;
}
Breakdown:
- acf/load_value/name=page_schema // Alter data for rendering
- $value
Comments
Post a Comment