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

Update tag visitor registration with unique ID constants #1469

Open
wants to merge 8 commits into
base: trunk
Choose a base branch
from

Conversation

pbearne
Copy link
Contributor

@pbearne pbearne commented Aug 13, 2024

Replaced hardcoded ID strings with unique ID constants for tag visitors to ensure consistency and maintainability. Updated the OD_Tag_Visitor_Registry::register method to handle dependencies, adding them only if they are not already registered.

Summary

Fixes #1419

Relevant technical choices

Replaced hardcoded ID strings with unique ID constants for tag visitors to ensure consistency and maintainability. Updated the `OD_Tag_Visitor_Registry::register` method to handle dependencies, adding them only if they are not already registered.
@pbearne pbearne added the [Plugin] Optimization Detective Issues for the Optimization Detective plugin label Aug 13, 2024
@pbearne pbearne self-assigned this Aug 13, 2024
Copy link

github-actions bot commented Aug 13, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @[email protected].

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: [email protected].

Co-authored-by: pbearne <[email protected]>
Co-authored-by: westonruter <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link
Member

@westonruter westonruter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for getting this off the ground!

See my inline comments.

The ultimate goal would be to refactor this code:

function auto_sizes_register_tag_visitors( OD_Tag_Visitor_Registry $registry ): void {
$registry->register( 'auto-sizes', 'auto_sizes_visit_tag' );
}
// Important: The Image Prioritizer's IMG tag visitor is registered at priority 10, so priority 100 ensures that the loading attribute has been correctly set by the time the Auto Sizes visitor runs.
add_action( 'od_register_tag_visitors', 'auto_sizes_register_tag_visitors', 100 );

So we could eliminate the need for the 100 priority.

For example:

function auto_sizes_register_tag_visitors( OD_Tag_Visitor_Registry $registry ): void {
	$registry->register( 
		'auto-sizes', 
		'auto_sizes_visit_tag', 
		array( 'image-prioritizer-img' ) 
	);
}
add_action( 'od_register_tag_visitors', 'auto_sizes_register_tag_visitors' );

An option question is what to do if the image-prioritizer-img tag visitor dependency doesn't exist. Does the auto-sizes then never run? Or would it need to rather do something like this:

function auto_sizes_register_tag_visitors( OD_Tag_Visitor_Registry $registry ): void {
	$registry->register( 
		'auto-sizes', 
		'auto_sizes_visit_tag', 
		defined( 'Image_Prioritizer_Img_Tag_Visitor::ID' ) ? array( Image_Prioritizer_Img_Tag_Visitor::ID ) : array()
	);
}
add_action( 'od_register_tag_visitors', 'auto_sizes_register_tag_visitors' );

