Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 561 lines (461 sloc) 15.357 kb
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
1 <?php
a9bc463 @danielbachhuber Tag v1.0.1
danielbachhuber authored
2 define( 'CNGNYC_VERSION', '1.0.1' );
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
3
49ad4f2 @danielbachhuber First pass at live events
danielbachhuber authored
4 include_once( 'php/class.cngnyc_event.php' );
5
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
6 if ( !class_exists( 'cngnyc' ) ) {
7
8 class cngnyc {
9
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
10 var $options_group = 'cngnyc_';
11 var $options_group_name = 'cngnyc_options';
12 var $settings_page = 'cngnyc_settings';
13
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
14 /**
15 * __construct()
16 */
17 function __construct() {
18
49ad4f2 @danielbachhuber First pass at live events
danielbachhuber authored
19 $this->event = new cngnyc_event();
20
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
21 // Add support for post formats and post thumbnails
22 add_action( 'after_setup_theme', array( &$this, 'after_setup_theme' ) );
23
24 add_action( 'init', array( &$this, 'init' ) );
25 add_action( 'init', array( &$this, 'create_taxonomies' ) );
26 add_action( 'init', array( &$this, 'enqueue_resources' ) );
27 add_action( 'init', array( &$this, 'register_menus' ) );
28
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
29 add_action( 'admin_init', array( &$this, 'admin_init' ) );
30
7a201c3 @danielbachhuber Make the project description a theme option
danielbachhuber authored
31 $this->options = get_option( $this->options_group_name );
32
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
33 } // END __construct()
34
35 /**
36 * init()
37 */
38 function init() {
78abf76 @danielbachhuber Don't show tags or categories
danielbachhuber authored
39 global $wp_taxonomies;
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
40
2a3c0c1 @danielbachhuber Add a Theme Options to the admin bar if user can edit those options
danielbachhuber authored
41 if ( is_admin_bar_showing() ) {
42 add_action( 'admin_bar_menu', array( &$this, 'add_admin_bar_items' ), 70 );
43 }
44
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
45 if ( is_admin() ) {
46 add_action( 'admin_menu', array(&$this, 'add_admin_menu_items') );
47 }
48
78abf76 @danielbachhuber Don't show tags or categories
danielbachhuber authored
49 if ( taxonomy_exists( 'post_tag' ) ) {
50 unset( $wp_taxonomies['post_tag']);
51 }
52 if ( taxonomy_exists( 'category' ) ) {
53 unset( $wp_taxonomies['category']);
54 }
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
55
56 } // END init()
57
58 /**
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
59 * admin_init()
60 */
61 function admin_init() {
62
63 $this->register_settings();
64
65 } // END admin_init()
66
67 /**
68 * add_admin_menu_items()
69 * Any admin menu items we need
70 */
71 function add_admin_menu_items() {
72
73 add_submenu_page( 'themes.php', 'Changing NYC Theme Options', 'Theme Options', 'manage_options', 'cngnyc_options', array( &$this, 'options_page' ) );
74
75 } // END add_admin_menu_items()
76
77 /**
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
78 * register_menus()
79 * Register menus
80 */
81 function register_menus() {
82 register_nav_menus(
83 array(
6f6a7bf @danielbachhuber Changing directions
danielbachhuber authored
84 'primary-navigation' => 'Primary Navigation',
85 'sidebar-taxonomy-places' => 'Taxonomy Sidebar: Places'
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
86 )
87 );
88 } // END register_menus()
89
90
91 /**
92 * enqueue_resources()
93 * Enqueue any resources we need
94 */
95 function enqueue_resources() {
96
97 if ( !is_admin() ) {
98 wp_enqueue_style( 'cngnyc_primary_css', get_bloginfo('template_directory') . '/style.css', false, CNGNYC_VERSION );
e113644 @danielbachhuber Facebook and Twitter icons in the right rail
danielbachhuber authored
99 wp_enqueue_style( 'custom_font_css', 'http://fonts.googleapis.com/css?family=Droid+Serif:regular,italic,bold,bolditalic', false );
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
100 }
101
102 } // END enqueue_resources()
103
104 /**
105 * create_taxonomies()
106 * Register taxonomies for all of our post types
107 */
108 function create_taxonomies() {
109
49ad4f2 @danielbachhuber First pass at live events
danielbachhuber authored
110 $post_types = array(
111 'post',
112 'cngnyc_event',
113 );
114
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
115 // Register the Classes taxonomy
116 $args = array(
117 'label' => 'Classes',
118 'labels' => array(
119 'name' => 'Classes',
120 'singular_name' => 'Class',
121 'search_items' => 'Search Classes',
122 'popular_items' => 'Popular Classes',
123 'all_items' => 'All Classes',
124 'parent_item' => 'Parent Classes',
125 'parent_item_colon' => 'Parent Classes:',
126 'edit_item' => 'Edit Class',
127 'update_item' => 'Update Class',
128 'add_new_item' => 'Add New Class',
129 'new_item_name' => 'New Class',
130 'separate_items_with_commas' => 'Separate classes with commas',
131 'add_or_remove_items' => 'Add or remove classes',
132 'choose_from_most_used' => 'Choose from the most common classes',
133 'menu_name' => 'Classes',
134 ),
b2d0c3d @danielbachhuber Make classes hiearchical
danielbachhuber authored
135 'hierarchical' => true,
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
136 'show_tagcloud' => false,
137 'rewrite' => array(
138 'slug' => 'classes',
139 'hierarchical' => true,
140 ),
141 );
142 register_taxonomy( 'cngnyc_classes', $post_types, $args );
143
52097a8 @danielbachhuber Include places taxonomy
danielbachhuber authored
144 // Register the Places taxonomy
145 $args = array(
146 'label' => 'Places',
147 'labels' => array(
148 'name' => 'Places',
149 'singular_name' => 'Place',
150 'search_items' => 'Search Places',
151 'popular_items' => 'Popular Places',
152 'all_items' => 'All Places',
153 'parent_item' => 'Parent Places',
154 'parent_item_colon' => 'Parent Places:',
155 'edit_item' => 'Edit Place',
156 'update_item' => 'Update Place',
157 'add_new_item' => 'Add New Place',
158 'new_item_name' => 'New Place',
159 'separate_items_with_commas' => 'Separate places with commas',
160 'add_or_remove_items' => 'Add or remove places',
161 'choose_from_most_used' => 'Choose from the most common places',
162 'menu_name' => 'Places',
163 ),
49ad4f2 @danielbachhuber First pass at live events
danielbachhuber authored
164 'hierarchical' => true,
52097a8 @danielbachhuber Include places taxonomy
danielbachhuber authored
165 'show_tagcloud' => false,
166 'rewrite' => array(
167 'slug' => 'places',
168 'hierarchical' => true,
169 ),
170 );
171 register_taxonomy( 'cngnyc_places', $post_types, $args );
172
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
173 // Register the Topics taxonomy
174 $args = array(
175 'label' => 'Topics',
176 'labels' => array(
177 'name' => 'Topics',
178 'singular_name' => 'Topic',
179 'search_items' => 'Search Topics',
180 'popular_items' => 'Popular Topics',
181 'all_items' => 'All Topics',
182 'parent_item' => 'Parent Topics',
183 'parent_item_colon' => 'Parent Topics:',
184 'edit_item' => 'Edit Topic',
185 'update_item' => 'Update Topic',
186 'add_new_item' => 'Add New Topic',
187 'new_item_name' => 'New Topic',
188 'separate_items_with_commas' => 'Separate topics with commas',
189 'add_or_remove_items' => 'Add or remove topics',
190 'choose_from_most_used' => 'Choose from the most common topics',
191 'menu_name' => 'Topics',
192 ),
193 'show_tagcloud' => false,
194 'rewrite' => array(
195 'slug' => 'topics',
196 'hierarchical' => true,
197 ),
198 );
199 register_taxonomy( 'cngnyc_topics', $post_types, $args );
200
e9eee52 @danielbachhuber Themes taxonomy
danielbachhuber authored
201 // Register the Themes taxonomy
202 $args = array(
203 'label' => 'Themes',
204 'labels' => array(
205 'name' => 'Themes',
206 'singular_name' => 'Theme',
207 'search_items' => 'Search Themes',
208 'popular_items' => 'Popular Themes',
209 'all_items' => 'All Themes',
210 'parent_item' => 'Parent Themes',
211 'parent_item_colon' => 'Parent Themes:',
212 'edit_item' => 'Edit Theme',
213 'update_item' => 'Update Theme',
214 'add_new_item' => 'Add New Theme',
215 'new_item_name' => 'New Theme',
216 'separate_items_with_commas' => 'Separate themes with commas',
217 'add_or_remove_items' => 'Add or remove themes',
218 'choose_from_most_used' => 'Choose from the most common themes',
219 'menu_name' => 'Themes',
220 ),
221 'hierarchical' => true,
222 'show_tagcloud' => false,
223 'rewrite' => array(
224 'slug' => 'themes',
225 'hierarchical' => true,
226 ),
227 );
b0f8701 @danielbachhuber First pass at a single page with header
danielbachhuber authored
228 register_taxonomy( 'cngnyc_themes', $post_types, $args );
e9eee52 @danielbachhuber Themes taxonomy
danielbachhuber authored
229
397df4a @danielbachhuber Taxonomy for media types
danielbachhuber authored
230 // Register the Media taxonomy
231 $args = array(
232 'label' => 'Media',
233 'labels' => array(
234 'name' => 'Media',
235 'singular_name' => 'Media',
236 'search_items' => 'Search Media',
237 'popular_items' => 'Popular Media',
238 'all_items' => 'All Media',
239 'parent_item' => 'Parent Media',
240 'parent_item_colon' => 'Parent Media:',
241 'edit_item' => 'Edit Media',
242 'update_item' => 'Update Media',
243 'add_new_item' => 'Add New Media',
244 'new_item_name' => 'New Media',
245 'separate_items_with_commas' => 'Separate media with commas',
246 'add_or_remove_items' => 'Add or remove media',
247 'choose_from_most_used' => 'Choose from the most common media',
248 'menu_name' => 'Media',
249 ),
250 'hierarchical' => true,
251 'show_tagcloud' => false,
252 'rewrite' => array(
253 'slug' => 'media',
254 'hierarchical' => true,
255 ),
256 );
257 register_taxonomy( 'cngnyc_media', $post_types, $args );
258
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
259 } // END create_taxonomies()
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
260
261 /**
262 * register_settings()
263 */
264 function register_settings() {
265
266 register_setting( $this->options_group, $this->options_group_name, array( &$this, 'settings_validate' ) );
267
268 // Global options
269 add_settings_section( 'cngnyc_global', 'Global', array(&$this, 'settings_global_section'), $this->settings_page );
270 add_settings_field( 'project_description', 'Project Description', array(&$this, 'settings_project_description_option'), $this->settings_page, 'cngnyc_global' );
786856e @danielbachhuber New theme option for making an event active
danielbachhuber authored
271 add_settings_field( 'active_event', 'Active Live Coverage', array(&$this, 'settings_active_event_option'), $this->settings_page, 'cngnyc_global' );
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
272
273
274 } // END register_settings()
275
276 /**
277 * settings_project_description_option()
278 */
279 function settings_project_description_option() {
280
7a201c3 @danielbachhuber Make the project description a theme option
danielbachhuber authored
281 $options = $this->options;
282 $allowed_tags = htmlentities( '<b><strong><em><i><span><a><br>' );
283
284 echo '<textarea id="project_description" name="' . $this->options_group_name . '[project_description]" cols="80" rows="6">';
285 if ( isset( $options['project_description'] ) && $options['project_description'] ) {
286 echo $options['project_description'];
287 }
288 echo '</textarea>';
289 echo '<p class="description">The following tags are permitted: ' . $allowed_tags . '</p>';
290
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
291 } // END settings_project_description_option()
786856e @danielbachhuber New theme option for making an event active
danielbachhuber authored
292
293 /**
294 * settings_active_event_option()
295 * Choose whether there's currently an active event
296 */
297 function settings_active_event_option() {
298
299 $options = $this->options;
300 $args = array(
301 'posts_per_page' => '-1',
302 'post_type' => 'cngnyc_event',
303 );
304 $all_events = new WP_Query( $args );
305 echo '<select id="active_event" name="' . $this->options_group_name . '[active_event]">';
306 echo '<option value="0">-- No active event --</option>';
307 if ( $all_events->have_posts() ) {
308 while ( $all_events->have_posts() ) {
309 $all_events->the_post();
310 echo '<option value="' . get_the_id() . '"';
311 if ( get_the_id() == $options['active_event'] ) {
312 echo ' selected="selected"';
313 }
314 echo '>' . get_the_title() . '</option>';
315 }
316 }
317 echo '</select>';
318 echo '<p class="description">Making an event active will add the event to the homepage and an alert message elsewhere</p>';
319
320 } // END settings_active_event_option()
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
321
322 /**
7a201c3 @danielbachhuber Make the project description a theme option
danielbachhuber authored
323 * settings_validate()
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
324 * Validation and sanitization on the settings field
325 */
326 function settings_validate( $input ) {
16da0fa @danielbachhuber Only allow specific tags
danielbachhuber authored
327
328 $allowed_tags = htmlentities( '<b><strong><em><i><span><a><br>' );
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
329
7a201c3 @danielbachhuber Make the project description a theme option
danielbachhuber authored
330 $input['top_announcement'] = strip_tags( $input['top_announcement'], $allowed_tags );
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
331 return $input;
332
7a201c3 @danielbachhuber Make the project description a theme option
danielbachhuber authored
333 } // END settings_validate()
147c19a @danielbachhuber Add a theme options page
danielbachhuber authored
334
335 /**
336 * Options page for the theme
337 */
338 function options_page() {
339 ?>
340 <div class="wrap">
341 <div class="icon32" id="icon-options-general"><br/></div>
342
343 <h2><?php _e('Changing NYC Theme Options', 'cngnyc-theme') ?></h2>
344
345 <form action="options.php" method="post">
346
347 <?php settings_fields( $this->options_group ); ?>
348 <?php do_settings_sections( $this->settings_page ); ?>
349
350 <p class="submit"><input name="submit" type="submit" class="button-primary" value="<?php esc_attr_e('Save Changes'); ?>" /></p>
351
352 </form>
353 </div>
354 <?php
355 }
2a3c0c1 @danielbachhuber Add a Theme Options to the admin bar if user can edit those options
danielbachhuber authored
356
357 /**
358 * add_admin_bar_items()
359 * Custom menu items for the admin bar
360 */
361 function add_admin_bar_items() {
362 global $wp_admin_bar;
363
364 // Add theme management links for users who can
365 if ( current_user_can('edit_theme_options') ) {
366 $args = array(
367 'title' => 'Theme Options',
368 'href' => admin_url( 'themes.php?page=cngnyc_options' ),
369 'parent' => 'appearance',
370 );
371 $wp_admin_bar->add_menu( $args );
372 }
373
374 } // END add_admin_bar_items()
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
375
376 /**
377 * after_setup_theme()
378 */
379 function after_setup_theme() {
380
381 $post_formats = array(
e9eee52 @danielbachhuber Themes taxonomy
danielbachhuber authored
382 'audio',
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
383 'gallery',
3e3d00c @danielbachhuber Add a video format and don't show the featured image
danielbachhuber authored
384 'video',
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
385 );
386 add_theme_support( 'post-formats', $post_formats );
387 add_post_type_support( 'post', 'post-formats' );
388
389 add_theme_support( 'post-thumbnails' );
390
391 } // END after_setup_theme()
392
393
394 } // END class cngnyc
395
396 } // END if ( !class_exists( 'cngnyc' ) )
397
398 global $cngnyc;
399 $cngnyc = new cngnyc();
400
6f6a7bf @danielbachhuber Changing directions
danielbachhuber authored
401 /**
402 * cngnyc_get_term_base()
403 */
404 function cngnyc_get_term_base( $term_object ) {
405
406 if ( !is_object( $term_object ) ) {
407 return false;
408 }
409
410 switch( $term_object->taxonomy ) {
411 case 'cngnyc_classes':
412 return 'classes';
413 break;
414 case 'cngnyc_topics':
415 return 'topics';
416 break;
417 case 'cngnyc_places':
418 return 'places';
419 break;
b0f8701 @danielbachhuber First pass at a single page with header
danielbachhuber authored
420 case 'cngnyc_themes':
421 return 'themes';
422 break;
6f6a7bf @danielbachhuber Changing directions
danielbachhuber authored
423 default:
424 return false;
425 }
426
427 } // END cngnyc_get_term_base()
428
429 /**
0d9b60e @danielbachhuber Dynamically generate
danielbachhuber authored
430 * cngnyc_head_title()
431 * Generate the <title> tag based on context
432 */
433 function cngnyc_head_title() {
434
435 $title = get_bloginfo('name') . ' | ' . get_bloginfo('description');
436
437 if ( is_single() ) {
438 global $post;
439 $title = get_the_title( $post->ID );
440 } else if ( is_tax() ) {
441 $title = single_term_title( false, false ) . ' | ' . get_bloginfo('name');
442 }
443
444 echo '<title>' . $title . '</title>';
445
446 } // END cngnyc_head_title()
447
448 /**
7a201c3 @danielbachhuber Make the project description a theme option
danielbachhuber authored
449 * cngnyc_project_description()
450 * Print the project description
451 */
452 function cngnyc_project_description() {
453 global $cngnyc;
454
455 if ( !empty( $cngnyc->options['project_description'] ) ) {
456 echo $cngnyc->options['project_description'];
457 } else {
458 echo "Please add a project description in theme options.";
459 }
460
461 } // END cngnyc_project_description()
462
463 /**
2548ff0 @danielbachhuber Homepage with an active event
danielbachhuber authored
464 * cngnyc_get_active_event()
465 * Get the active event if there is one
466 *
467 * @param int $post_id Post ID of the active event
468 */
469 function cngnyc_get_active_event() {
470 global $cngnyc;
471
472 return $cngnyc->options['active_event'];
473
474 } // END cngnyc_get_active_event()
475
476 /**
6f6a7bf @danielbachhuber Changing directions
danielbachhuber authored
477 * cngnyc_is_post_term()
478 */
479 function cngnyc_is_post_term( $term_object, $post_terms = array() ) {
480
481 if ( !is_object( $term_object ) || empty( $post_terms ) ) {
482 return false;
483 }
484
485 foreach ( $post_terms as $post_term ) {
b0f8701 @danielbachhuber First pass at a single page with header
danielbachhuber authored
486 if ( $post_term->slug == $term_object->slug && $post_term->taxonomy == $term_object->taxonomy ) {
487 return true;
488 }
489 } // END foreach ( $post_terms as $post_term )
490
491 return false;
6f6a7bf @danielbachhuber Changing directions
danielbachhuber authored
492
493 } // END cngnyc_is_post_term()
494
807f89d @danielbachhuber Steal comments code from TwentyTen. First pass at styling
danielbachhuber authored
495 if ( ! function_exists( 'twentyten_comment' ) ) :
496 /**
497 * Template for comments and pingbacks.
498 *
499 * To override this walker in a child theme without modifying the comments template
500 * simply create your own twentyten_comment(), and that function will be used instead.
501 *
502 * Used as a callback by wp_list_comments() for displaying the comments.
503 *
504 * @since Twenty Ten 1.0
505 */
506 function twentyten_comment( $comment, $args, $depth ) {
507 $GLOBALS['comment'] = $comment;
508 switch ( $comment->comment_type ) :
509 case '' :
510 ?>
511 <li <?php comment_class(); ?> id="li-comment-<?php comment_ID(); ?>">
b2d1d51 @danielbachhuber Style the comments
danielbachhuber authored
512
807f89d @danielbachhuber Steal comments code from TwentyTen. First pass at styling
danielbachhuber authored
513 <div id="comment-<?php comment_ID(); ?>">
b2d1d51 @danielbachhuber Style the comments
danielbachhuber authored
514
515 <div class="comment-meta float-right">
807f89d @danielbachhuber Steal comments code from TwentyTen. First pass at styling
danielbachhuber authored
516 <div class="comment-author vcard">
b2d1d51 @danielbachhuber Style the comments
danielbachhuber authored
517 <div class="avatar float-right">
518 <?php echo get_avatar( $comment, 48 ); ?>
519 </div>
520 <?php comment_author_link(); ?>
807f89d @danielbachhuber Steal comments code from TwentyTen. First pass at styling
danielbachhuber authored
521 </div><!-- .comment-author .vcard -->
522
b2d1d51 @danielbachhuber Style the comments
danielbachhuber authored
523 <div class="commentmetadata"><a href="<?php echo esc_url( get_comment_link( $comment->comment_ID ) ); ?>">
807f89d @danielbachhuber Steal comments code from TwentyTen. First pass at styling
danielbachhuber authored
524 <?php
525 /* translators: 1: date, 2: time */
526 printf( __( '%1$s at %2$s', 'twentyten' ), get_comment_date(), get_comment_time() ); ?></a><?php edit_comment_link( __( '(Edit)', 'twentyten' ), ' ' );
527 ?>
b2d1d51 @danielbachhuber Style the comments
danielbachhuber authored
528 </div><!-- END .commentmetadata -->
529
530 </div><!-- END .comment-meta -->
807f89d @danielbachhuber Steal comments code from TwentyTen. First pass at styling
danielbachhuber authored
531
b2d1d51 @danielbachhuber Style the comments
danielbachhuber authored
532 <div class="comment-body">
533 <?php comment_text(); ?>
534 </div>
535
536 <?php if ( $comment->comment_approved == '0' ) : ?>
537 <p class="awaiting-moderation"><em><?php _e( 'Your comment is awaiting moderation.', 'twentyten' ); ?></em></p>
538 <?php endif; ?>
807f89d @danielbachhuber Steal comments code from TwentyTen. First pass at styling
danielbachhuber authored
539
540 <div class="reply">
541 <?php comment_reply_link( array_merge( $args, array( 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
542 </div><!-- .reply -->
b2d1d51 @danielbachhuber Style the comments
danielbachhuber authored
543
544 <div class="clear-right"></div>
545
807f89d @danielbachhuber Steal comments code from TwentyTen. First pass at styling
danielbachhuber authored
546 </div><!-- #comment-## -->
547
548 <?php
549 break;
550 case 'pingback' :
551 case 'trackback' :
552 ?>
553 <li class="post pingback">
554 <p><?php _e( 'Pingback:', 'twentyten' ); ?> <?php comment_author_link(); ?><?php edit_comment_link( __('(Edit)', 'twentyten'), ' ' ); ?></p>
555 <?php
556 break;
557 endswitch;
558 }
559 endif;
560
45e55e1 @danielbachhuber First pass at functions.php
danielbachhuber authored
561 ?>
Something went wrong with that request. Please try again.