-
Notifications
You must be signed in to change notification settings - Fork 385
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
Enable captions on Gallery shortcodes #3659
Changes from 21 commits
1b34cef
dde1e46
a48d974
5c7334b
641e008
cbd925b
5e07516
93246e8
08404be
0caa844
2c32f41
22ae686
82b428a
d3ba063
93aa3ea
6ba9bdb
2ed1653
5794193
78b0c75
3125261
67c7590
692d14b
8eb54a8
07cfc97
c0a5e05
7e206ef
3f0ee52
2b4a98f
284b328
d7fdbd2
be2b4e2
12c6d26
951cd3f
12f062e
92a764e
7b603ea
305e471
8de2340
3cdd86f
097d1b8
873c41a
38df209
f48d09b
5a8749c
0355530
450f9cd
0ae904e
4ac1d25
478f71e
c7d5d6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,44 @@ | ||||||
<?php | ||||||
/** | ||||||
* Class Captioned_Image | ||||||
* | ||||||
* @package AMP | ||||||
*/ | ||||||
|
||||||
namespace AMP; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should try to keep the AMP namespace structured from the start, to not end up with an ever-growing flat list of objects in the namespace folder. Once we start really going down the OOP route, we'll more separate classes with less code in each, so we need to plan ahead. The root namespace should be reserved for the most fundamental interfaces/building blocks, and then have a few meaningful subnamespaces for the rest of the classes. What we might need so far (just a first thought, really):
Do we want to add a placeholder namespace, like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea, the current directory to namespace mapping is:
How does that look? |
||||||
|
||||||
/** | ||||||
* Class Captioned_Image | ||||||
* | ||||||
* @since 1.5.0 | ||||||
* @internal | ||||||
*/ | ||||||
final class Captioned_Image extends Image implements Has_Caption { | ||||||
|
||||||
/** | ||||||
* The caption text. | ||||||
* | ||||||
* @var string | ||||||
*/ | ||||||
private $caption; | ||||||
|
||||||
/** | ||||||
* Constructs the class. | ||||||
* | ||||||
* @param \DOMElement $image_node The image node. | ||||||
* @param string $caption The caption text. | ||||||
*/ | ||||||
public function __construct( \DOMElement $image_node, $caption ) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest always importing all classes, even the non-namespaced ones. This will not only get rid of the use DOMElement; This list of dependencies is very valuable later down the road for debugging and refactoring.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, 3f0ee52 imports the classes. |
||||||
parent::__construct( $image_node ); | ||||||
$this->caption = $caption; | ||||||
} | ||||||
|
||||||
/** | ||||||
* Gets the caption text. | ||||||
* | ||||||
* @return string The caption text. | ||||||
*/ | ||||||
public function get_caption() { | ||||||
return $this->caption; | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
/** | ||
* Interface Has_Caption | ||
* | ||
* @package AMP | ||
*/ | ||
|
||
namespace AMP; | ||
|
||
/** | ||
* Interface Has_Caption | ||
* | ||
* @since 1.5.0 | ||
* @internal | ||
*/ | ||
interface Has_Caption { | ||
/** | ||
* Gets the caption. | ||
* | ||
* @return string The caption text. | ||
*/ | ||
public function get_caption(); | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,57 @@ | ||||||||||||||||
<?php | ||||||||||||||||
/** | ||||||||||||||||
* Class Image_List | ||||||||||||||||
* | ||||||||||||||||
* @package AMP | ||||||||||||||||
*/ | ||||||||||||||||
|
||||||||||||||||
namespace AMP; | ||||||||||||||||
|
||||||||||||||||
/** | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, I suggest importing all external dependencies, as that makes it very clear what to watch out for later when refactoring or diagnosing bugs.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, good idea. 3f0ee52 imports the classes. Your commit above looks good, but I moved the files to |
||||||||||||||||
* Class Image_List | ||||||||||||||||
* | ||||||||||||||||
* @since 1.5.0 | ||||||||||||||||
* @internal | ||||||||||||||||
*/ | ||||||||||||||||
final class Image_List implements \IteratorAggregate, \Countable { | ||||||||||||||||
|
||||||||||||||||
/** | ||||||||||||||||
* The captioned images. | ||||||||||||||||
* | ||||||||||||||||
* @var Captioned_Image[] | ||||||||||||||||
*/ | ||||||||||||||||
private $elements = []; | ||||||||||||||||
|
||||||||||||||||
/** | ||||||||||||||||
* Adds an image to the list. | ||||||||||||||||
* | ||||||||||||||||
* @param \DOMElement $image_node The image to add. | ||||||||||||||||
* @param string $caption The caption to add. | ||||||||||||||||
* @return self | ||||||||||||||||
*/ | ||||||||||||||||
public function add( \DOMElement $image_node, $caption = '' ) { | ||||||||||||||||
$this->elements[] = empty( $caption ) ? new Image( $image_node ) : new Captioned_Image( $image_node, $caption ); | ||||||||||||||||
return $this; | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
/** | ||||||||||||||||
* Gets an iterator with the elements. | ||||||||||||||||
* | ||||||||||||||||
* This together with the IteratorAggregate turns the object into a "Traversable", | ||||||||||||||||
* so you can just foreach over it and receive its elements in the correct type. | ||||||||||||||||
* | ||||||||||||||||
* @return \ArrayIterator An iterator with the elements. | ||||||||||||||||
*/ | ||||||||||||||||
public function getIterator() { | ||||||||||||||||
return new \ArrayIterator( $this->elements ); | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
/** | ||||||||||||||||
* Gets the count of the images. | ||||||||||||||||
* | ||||||||||||||||
* @return int The number of images. | ||||||||||||||||
*/ | ||||||||||||||||
public function count() { | ||||||||||||||||
return count( $this->elements ); | ||||||||||||||||
} | ||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
/** | ||
* Class Image | ||
* | ||
* @package AMP | ||
*/ | ||
|
||
namespace AMP; | ||
|
||
/** | ||
* Class Image | ||
* | ||
* @since 1.5.0 | ||
* @internal | ||
*/ | ||
class Image { | ||
|
||
/** | ||
* The image node. | ||
* | ||
* @var \DOMElement | ||
*/ | ||
protected $image_node; | ||
|
||
/** | ||
* Constructs the class. | ||
* | ||
* @param \DOMElement $image_node The image node. | ||
*/ | ||
public function __construct( \DOMElement $image_node ) { | ||
$this->image_node = $image_node; | ||
} | ||
|
||
/** | ||
* Gets the image. | ||
* | ||
* @return \DOMElement | ||
*/ | ||
public function get_image_node() { | ||
return $this->image_node; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,8 @@ | |
* @package AMP | ||
*/ | ||
|
||
use AMP\Image_List; | ||
|
||
/** | ||
* Class AMP_Gallery_Embed_Handler | ||
* | ||
|
@@ -129,25 +131,14 @@ public function shortcode( $attr ) { | |
'width' => $width, | ||
'height' => $height, | ||
'alt' => trim( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ), // Logic from wp_get_attachment_image(). | ||
'id' => $attachment_id, | ||
]; | ||
} | ||
|
||
$args = [ | ||
'images' => $urls, | ||
'images' => $urls, | ||
'lightbox' => ! empty( $atts['lightbox'] ), | ||
]; | ||
if ( ! empty( $atts['lightbox'] ) ) { | ||
$args['lightbox'] = true; | ||
$lightbox_tag = AMP_HTML_Utils::build_tag( | ||
'amp-image-lightbox', | ||
[ | ||
'id' => AMP_Base_Sanitizer::AMP_IMAGE_LIGHTBOX_ID, | ||
'layout' => 'nodisplay', | ||
'data-close-button-aria-label' => __( 'Close', 'amp' ), | ||
] | ||
); | ||
/* We need to add lightbox tag, too. @todo Could there be a better alternative for this? */ | ||
return $this->render( $args ) . $lightbox_tag; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is now using amp-lightbox-gallery as recommended by amphtml, so all that's needed is a |
||
|
||
return $this->render( $args ); | ||
} | ||
|
@@ -211,6 +202,7 @@ public function maybe_override_gallery( $html, $attributes ) { | |
* @return string Rendered. | ||
*/ | ||
public function render( $args ) { | ||
$dom = new DOMDocument(); | ||
$this->did_convert_elements = true; | ||
|
||
$args = wp_parse_args( | ||
|
@@ -224,11 +216,7 @@ public function render( $args ) { | |
return ''; | ||
} | ||
|
||
$max_aspect_ratio = 0; | ||
$carousel_width = 0; | ||
$carousel_height = 0; | ||
|
||
$images = []; | ||
$images = new Image_List(); | ||
foreach ( $args['images'] as $props ) { | ||
$image_atts = [ | ||
'src' => $props['url'], | ||
|
@@ -241,47 +229,38 @@ public function render( $args ) { | |
$image_atts['srcset'] = $props['srcset']; | ||
} | ||
|
||
$this_aspect_ratio = $props['width'] / $props['height']; | ||
if ( $this_aspect_ratio > $max_aspect_ratio ) { | ||
$max_aspect_ratio = $this_aspect_ratio; | ||
$carousel_width = $props['width']; | ||
$carousel_height = $props['height']; | ||
} | ||
|
||
if ( ! empty( $args['lightbox'] ) ) { | ||
$image_atts['lightbox'] = ''; | ||
$image_atts['on'] = 'tap:' . AMP_Img_Sanitizer::AMP_IMAGE_LIGHTBOX_ID; | ||
$image_atts['role'] = 'button'; | ||
$image_atts['tabindex'] = 0; | ||
} | ||
$image = AMP_HTML_Utils::build_tag( | ||
$image = AMP_DOM_Utils::create_node( | ||
$dom, | ||
'amp-img', | ||
$image_atts | ||
); | ||
|
||
if ( ! empty( $props['href'] ) ) { | ||
$image = AMP_HTML_Utils::build_tag( | ||
$previous_image = $image; | ||
$image = AMP_DOM_Utils::create_node( | ||
$dom, | ||
'a', | ||
[ | ||
'href' => $props['href'], | ||
], | ||
$image | ||
] | ||
); | ||
$image->appendChild( $previous_image ); | ||
} | ||
|
||
$images[] = $image; | ||
$caption = isset( $props['id'] ) ? wp_get_attachment_caption( $props['id'] ) : ''; | ||
$images->add( $image, $caption ); | ||
} | ||
|
||
return AMP_HTML_Utils::build_tag( | ||
'amp-carousel', | ||
[ | ||
'width' => $carousel_width, | ||
'height' => $carousel_height, | ||
'type' => 'slides', | ||
'layout' => 'responsive', | ||
], | ||
implode( PHP_EOL, $images ) | ||
); | ||
$amp_carousel = new AMP_Carousel( $dom ); | ||
$carousel_node = $amp_carousel->create_and_get( $images ); | ||
|
||
// Prevent an error in get_content_from_dom_node() when it calls $node->parentNode->insertBefore(). | ||
$dom->appendChild( $carousel_node ); | ||
|
||
return AMP_DOM_Utils::get_content_from_dom_node( $dom, $carousel_node ); | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ensures that the classmaps for the files in
src/
are regenerated withcomposer install
. Otherwise, I think it's necessary to runcomposer install -o
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be removed, and a corresponding change should be made to the build process instead.
If an optimized autoloader is forced, then you'll have to constantly rebuild the plugin on filesystem changes even during development.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, it's removed in 4ac1d25. Next, I'll apply in in the build processes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c7d5d6e adds the
-o
flag tocomposer install
only for production build processes and when creating a pre-release.Maybe it should should also be added to
.travis.yml
, but I thought the optimization wouldn't be worth the trouble in debugging if the build is cached: