Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Largo-specific photo credit metadata is not output in image block #1683

Closed
2 tasks
benlk opened this issue Apr 23, 2019 · 17 comments
Closed
2 tasks

Largo-specific photo credit metadata is not output in image block #1683

benlk opened this issue Apr 23, 2019 · 17 comments
Assignees
Labels
category: gutenberg Relating to general Gutenberg compatibility category: images Issues relating to images Estimate: < 4 Hours priority: high Either blocks work on a priority-normal task or a solution here informs other work. status: needs research We need to look into this to see what's needed type: question
Milestone

Comments

@benlk
Copy link
Collaborator

benlk commented Apr 23, 2019

The media credit metadata added by the Navis Media Credit plugin (included in Largo) in https://github.com/INN/largo/blob/v0.6.1/lib/navis-media-credit/navis-media-credit.php isn't output on Gutenberg image blocks.

  • can Image Block output be modified?
  • if it can, add the media credit output.
@benlk benlk added type: question priority: normal Must be completed before release of this version of plugin. category: gutenberg Relating to general Gutenberg compatibility labels Apr 23, 2019
@benlk benlk modified the milestones: 0.6.2, 0.6.3 Apr 23, 2019
@benlk
Copy link
Collaborator Author

benlk commented Apr 23, 2019

This might be possible, via the server-side function https://developer.wordpress.org/reference/functions/render_block/ which would allow modifying the wp:image block markup before it's output by do_blocks( $the_content ).

Here's what an image block's markup looks like:

<!-- wp:image {"id":98709,"align":"center"} -->
<div class="wp-block-image">
    <figure class="aligncenter">
        <img src="https://example.test/wp-content/uploads/2018/01/TEDx3.png" alt="" class="wp-image-98709"/>
    </figure>
</div>
<!-- /wp:image -->

And here's what the output of the_content() looks like:

<div class="wp-block-image">
    <figure class="aligncenter">
         <img src="https://example.test/wp-content/uploads/2018/01/TEDx3.png" alt="" class="wp-image-98709" srcset="https://example.test/wp-content/uploads/2018/01/TEDx3.png 731w, https://example.test/wp-content/uploads/2018/01/TEDx3-210x140.png 210w, https://example.test/wp-content/uploads/2018/01/TEDx3-336x224.png 336w" sizes="(max-width: 731px) 100vw, 731px">
    </figure>
</div>

Note the addition of srcset and sizes.

@benlk
Copy link
Collaborator Author

benlk commented Apr 25, 2019

Can we look at the list of do_block handlers and to see if there's a PHP handler there that would let us more-easily write the image credits into the markup, rather than using regular expressions to parse HTML?

@benlk benlk added priority: high Either blocks work on a priority-normal task or a solution here informs other work. and removed priority: normal Must be completed before release of this version of plugin. labels Apr 26, 2019
@joshdarby joshdarby self-assigned this May 14, 2019
@joshdarby
Copy link
Collaborator

@benlk So far it looks like we only have two options here other than regex.

  1. Use DOMDocument to parse html elements and insert the metadata after each image. Something like this
function add_media_credit_to_content_images( $content ){

	$content = mb_convert_encoding( $content, 'HTML-ENTITIES', "UTF-8" );
	$document = new DOMDocument();
	$document->loadHTML( utf8_decode( $content ) );

	$imgs = $document->getElementsByTagName( 'img' );

	foreach ($imgs as $img) {

		$attachment_id = attachment_url_to_postid( $img->getAttribute( 'src' ) );
		$attachment_credit = get_post_meta( $attachment_id, '_media_credit', true );

		$img_credit_element = $document->createElement( 'figcaption', $attachment_credit );
		$img->parentNode->appendChild($img_credit_element);

	}

	$html = $document->saveHTML();
	return $html;

}

add_filter( 'the_content', 'add_media_credit_to_content_images' );
  1. Use the render_block filter to find any core image block, get their content, and do an ugly str_replacce to remove the ending </figure> tag, insert the caption, then insert a new ending </figure> tag, like this:
function add_media_credit_to_content_images( $block_content, $block){
	
	if ( 'core/image' === $block['blockName'] ) {

		if( !empty ( $block['attrs']['id'] ) ){

			$attachment_id = $block['attrs']['id'];
			$attachment_credit = get_post_meta( $attachment_id, '_media_credit', true );

			$block_content = str_replace( '</figure>', '', $block_content ) . "<figcaption>" . $attachment_credit . "</figcaption></figure>";

		}
	}
	
	return $block_content;
	
}

