Would be nice if there was an easy way to sanitize arbitrary custom data (i.e. Structured data from ACF or elsewhere).
Can you provide an example?
For custom post templates, something along the lines of <?php echo $this->sanitize( get_field('notes') ); ?>
Or being able to sanitize an additional type of content. For example I use a custom gallery shortcode that utilizes ACF galleries. So it would be great to be able to sanitize that custom shortcode just like how the built-in gallery shortcode is sanitized.
@garrettjohnson as in, you want to include custom data in the AMP content?
@kkranzo for custom shortcodes, see this section: https://github.com/Automattic/amp-wp#handling-media
Ah, okay.
So in my functions.php file where I create the html output for my regular custom shortcode, I can just check for is_amp_endpoint() and then output amp specific html for that scenario, correct?
@kkranzo Yes:
add_shortcode( 'xyz-shortcode', 'xyz_render_shortcode' );
function xyz_render_shortcode( $atts ) {
if ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) {
return 'AMP rocks!';
} else {
return 'You should use AMP!';
}
}
When viewing the AMP version of a post, this will output AMP rocks!. Note that I have not tested this code.
@mjangda Yes, custom data in the content of the page, but not inside post_amp_content. Using the amp_post_template_file filter works, but the addition of being able to process data with the same sanitizers we're using for post content would be great.
Can I already run an sanitizer over custom content? Can't seem to find out how I can implement custom content in my custom template and sanitize it.
Please help.
Did you find a way to run the plugin's embed/sanitizers on an arbitrary string for use in a template? I don't understand why there isn't a simple helper/action/filter I could use to format my content correctly.
It's a bit clunky, but it is possible.
If you just want to run a sanitizer, you can use the new AMP_Content_Sanitizer::sanitize method added in 0.4. See the featured image handling for an example.
If you want to run Embeds + the_content + Sanitizers, you can use the AMP_Content class directly (like the amp-post-template class does. The only issue there is that running the_content again can result in extra cruft sneaking in.
The one other caveat is that you should do all of this in the amp_post_template_data filter; the resulting scripts/styles should be appended to amp_component_scripts and post_amp_styles and the content can be appended to a key of your choice and then echoed in the template:
// warning rough, untested php5.3+ ahead
// passes a meta value through the image sanitizer
add_filter( 'amp_post_template_data', function( $data, $post ) {
$secondary_image = get_post_meta( $post->ID, 'my_secondary_image', true );
if ( empty( $secondary_image ) ) {
$data['my_secondary_image'] = false;
return $data;
}
list( $sanitized_html, $featured_scripts, $featured_styles ) = AMP_Content_Sanitizer::sanitize(
$secondary_image,
array( 'AMP_Img_Sanitizer' => array() )
);
$data['my_secondary_image'] = $sanitized_html;
if ( $featured_scripts ) {
$data['amp_component_scripts'] = array_merge( $data['amp_component_scripts'], $featured_scripts );
}
if ( $featured_styles ) {
$data['post_amp_styles'] = array_merge( $data['post_amp_styles'], $featured_styles );
}
return $data;
}, 10, 2 );
Then, in your template:
$secondary_image = $this->get( 'my_secondary_image' );
if ( $secondary_image ) {
echo $secondary_image; // no esc/kses; amphtml
}
(I guess it'd be nice to pass a reference to the AMP_Post_Template object in the hook as well to expose some of the utility functions.)
Of course, all of this is open to feedback/suggestions around how we could make it easier to work with.
@mjangda thanks! I was poking around with that class but didn't realize I needed to use it within the filter. Trying to make a new instance for my custom content was returning some global content over and over. Will try this fix. Thanks again!
@mjangda Am I doing this right? I can't get the following example to work. Specifically I'd like to get oEmbeds, like Tweets in the example, working from the filter.
function add_custom( $data, $post ) {
$custom_content = 'Some custom text with a tweet\nhttps://twitter.com/ACLUofMichigan/status/793134790530576384'
$amp_content = new AMP_Content( $custom_content,
apply_filters( 'amp_content_embed_handlers', array(
'AMP_Twitter_Embed_Handler' => array(),
'AMP_YouTube_Embed_Handler' => array(),
'AMP_Instagram_Embed_Handler' => array(),
'AMP_Vine_Embed_Handler' => array(),
'AMP_Facebook_Embed_Handler' => array(),
'AMP_Gallery_Embed_Handler' => array(),
) ),
apply_filters( 'amp_content_sanitizers', array(
'AMP_Blacklist_Sanitizer' => array(),
'AMP_Img_Sanitizer' => array(),
'AMP_Video_Sanitizer' => array(),
'AMP_Audio_Sanitizer' => array(),
'AMP_Iframe_Sanitizer' => array(
'add_placeholder' => true,
),
) )
);
$data[ 'custom_content' ] = $amp_content->get_amp_content();
return $data;
}
add_filter( 'amp_post_template_data', 'add_custom', 10, 2 );
Looks like no content is getting passed through during the build_post_content function. What am I supposed to pass for the third argument to the apply_filters functions in that case since there's no real post object?
@mjangda would really appreciate an example like yours above that does the same with oEmbeds included. I tried simply altering the post content to what I wanted with Embeds before the plugin does the oEmbed clean up itself but this also breaks the amp-live-lists I'm trying to inject (my current goal).
Ok I got it to work finally by using the AMP_Post_Template class. Thankfully the content I wanted to add was essentially the concatenated content of a bunch of posts from a different post type. If you wanted to do this for an arbitrary string that wasn't in a post I'm still not sure how you'd handle it since I couldn't get the AMP_Content class to convert the embeds correctly (though it did seem to sanitize correctly more or less).
Essentially I created a AMP_Post_Template object for each of my posts-to-be-concatenated. I was then able to fetch out it's content and scripts via $amp_post->get( 'post_amp_content' ) and $amp_post->get( 'amp_component_scripts' ) respectively. After that I added the content and scripts to the $data object from the amp_post_template_data filter.
is there an easy way to load a template partial from the non-amp theme but pass it through the sanitizer? In my amp template I would just like to call something like $this->sanitize(get_template_part('partials/author-bio'))
The recommended way to serve AMP templates moving forward is to use the theme support introduced in 0.7 and the upcoming 1.0.
And when using AMP theme support, you do everything as you do normally when writing your theme.
@BenChirlin @garrettjohnson @mjangda @kkranzo @R3dRidl3 @westonruter @benjamingeorge
Thank You All. Your discussion helped me solve my problem.
All of you guys ROCK!!!!!!!
Cheers :) :+1:
Most helpful comment
is there an easy way to load a template partial from the non-amp theme but pass it through the sanitizer? In my amp template I would just like to call something like
$this->sanitize(get_template_part('partials/author-bio'))