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

Add annotations REST API using comments #4386

Closed
wants to merge 1 commit into from
Closed

Add annotations REST API using comments #4386

wants to merge 1 commit into from

Conversation

jaswrks
Copy link
Contributor

@jaswrks jaswrks commented Jan 10, 2018

Description

A REST API for annotations using custom comment types. This approach has my vote 👍
This PR is an alternative to annotations as a custom post type in #4385

API Documentation

See: https://speca.io/jaswrks/wp-annotation-comments

Conforms to the W3C annotation data model for annotation selectors and maintains some parity with the W3C annotation object model and protocol — while still doing things the WordPress way, which maximizes compatibility with WP REST API utilities, including those in JavaScript.

Tip: Review annotation creation examples to see how W3C annotation selectors work.

In the future, we could add an additional API controller that supports the JSON-LD annotation protocol, and simply map those requests to the official WP REST API internally; e.g., rest_do_request(). I've been over that protocol carefully. The API presented in this PR collects enough information, in the right way, to eventually support it if we'd like to.

For now, my feeling is that the JSON-LD protocol for annotations is still very young, and so are annotations in WordPress. From a practical standpoint, I suggest that we make the JSON-LD protocol a secondary objective once Gutenberg annotations have matured somewhat; i.e., to maximize compatibility with other annotation clients following the W3C.

How Has This Been Tested?

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows has proper inline documentation.

Types of changes

My initial work on an API for annotations began in #3807. Since then, the main change has been to consider the W3C Annotation Data model. See note above regarding W3C conformity/parity.

  • This approach uses custom comment types instead of a custom post type.
  • There has also been some refactoring, code cleanup, docBlock, and unit test enhancement.

Annotations as a Custom Comment Type

Pros and cons. Can you think of any others?

Comment Type Pros

  • We inherit a lot of functionality associated with comment/annotation author handling, content handling, hierarchical queries, spam-checking, flood-checking, notifications, etc. If front-end annotations become a thing, there's very little we need to do given the similarities. I've already added support for both front and back-end annotation types in this PR without much trouble.

    Note: As a security precaution, front-end annotations are disabled internally for now. At this time, the main focus is on back-end annotations. Front-end annotations are simply being considered for the purpose of optimizing our approach and the object model.

  • The WP_Comment_Query class, the WP_Comment object model, and core logic closely matches that of annotations. e.g., Author ID, or instead collect author name/email. Statuses like spam, hold, approve with respect to front-end comments, these also make sense for front-end annotations. Also, most of the configurable WordPress settings & filters associated with comments also apply to annotations. So we inherit all of those too.

Comment Type Cons

  • This approach puts annotations into the same table as comments. Depending on how you look at it, that's either a good thing (organization of semantics) or a bad thing (private annotation security). Comments and annotations are both alike, but private back-end annotations not so much. Therefore, this approach currently requires comment query filters that keep annotations out of the comments admin area, and away from plugins that might mistake them as being a more typical comment type. In this PR, the following alters comments_clauses in core.
/**
 * Filters WP_Comment_Query clauses.
 *
 * @param  array            $pieces Array of comment query clauses.
 * @param  WP_Comment_Query $query  Current WP_Comment_Query instance.
 *
 * @return array                    Array of comment query clauses.
 */
public static function on_comments_clauses( $pieces, $query ) {
	global $wpdb;

	/*
	 * When cache_domain is 'annotations', only then will annotations be returned by WP_Comment_Query.
	 * Otherwise, if cache_domain is not 'annotations', annotation comment types cannot be returned whatsoever.
	 *
	 * The point being that we want to keep annotations out of any normal comment query performed by core,
	 * and also keep them away from comment-related plugins; i.e., annotations will be unexpected by most plugins.
	 * If a plugin *does* want to query annotations, they should set cache_domain to 'annotations'.
	 */
	if ( 'annotations' !== $query->query_vars['cache_domain'] ) {
		$annotation_types = self::$types;

		foreach ( $annotation_types as &$_type ) {
			$_type = $wpdb->prepare( '%s', $_type );
		}
		$pieces['where'] .= $pieces['where'] ? ' AND ' : '';
		$pieces['where'] .= 'comment_type NOT IN (' . implode( ', ', $annotation_types ) . ')';
	}

	return $pieces;
}
  • This approach builds on top of the comment type in WP core, which has not seen the same sort of extensibility love that custom post types have. For example, there is no register_comment_type() or register_comment_status() functionality.

    Therefore, well-supported extensibility features are lacking somewhat when it comes to comments, and instead we'll need to do what we can with filters exposed by WP core. At the moment, I'm not aware of any major roadblocks in this approach, but it's hard to tell what the future might hold for annotations. So it's worth comparing this approach to that of a custom annotation post type. Which do you think is better and why?