add_filter( 'render_block', 'add_media_credit_to_content_images', 10, 2 );

@joshdarby
Copy link
Collaborator

Another option would be to use the block filters API and actually add the credit into the editor when the image is selected.

@benlk
Copy link
Collaborator Author

benlk commented May 16, 2019

That does sound better; it would avoid confusion between the editor depiction of the content and the frontend depiction.

@MirandaEcho MirandaEcho added Category: Gutenberg Compatibility category: images Issues relating to images Estimate Needed and removed category: gutenberg Relating to general Gutenberg compatibility labels May 21, 2019
@benlk benlk added category: gutenberg Relating to general Gutenberg compatibility and removed Category: Gutenberg Compatibility labels May 22, 2019
@benlk
Copy link
Collaborator Author

benlk commented Jun 6, 2019

  • try out the block filters API
    • where is JS loading the metadata from?
  • generate an estimate for this issue
  • implement in all relevant image blocks

@benlk benlk added status: needs research We need to look into this to see what's needed and removed status: needs research We need to look into this to see what's needed labels Jun 6, 2019
@joshdarby
Copy link
Collaborator

joshdarby commented Jun 18, 2019

An update for this issue:

It's pretty easy to replace the caption in the Gutenberg image block in the editor. All you need to do is enqueue a JS file for Gutenberg edits, load the correct elements, and do props.attributes.caption = "My caption".

The hard part is grabbing metadata, which is where the media credit is stored. It doesn't look like you can choose what data to load for a block. Here's what you get back from props.attributes for an image:

attributes:
alt: ""
caption: ""
id: 366
link: "https://largo.dev/uncategorized/hello/attachment/screen-shot-2019-04-22-at-12-25-26-pm"
linkDestination: "none"
url: "https://largo.dev/wp-content/uploads/2019/04/Screen-Shot-2019-04-22-at-12.25.26-PM.png"

I suppose we could do a query to the WP API to grab the media credit?

@benlk
Copy link
Collaborator Author

benlk commented Jun 19, 2019

If querying the API works, let's do that.

@joshdarby
Copy link
Collaborator

joshdarby commented Jun 19, 2019

Querying the API works pretty well using something like this after registering the _media_credit meta field as a field for the API:

var attachment = new wp.api.models.Media( { id: attachment_id } );
var attachment_response = post.fetch().then( function( attachment ){
   var media_credit = attachment.media_credit;
}

The last thing I need to figure out is what filter to fire it on. Currently I have it set to editor.BlockEdit but that fires on every instance of the block being edited, such as hovered over, moved, updated, removed, etc. which we don't want.

@joshdarby
Copy link
Collaborator

joshdarby commented Jun 19, 2019

Also, looks like there's no default way of achieving this sort of thing just yet: WordPress/gutenberg#8472

@benlk
Copy link
Collaborator Author

benlk commented Jun 19, 2019

Maybe on blocks.getSaveElement?

@joshdarby
Copy link
Collaborator

Maybe on blocks.getSaveElement?

@benlk Probably something like that. blocks.getSaveContent.extraProps seems to be working.

@joshdarby
Copy link
Collaborator

joshdarby commented Jun 20, 2019

To-do still:

  • Figure out how to display inserted caption in block before reloading page after saving. Maybe blocks.getSaveContent isn't the correct filter to use?
  • Add in media credit url also.

@joshdarby
Copy link
Collaborator

Figure out how to display inserted caption in block before reloading page after saving. Maybe blocks.getSaveContent isn't the correct filter to use?

Turns out you don't need to reload the page after saving, you just need to hang tight for a second.

@benlk
Copy link
Collaborator Author

benlk commented Jul 16, 2019

We should open a companion issue here for the Gallery Block, and whatever other image blocks Core provides that we'd want to use image credits for.

We will also need to update the helpdesk docs for the changes introduced in #1733.

@joshdarby
Copy link
Collaborator

@benlk Should that be one issue or two separate (one for gallery, one for everything else)?

@benlk
Copy link
Collaborator Author

benlk commented Jul 16, 2019

I think one for Gallery, one for Cover, one for Media and Text. Kinda taking the same approach as #1701

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: gutenberg Relating to general Gutenberg compatibility category: images Issues relating to images Estimate: < 4 Hours priority: high Either blocks work on a priority-normal task or a solution here informs other work. status: needs research We need to look into this to see what's needed type: question
Projects
None yet
Development

No branches or pull requests

3 participants