Skip to content

Commit 744a614

Browse files
jomurgelkevinfodness
authored andcommitted
AN-169 Additional Gutenberg Embeds Support (#656)
1 parent 1708d24 commit 744a614

File tree

7 files changed

+923
-0
lines changed

7 files changed

+923
-0
lines changed

includes/apple-exporter/class-component-factory.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ public static function initialize(
9494
self::register_component( 'instagram', '\\Apple_Exporter\\Components\\Instagram' );
9595
self::register_component( 'table', '\\Apple_Exporter\\Components\\Table' );
9696
self::register_component( 'flickr', '\\Apple_Exporter\\Components\\Flickr' );
97+
self::register_component( 'wp-embed', '\\Apple_Exporter\\Components\\WP_Embed' );
98+
self::register_component( 'spotify', '\\Apple_Exporter\\Components\\Spotify' );
99+
self::register_component( 'soundcloud', '\\Apple_Exporter\\Components\\SoundCloud' );
97100
self::register_component( 'iframe', '\\Apple_Exporter\\Components\\Embed_Web_Video' );
98101
self::register_component( 'img', '\\Apple_Exporter\\Components\\Image' );
99102
self::register_component( 'video', '\\Apple_Exporter\\Components\\Video' );
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
/**
3+
* Publish to Apple News Includes: Apple_Exporter\Components\SoundCloud class
4+
*
5+
* Contains a class which is used to transform SoundCloud embeds into Apple News format.
6+
*
7+
* @package Apple_News
8+
* @subpackage Apple_Exporter
9+
* @since 0.2.0
10+
*/
11+
12+
namespace Apple_Exporter\Components;
13+
14+
/**
15+
* A class to transform an SoundCloud embed into an SoundCloud Apple News component.
16+
*
17+
* @since 0.2.0
18+
*/
19+
class SoundCloud extends Component {
20+
21+
/**
22+
* Spotify URLs to validate.
23+
*
24+
* @return void
25+
*/
26+
public static function validateUrl( $url = '' ) {
27+
return (
28+
preg_match( '#https?:\/\/(?:w\.|www\.|)soundcloud\.com\/player\/[^"\']++#', $url )
29+
);
30+
}
31+
32+
/**
33+
* Look for node matches for this component.
34+
*
35+
* @param \DOMElement $node The node to examine for matches.
36+
*
37+
* @access public
38+
* @return \DOMElement|null The node on success, or null on no match.
39+
*/
40+
public static function node_matches( $node ) {
41+
42+
// Match the src attribute against a classname (gutenberg) or soundcloud regex (classic)
43+
if (
44+
'figure' === $node->nodeName && self::node_has_class( $node, 'is-provider-soundcloud' )
45+
|| $node->hasChildNodes() && 'iframe' === $node->childNodes[0]->nodeName && self::validateUrl( $node->childNodes[0]->getAttribute( 'src' ) )
46+
) {
47+
return $node;
48+
}
49+
50+
return null;
51+
}
52+
53+
/**
54+
* Register all specs for the component.
55+
*
56+
* @access public
57+
*/
58+
public function register_specs() {
59+
$this->register_spec(
60+
'soundcloud-json',
61+
__( 'SoundCloud JSON', 'apple-news' ),
62+
array(
63+
'layout' => 'soundcloud-layout',
64+
'role' => 'container',
65+
'components' => '#components#',
66+
)
67+
);
68+
69+
$this->register_spec(
70+
'soundcloud-layout',
71+
__( 'Embed Layout', 'apple-news' ),
72+
array(
73+
'margin' => array(
74+
'top' => 15,
75+
'bottom' => 15,
76+
),
77+
)
78+
);
79+
}
80+
81+
/**
82+
* Build the component.
83+
*
84+
* @param string $html The HTML to parse into text for processing.
85+
*
86+
* @access protected
87+
*/
88+
protected function build( $html ) {
89+
90+
$caption = '';
91+
$hide_article_caption = true;
92+
$link = '';
93+
$title = '';
94+
$url = '';
95+
96+
// If we have a url, parse.
97+
if ( preg_match( '#<iframe.*?title="(.*?)".*?src="(.*?)"(.*?)>#', $html, $matches ) ) {
98+
$title = $matches[1];
99+
$url = $matches[2];
100+
$link = '<a href="' . esc_url( $url ) . '">' . esc_html__( 'View on SoundCloud.', 'apple-news' ) . '</a>';
101+
102+
// If caption exists, set as caption.
103+
$hide_article_caption = false;
104+
if ( preg_match( '#figcaption>(.*?)</fig#', $html, $caption_matches ) ) {
105+
$caption = $caption_matches[1];
106+
$hide_article_caption = false;
107+
}
108+
}
109+
110+
$registration_array = [
111+
'#components#' => [
112+
[
113+
'role' => 'heading2',
114+
'text' => $title,
115+
'format' => 'html',
116+
],
117+
],
118+
];
119+
120+
if ( ! empty( $caption ) ) {
121+
$registration_array['#components#'][]= [
122+
'role' => 'caption',
123+
'text' => $caption,
124+
'format' => 'html',
125+
'textStyle' => [
126+
'fontSize' => 16,
127+
],
128+
'hidden' => $hide_article_caption,
129+
];
130+
}
131+
132+
$registration_array['#components#'][] = [
133+
'role' => 'body',
134+
'text' => $link,
135+
'format' => 'html',
136+
'textStyle' => [
137+
'fontSize' => 14,
138+
],
139+
];
140+
141+
$this->register_json(
142+
'soundcloud-json',
143+
$registration_array
144+
);
145+
146+
// Get information about the currently loaded theme.
147+
$theme = \Apple_Exporter\Theme::get_used();
148+
149+
// Register the layout for the table.
150+
$this->register_layout( 'soundcloud-layout', 'soundcloud-layout' );
151+
}
152+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
/**
3+
* Publish to Apple News Includes: Apple_Exporter\Components\Spotify class
4+
*
5+
* Contains a class which is used to transform Spotify embeds into Apple News format.
6+
*
7+
* @package Apple_News
8+
* @subpackage Apple_Exporter
9+
* @since 0.2.0
10+
*/
11+
12+
namespace Apple_Exporter\Components;
13+
14+
/**
15+
* A class to transform an Spotify embed into an Spotify Apple News component.
16+
*
17+
* @since 0.2.0
18+
*/
19+
class Spotify extends Component {
20+
21+
/**
22+
* Spotify URLs to validate.
23+
*
24+
* @return void
25+
*/
26+
public static function validateUrl( $url = '' ) {
27+
return (
28+
preg_match( '#https?:\/\/(?:play\.|open\.)(?:)spotify\.com\/#', $url )
29+
);
30+
}
31+
32+
/**
33+
* Look for node matches for this component.
34+
*
35+
* @param \DOMElement $node The node to examine for matches.
36+
*
37+
* @access public
38+
* @return \DOMElement|null The node on success, or null on no match.
39+
*/
40+
public static function node_matches( $node ) {
41+
42+
// Match the src attribute against a classname (gutenberg) or spotify regex (classic)
43+
if (
44+
'figure' === $node->nodeName && self::node_has_class( $node, 'is-provider-spotify' )
45+
|| $node->hasChildNodes() && 'iframe' === $node->childNodes[0]->nodeName && self::validateUrl( $node->childNodes[0]->getAttribute( 'src' ) )
46+
) {
47+
return $node;
48+
}
49+
50+
return null;
51+
}
52+
53+
/**
54+
* Register all specs for the component.
55+
*
56+
* @access public
57+
*/
58+
public function register_specs() {
59+
$this->register_spec(
60+
'spotify-json',
61+
__( 'Spotify JSON', 'apple-news' ),
62+
array(
63+
'layout' => 'spotify-layout',
64+
'role' => 'container',
65+
'components' => '#components#',
66+
)
67+
);
68+
69+
$this->register_spec(
70+
'spotify-layout',
71+
__( 'Embed Layout', 'apple-news' ),
72+
array(
73+
'margin' => array(
74+
'top' => 15,
75+
'bottom' => 15,
76+
),
77+
)
78+
);
79+
}
80+
81+
/**
82+
* Build the component.
83+
*
84+
* @param string $html The HTML to parse into text for processing.
85+
*
86+
* @access protected
87+
*/
88+
protected function build( $html ) {
89+
90+
$caption = '';
91+
$hide_article_caption = true;
92+
$link = '';
93+
$title = '';
94+
$url = '';
95+
96+
// If we have a url, parse.
97+
if ( preg_match( '#<iframe.*?title="(.*?)".*?src="(.*?)"(.*?)>#', $html, $matches ) ) {
98+
$title = $matches[1];
99+
$url = $matches[2];
100+
$link = '<a href="' . esc_url( $url ) . '">' . esc_html__( 'View on Spotify.', 'apple-news' ) . '</a>';
101+
102+
// If caption exists, set as caption.
103+
$hide_article_caption = false;
104+
if ( preg_match( '#figcaption>(.*?)</figcaption#', $html, $caption_matches ) ) {
105+
$caption = $caption_matches[1];
106+
$hide_article_caption = false;
107+
}
108+
}
109+
110+
$registration_array = [
111+
'#components#' => [
112+
[
113+
'role' => 'heading2',
114+
'text' => $title,
115+
'format' => 'html',
116+
],
117+
],
118+
];
119+
120+
if ( ! empty( $caption ) ) {
121+
$registration_array['#components#'][] = [
122+
'role' => 'caption',
123+
'text' => $caption,
124+
'format' => 'html',
125+
'textStyle' => [
126+
'fontSize' => 16,
127+
],
128+
'hidden' => $hide_article_caption,
129+
];
130+
}
131+
132+
$registration_array['#components#'][] = [
133+
'role' => 'body',
134+
'text' => $link,
135+
'format' => 'html',
136+
'textStyle' => [
137+
'fontSize' => 14,
138+
],
139+
];
140+
141+
$this->register_json(
142+
'spotify-json',
143+
$registration_array
144+
);
145+
146+
// Get information about the currently loaded theme.
147+
$theme = \Apple_Exporter\Theme::get_used();
148+
149+
// Register the layout for the table.
150+
$this->register_layout( 'spotify-layout', 'spotify-layout' );
151+
}
152+
}

0 commit comments

Comments
 (0)