Back-End Annotation Permissions

Simplified Explanation

  • If you can edit_posts, and you can edit_post (this post). Or, if you're the post author. Then you can read all, and create, edit, delete your own back-end annotations in this post.

  • Administrators and Editors can edit and delete any post, so they can read, edit, and delete any annotation without restriction.

  • Subscribers and the public have no access to back-end annotations whatsoever.

back-end-permissions

Front-End Annotation Permissions

Simplified Explanation

Almost exactly the same as comments. They adhere to the same rules with respect to comments being open, or not, and anyone who can moderate_comments can moderate front-end annotations.

Note: As a security precaution, front-end annotations are disabled internally for now. At this time, the main focus is on back-end annotations. Front-end annotations are simply being considered for the purpose of optimizing our approach and the object model.

front-end-permissions

TODO

  • Collect feedback and decide which approach is better (post type vs. comment type).
  • In the PR with the right approach, add additional unit tests, security review, polish.

@jaswrks
Copy link
Contributor Author

jaswrks commented Jan 13, 2018

Other Thoughts / Conclusions

This PR implements both front and back annotations.

However, I've concluded that if front-end annotations ever do become a thing, they'd be better implemented in a way that would simply extend the existing default comment type. In other words, WP core comments could simply be enhanced; allowing them to have annotation-like properties.

That way front-end comments and front-end annotations are both the same thing. The only real
difference being that an annotation has a selector; i.e., annotates a specific part of the document. If it doesn't (or is later orphaned) it simply joins or rejoins the flow of comments and is therefore treated like any other front-end comment, because it doesn't select anything.

So it might make sense to remove front-end annotations from this API altogether.

  • The term 'Annotation' could then be used to specifically describe back-end comments. Instead of having an admin_annotation comment type, we'd just have the annotation type.
  • The existing 'Comment' object model could later be enhanced to support selectors and simply be referred to as a selection-specific Comment — a front-end annotation.

If we go that route, then this PR could be used almost as-is. I'd just strip away the support for front-end annotation types and assume those will be added later in the manner that I just described. Or in any other way, for that matter.

In fact, I already have an up-to-date copy of this PR in reserve that's had support for front-end annotations stripped away. If that becomes desirable we could use it.

@jaswrks
Copy link
Contributor Author

jaswrks commented Jan 15, 2018

I enhanced the API documentation at:
https://speca.io/jaswrks/wp-annotation-comments

  • Move list of capabilities from PR outline to docs.
  • Add details regarding field-specific permissions.
  • Add additional (previously undocumented) functionality.
  • Add more examples.

@jaswrks
Copy link
Contributor Author

jaswrks commented Jan 16, 2018

Ready for review.

@jaswrks
Copy link
Contributor Author

jaswrks commented Jan 23, 2018

jsFiddle: Building and highlighting a W3C Annotation Selector using XPath.
https://jsfiddle.net/jaswrks/1cLaeyfd/

@jaswrks
Copy link
Contributor Author

jaswrks commented Jan 26, 2018

Closing in favor of #4685, which is a copy of this PR, but with support for front-end annotations stripped away.

@jaswrks jaswrks closed this Jan 26, 2018
@gziolo gziolo removed the [Status] In Progress Tracking issues with work in progress label Dec 14, 2018
@omarreiss omarreiss added the [Feature] Annotations Adding annotation functionality label Mar 26, 2019
@gziolo gziolo added the [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration label Nov 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Annotations Adding annotation functionality [Feature] Real-time Collaboration Phase 3 of the Gutenberg roadmap around real-time collaboration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants