-
Notifications
You must be signed in to change notification settings - Fork 0
/
template.inc
337 lines (281 loc) · 10.5 KB
/
template.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
<?php
/**
* @file
* Helper functions that are not used on every site.
*
* The contents of many functions here were copied and pasted from the bodies of
* hook implementations on the sites they were written for. Documentation of
* some of those functions' parameters are found on the hooks they were
* originally implementations of; those hooks are noted by name in the docblock
* for those functions.
*/
/**
* Returns an array with my mad responsive breakpoint calculations.
*
* Probably soon to be obsoleted by my switch from the less module to
* Sass + CodeKit.
*
* @param int[] $maxima
* The largest number of pixels you possibly want for each breakpoint's
* smallest width. In other words, "the maximum for each minimum". DO NOT
* include the smallest breakpoint; it goes from 0 to one pixel less than
* your smallest breakpoint's minimum.
* @param string
* The name of the smallest breakpoint.
* @param int $columns
* The number of columns in the normal layout.
* @param int $column_factor
* The number by which you want all column widths to be divisible.
*
* @return array
* Data structure representing every breakpoint and their smallest and largest
* widths.
*/
function _copy_me_get_breakpoint_dimensions(
$maxima = array('desktop-large' => 1200, 'desktop-small' => 980, 'tablet' => 768), // The largest that each breakpoint minimum can POSSIBLY go
$smallest_breakpoint_name = 'mobile', // The breakpoint that begins at zero and extends to the lowest breakpoint in $maxima
$columns = 12, // Number of columns in the grid layout
$column_factor = 5 // Number by which all column widths must be divisible
) {
arsort($maxima); // Sort the breakpoints, largest first
$breakpoints = array_keys($maxima); // List of breakpoints
$dimensions = array();
// The fun begins. For each breakpoint, find the highest column width that is divisible by
// $column_factor, and also results in a number less than or equal to the $maxima entry
// when you multiply the column width by $columns.
foreach($maxima as $breakpoint => $maximum) {
$dimensions[$breakpoint]['column-x'] = floor($maximum / $columns) - (floor($maximum / $columns) % $column_factor);
}
// Now, given the calculated column widths, compute the boundaries of each breakpoint.
for($i = 0; $i < count($breakpoints); $i++) {
$boundary = $dimensions[$breakpoints[$i]]['column-x'] * $columns; // The minimum for this breakpoint is just the column width times the number of columns
$dimensions[$breakpoints[$i]]['min'] = $boundary; // Put it in the actual result array
if(!empty($breakpoints[$i + 1])) { // If there's another breakpoint with a non-zero minimum
$dimensions[$breakpoints[$i + 1]]['max'] = $boundary - 1; // The next-largest breakpoint's upper boundary is, of course, one pixel less
} else { // If this is the smallest breakpoint with non-zero minimum
$dimensions[$smallest_breakpoint_name]['max'] = $boundary - 1; //
}
}
return $dimensions;
}
/**
* Gets a value out of a Drupal entity object's field property. Needs work.
*
* @param string $entity_type
* E.g. 'node'.
* @param object $entity
* Entity object.
* @param string
* Machine name of the field you want to retrieve one of the values of.
* @param int $delta
* Which entry in a multi-value field you want.
* @param string $img_prop
* Which property of an image you want to return. This should be abstracted
* out to apply to any field type, not just images.
*
* @return string
* The raw value or rendered output of the requested field.
*/
function _copy_me_get_field_item_value($entity_type, $entity, $field_name, $delta = 0, $img_prop = 'uri') {
$field_info = field_info_field($field_name);
$result = field_get_items($entity_type, $entity, $field_name);
if($field_info['type'] === 'datetime') {
return strtotime($result[$delta]['value'] . 'UTC');
}
if($field_info['type'] === 'taxonomy_term_reference') {
return $result[$delta]['tid'];
}
$result = field_view_value($entity_type, $entity, $field_name, $result[$delta]);
if(!empty($result['#theme']) && $result['#theme'] === 'image_formatter') {
if(empty($result['#item'])) {
return FALSE;
}
if($img_prop === 'uri') {
$uri = $result['#item']['uri'];
if(!empty($result['#image_style'])) {
$uri = image_style_url($result['#image_style'],
image_style_path($result['#image_style'], $result['#item']['uri'])
);
}
return file_create_url($uri);
} else {
return $result['#item'][$img_prop];
}
}
return render($result);
}
/**
* Makes Location module proximity searches more user-friendly, after liberal
* CSS application
*
* @param object &$form
* Form object.
* @param string $el
* Machine name of the element of the exposed form to modify.
*/
function _copy_me_prettify_location_search(&$form, $el = 'zip') {
$form[$el]['postal_code']['#title'] = t('ZIP code');
$form[$el]['postal_code']['#size'] = 5;
$form[$el]['search_units']['#type'] = 'hidden';
$form[$el]['search_distance']['#prefix'] = 'Show locations within ';
$form[$el]['search_distance']['#suffix'] = ' miles of ';
$form[$el]['search_distance']['#size'] = 3;
$form[$el]['search_distance']['#weight'] = 0;
}
/**
* Wraps menu block submenus in an additional div. This function does nothing
* without being called in an actual copy_me_menu_link function.
*
* Remember to return this function's return value when you call it!
*
* @param array $variables
* Variables array from theme_menu_link().
*
* @return string
* Constructed menu link suitable for theme_menu_link() return value.
*
* @see theme_menu_link()
*/
function _copy_me_wrap_menu_submenus($variables) {
$element = $variables ['element'];
$sub_menu = '';
if ($element ['#below']) {
$sub_menu = '<div class="submenu">' . drupal_render($element ['#below']) . '</div>';
}
$options = $element['#localized_options'];
$options['html'] = TRUE;
$output = '<span>' . check_plain($element['#title']) . '</span>';
$output = l($output, $element ['#href'], $options);
return '<li' . drupal_attributes($element ['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
/**
* Does surgery on Illustrator's default SVG output.
*
* @param string $svg
* File path or Drupal URI to uploaded SVG file. Only works on local file
* systems at this time.
* @param bool $is_uri
* Manual designation of whether a file path or a Drupal URI was supplied.
*
* @return string
* Final SVG string for document.
*
* @todo Detect what kind of path is supplied, instead of having a parameter
* for it.
* @todo Change to work with remote file systems.
*/
function _copy_me_get_svg($svg, $is_uri = TRUE) {
if($is_uri) {
$svg = drupal_realpath($svg);
}
$svg = file_get_contents($svg);
$svg = substr($svg, strpos($svg, "\n") + 1);
$svg = preg_replace('/id="Layer_[0-9]*"/', sprintf('class="svg"'), $svg);
$svg = str_replace('\n', '', $svg);
$svg = '<!--[if gte IE 9]><!-->' . $svg . '<!--<![endif]-->';
return $svg;
}
/**
* Constructs grammatically pleasing titles for News archive views that accept
* year, month, and day arguments.
*
* To be called in copy_me_views_pre_render(), naturally.
*
* @param object &$view
* $view object from hook_views_pre_render().
*/
function _copy_me_news_view_titles(&$view) {
$date_parts = array(
(int)$view->argument['created_year']->argument,
(int)$view->argument['created_month']->argument,
(int)$view->argument['created_day']->argument,
);
$date_parts = array_filter($date_parts);
if(empty($date_parts)) {
return;
}
$date_preposition = 'in'; // "No news items in January 2014" versus "No news items on January 8, 2014"
if(!empty($date_parts[1])) {
$date_obj = DateTime::createFromFormat('!m', (int)$date_parts[1]);
$date_parts[1] = $date_obj->format('F') . ' ';
}
if(!empty($date_parts[2])) {
$date_parts[2] = (string)$date_parts[2] . ', ';
$date_preposition = 'on'; // See comment above
}
$date_parts = array_pad($date_parts, 3, '');
$date_string = sprintf('%s%s%d', $date_parts[1], $date_parts[2], $date_parts[0]);
if(empty($date_string)) {
$date_string = '';
}
$view->empty['area']->options['content'] = sprintf('There were no news items %s %s.', $date_preposition, $date_string);
}
/**
* Stops Drupal's default behavior of automatically expanding the children
* of menu links pointing to your current page.
*
* Goes in copy_me_menu_block_tree_alter().
*
* @see hook_menu_block_tree_alter()
*/
function _copy_me_suppress_menu_auto_expansion(&$tree, &$config) {
// Don't do anything if the entire menu block is set to be Expanded
if($config['expanded']) {
return;
}
foreach($tree as $link_key => &$link) {
if(!empty($link['below'])) {
if(!$link['link']['expanded']) { // Only hide children if this link is not manually set to expanded
$link['below'] = array();
} else {
// Call this same function recursively on the children.
_copy_me_suppress_menu_auto_expansion($link['below'], $config);
}
}
}
unset($link);
}
/**
* Adds class to Views list containers (<ul>, <ol>) denoting how many rows are
* within.
*
* Goes in copy_me_preprocess_views_view_list().
*
* @see template_preprocess_views_view_list()
*/
function _copy_me_list_view_container_quantity_class(&$variables) {
$handler = $variables['view']->style_plugin;
$variables['list_type_prefix'] = sprintf('<%s class="view-rows-%s">', $handler->options['type'], count($variables['rows']));
}
/**
* Adds a notice to the bottom of the final page of a paginated View.
*
* Goes in copy_me_views_pre_render().
*
* @param object &$view
* View object.
* @param string[] $list_displays
* Array of machine names of displays that show a list of rendered posts
* @param string[] $nav_displays
* Array of machine names of displays that show a summary navigation
*/
function _copy_me_end_of_paged_view(&$view, $list_displays = array('page_1'), $nav_displays = array('attachment_1')) {
if(in_array($view->current_display, $list_displays)) {
$current_page = $view->query->pager->current_page + 1;
$total = (int) $view->query->pager->total_items;
$per_page = $view->query->pager->options['items_per_page'];
if($current_page * $per_page >= $total) {
ob_start();
include 'sites/default/themes/aedc/templates/old-newsroom-entries.php'; // FIXME FIXME!
$notice = ob_get_clean();
$view->attachment_after .= $notice;
$view->attachment_before .= $notice;
}
}
if(in_array($view->current_display, $nav_displays)) {
$obj = new stdClass();
$obj->node_created_year = '2012 and earlier'; // FIXME FIXME!
$obj->node_created = '1341014400'; // FIXME FIXME!
$view->result[] = $obj;
}
}