Skip to content

Commit aa8af32

Browse files
committed
Generate embeds using oEmbed
* Fetch embed codes from the new oEmbed service instead of creating them manually (but leave existing functions in place until we're sure they can be discarded) * Support both `maxwidth/maxheight` and `height/width` shortcode attrs, but only sends `max*` to the provider * Nominally backwards-compatible with existing shortcodes and settings (should be tested) * Piggy-backs on WordPress's internal oembed caching; to disable, change `add_shortcode('documentcloud', array(&$this, 'handle_dc_shortcode_with_caching'));` to `add_shortcode('documentcloud', array(&$this, 'handle_dc_shortcode'));` Affects #16 Closes #14
1 parent 0a380d3 commit aa8af32

File tree

1 file changed

+147
-7
lines changed

1 file changed

+147
-7
lines changed

documentcloud.php

+147-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Plugin Name: DocumentCloud
44
* Plugin URI: https://www.documentcloud.org/
55
* Description: Embed DocumentCloud resources in WordPress content.
6-
* Version: 0.1.2
6+
* Version: 0.2
77
* Authors: Chris Amico, Justin Reese
88
* License: GPLv2
99
***/
@@ -29,18 +29,22 @@ class WP_DocumentCloud {
2929

3030
function __construct() {
3131

32-
// Register us as an oEmbed provider
3332
add_action('init', array(&$this, 'register_dc_oembed_provider'));
34-
// Register [documentcloud] shortcode using old embed method
35-
add_shortcode('documentcloud', array(&$this, 'embed_shortcode'));
36-
33+
add_shortcode('documentcloud', array(&$this, 'handle_dc_shortcode_with_caching'));
34+
add_filter('oembed_fetch_url', array(&$this, 'add_dc_arguments'), 10, 3);
35+
3736
// Setup TinyMCE shortcode-generation plugin
3837
add_action('init', array(&$this, 'register_tinymce_filters'));
3938

40-
// Process shortcodes and add admin settings
41-
add_action('save_post', array(&$this, 'save'));
39+
// Setup admin settings
4240
add_action('admin_menu', array(&$this, 'add_options_page'));
4341
add_action('admin_init', array(&$this, 'settings_init'));
42+
43+
// Register [documentcloud] shortcode using old embed method
44+
// add_shortcode('documentcloud', array(&$this, 'embed_shortcode'));
45+
46+
// Store metadata upon post save
47+
// add_action('save_post', array(&$this, 'save'));
4448
}
4549

4650
function register_dc_oembed_provider() {
@@ -56,9 +60,143 @@ function register_dc_oembed_provider() {
5660
// wp_oembed_add_provider('http://[your_domain]/documents/*','http://[your_domain]/api/oembed.{format}');
5761
// wp_oembed_add_provider('https://[your_domain]/documents/*','http://[your_domain]/api/oembed.{format}');
5862

63+
wp_oembed_add_provider('http://www.documentcloud.org/documents/*', 'https://www.documentcloud.org/api/oembed.{format}');
5964
wp_oembed_add_provider('https://www.documentcloud.org/documents/*', 'https://www.documentcloud.org/api/oembed.{format}');
6065
}
6166

67+
function default_dc_atts() {
68+
// Notably, `maxwidth/maxheight` are NOT set here, even though
69+
// they are proper attributes, because we let the user set them
70+
// in the settings area. See notes on `handle_dc_shortcode()`.
71+
return array(
72+
'url' => null,
73+
'container' => null,
74+
'notes' => null,
75+
'responsive_offset' => null,
76+
'default_page' => null,
77+
'default_note' => null,
78+
'zoom' => null,
79+
'search' => null,
80+
'sidebar' => 'false', // Backwards-compatibility
81+
'text' => 'true', // Backwards-compatibility
82+
'pdf' => 'true', // Backwards-compatibility
83+
'responsive' => null,
84+
);
85+
}
86+
87+
function add_dc_arguments($provider, $url, $args) {
88+
foreach ($args as $key => $value) {
89+
switch ($key) {
90+
// We don't want to pass these three to the provider
91+
case 'height':
92+
case 'width':
93+
case 'discover':
94+
break;
95+
default:
96+
$provider = add_query_arg( $key, $value, $provider );
97+
break;
98+
}
99+
}
100+
return $provider;
101+
}
102+
103+
function handle_dc_shortcode($atts) {
104+
$filtered_atts = shortcode_atts($this->default_dc_atts(), $atts);
105+
106+
// This is a tricky bit of logic that ends up:
107+
// 1. Allowing both `width/height` and `maxwidth/maxheight` as
108+
// acceptable shortcode parameters;
109+
// 2. Only sending `maxwidth/maxheight` to the oEmbed service;
110+
// 3. Respecting the user's settings
111+
// To understand it, you must deeply understand the flow of
112+
// data through the WordPress bowels, or at least misunderstand
113+
// it in the same way we do. It could likely be cleaned up,
114+
// but should be WELL TESTED if so.
115+
if (isset($atts['maxheight'])) {
116+
$filtered_atts['maxheight'] = $atts['maxheight'];
117+
} else if (isset($atts['height'])) {
118+
$filtered_atts['maxheight'] = $atts['height'];
119+
} else {
120+
$filtered_atts['maxheight'] = get_option('documentcloud_default_height', 600);
121+
}
122+
if (isset($atts['maxwidth'])) {
123+
$filtered_atts['maxwidth'] = $atts['maxwidth'];
124+
} else if (isset($atts['width'])) {
125+
$filtered_atts['maxwidth'] = $atts['width'];
126+
} else {
127+
$filtered_atts['maxwidth'] = get_option('documentcloud_default_width', 620);
128+
}
129+
130+
// Either the `url` or `id` attributes are required, but `id`
131+
// is only supported for backwards compatibility. If it's used,
132+
// we force this to embed a document. I.e., it can't be used
133+
// for embedding notes, pages, or other non-document resources.
134+
if (!$atts['url']) {
135+
if (!$atts['id']) {
136+
return '';
137+
}
138+
else {
139+
$url = $filtered_atts['url'] = "https://www.documentcloud.org/documents/{$atts['id']}.html";
140+
}
141+
} else {
142+
$url = $atts['url'];
143+
}
144+
145+
return wp_oembed_get($url, $filtered_atts);
146+
}
147+
148+
// This is an exact clone of `handle_dc_shortcode`, except that it
149+
// lets WordPress cache the result of the oEmbed call. Thanks to
150+
// http://bit.ly/1HykA0U for this pattern.
151+
function handle_dc_shortcode_with_caching($atts) {
152+
global $wp_embed;
153+
154+
$filtered_atts = shortcode_atts($this->default_dc_atts(), $atts);
155+
156+
// This is a tricky bit of logic that ends up:
157+
// 1. Allowing both `width/height` and `maxwidth/maxheight` as
158+
// acceptable shortcode parameters;
159+
// 2. Only sending `maxwidth/maxheight` to the oEmbed service;
160+
// 3. Respecting the user's settings
161+
// To understand it, you must deeply understand the flow of
162+
// data through the WordPress bowels, or at least misunderstand
163+
// it in the same way we do. It could likely be cleaned up,
164+
// but should be WELL TESTED if so.
165+
if (isset($atts['maxheight'])) {
166+
$filtered_atts['maxheight'] = $atts['maxheight'];
167+
} else if (isset($atts['height'])) {
168+
$filtered_atts['maxheight'] = $atts['height'];
169+
} else {
170+
$filtered_atts['maxheight'] = get_option('documentcloud_default_height', 600);
171+
}
172+
if (isset($atts['maxwidth'])) {
173+
$filtered_atts['maxwidth'] = $atts['maxwidth'];
174+
} else if (isset($atts['width'])) {
175+
$filtered_atts['maxwidth'] = $atts['width'];
176+
} else {
177+
$filtered_atts['maxwidth'] = get_option('documentcloud_default_width', 620);
178+
}
179+
180+
// Either the `url` or `id` attributes are required, but `id`
181+
// is only supported for backwards compatibility. If it's used,
182+
// we force this to embed a document. I.e., it can't be used
183+
// for embedding notes, pages, or other non-document resources.
184+
if (!$atts['url']) {
185+
if (!$atts['id']) {
186+
return '';
187+
}
188+
else {
189+
$url = $filtered_atts['url'] = "https://www.documentcloud.org/documents/{$atts['id']}.html";
190+
}
191+
} else {
192+
$url = $atts['url'];
193+
}
194+
195+
return $wp_embed->shortcode($filtered_atts, $url);
196+
}
197+
198+
// TinyMCE and settings page
199+
62200
function register_tinymce_filters() {
63201
add_filter('mce_external_plugins',
64202
array(&$this, 'add_tinymce_plugin')
@@ -148,6 +286,8 @@ function full_width_field() {
148286

149287
function settings_section() {}
150288

289+
// Hopefully can remove from here down?
290+
151291
function save($post_id) {
152292
// tell the post if we're carrying a wide load
153293

0 commit comments

Comments
 (0)