@@ -37,9 +37,20 @@ final class OD_Tag_Visitor_Registry implements Countable, IteratorAggregate {
*
* @param string $id Identifier for the tag visitor.
* @param callable $tag_visitor_callback Tag visitor callback.
* @param array<mixed> $dependencies array with ID as key and Callable as value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param array<mixed> $dependencies array with ID as key and Callable as value
* @param string[] $dependencies Tag visitors that must run before this tag visitor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel this should be any so we can have more than one dependency

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and that's still the case: string[] is an array of strings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the change.

Comment on lines 42 to 54
public function register( string $id, callable $tag_visitor_callback, array $dependencies = array() ): void
{
if (!empty($dependencies)) {
foreach ($dependencies as $dependency_id => $dependency_callback) {
if (!self::is_registered($dependency_id)) {
$this->visitors[$dependency_id] = $dependency_callback;
}
}
}
if (!self::is_registered($id)) {
$this->visitors[$id] = $tag_visitor_callback;
}
}
Copy link
Member

@westonruter westonruter Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking rather that this would work more like how WP_Scripts works, where you can register a script (or tag visitor) with a given handle (or ID) and supply dependencies which are a list of strings (i.e. handles/IDs). Then later when obtaining the list of tag visitors to apply, it would recursively look up the registered tag visitors to make sure that those which have no dependencies run first, followed by those which have dependencies.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see a way of changing this to just passing the className and the dependencies as a series of class names
and then getting the ID from the class

Or just building an array values and then load them in the first call to get_registered

Part of the problem is I am not sure what the code is doing

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tag visitor registry is a collection of callables which are invoked when iterating over the tags via HTML Tag Processor. A tag visitor may be an invokable class or it may be a closure or a function or any other callable. See the Enhanced Responsive Images for an example tag visitor which is a regular PHP function and not a class:

/**
* Visits responsive lazy-loaded IMG tags to ensure they include sizes=auto.
*
* @since 1.1.0
*
* @param OD_Tag_Visitor_Context $context Tag visitor context.
* @return false Whether the tag should be recorded in URL metrics.
*/
function auto_sizes_visit_tag( OD_Tag_Visitor_Context $context ): bool {
if ( 'IMG' !== $context->processor->get_tag() ) {
return false;
}
$sizes = $context->processor->get_attribute( 'sizes' );
if ( ! is_string( $sizes ) ) {
return false;
}
$sizes = preg_split( '/\s*,\s*/', $sizes );
if ( ! is_array( $sizes ) ) {
return false;
}
$is_lazy_loaded = ( 'lazy' === $context->processor->get_attribute( 'loading' ) );
$has_auto_sizes = in_array( 'auto', $sizes, true );
$changed = false;
if ( $is_lazy_loaded && ! $has_auto_sizes ) {
array_unshift( $sizes, 'auto' );
$changed = true;
} elseif ( ! $is_lazy_loaded && $has_auto_sizes ) {
$sizes = array_diff( $sizes, array( 'auto' ) );
$changed = true;
}
if ( $changed ) {
$context->processor->set_attribute( 'sizes', join( ', ', $sizes ) );
}
return false; // Since this tag visitor does not require this tag to be included in the URL Metrics.
}

So in the same way as with WP_Scripts where registered scripts have handles, here too tag visitors (callables) have IDs. As with script dependencies being able to register a script which depends on another script by passing an array of dependency handles, so too as seen in Enhanced Responsive Images there should be a way to register a tag visitor so that it runs after other tag visitors have done.

/**
* The ID used the register the class
*/
public const ID = 'image-prioritizer-img';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would also make sense to add to Embed_Optimizer_Tag_Visitor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, I don't see any change to the Embed_Optimizer_Tag_Visitor class in the Embed Optimizer plugin?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@westonruter I am not sure what is going on here you might need to take this over

Paul Bearne added 2 commits August 15, 2024 16:24
Standardize spacing in visitor registration method for better readability. Additionally, introduce a constant ID in Image_Prioritizer_Tag_Visitor to facilitate consistent class registration.
Updated the tag visitor registration to use a consistent method for registering dependencies. Specifically, adjusted the `register` method in `class-od-tag-visitor-registry.php` and modified `auto_sizes_register_tag_visitors` to include a conditional dependency for the Image Prioritizer visitor. Removed unnecessary priority in the `add_action` call for better execution order management.
plugins/auto-sizes/optimization-detective.php Outdated Show resolved Hide resolved
plugins/image-prioritizer/helper.php Outdated Show resolved Hide resolved
plugins/image-prioritizer/helper.php Outdated Show resolved Hide resolved
@westonruter westonruter added the [Type] Enhancement A suggestion for improvement of an existing feature label Aug 16, 2024
pbearne and others added 5 commits August 21, 2024 19:44
Updated the tag visitor registration to use a consistent method for registering dependencies. Specifically, adjusted the `register` method in `class-od-tag-visitor-registry.php` and modified `auto_sizes_register_tag_visitors` to include a conditional dependency for the Image Prioritizer visitor. Removed unnecessary priority in the `add_action` call for better execution order management.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked [Plugin] Optimization Detective Issues for the Optimization Detective plugin [Type] Enhancement A suggestion for improvement of an existing feature
Projects
Status: Not Started/Backlog 📆
Development

Successfully merging this pull request may close these issues.

Dependencies for tag visitors in Optimization Detective
2 participants