wp-duckbehaviorjournal/functions.php

1244 lines
45 KiB
PHP
Raw Permalink Normal View History

<?php
function duck_behavior_journal_setup()
{
add_theme_support('post-thumbnails');
add_theme_support('title-tag');
register_nav_menus(array(
'primary' => __('Primary Menu', 'duck-behavior-journal'),
'footer' => __('Footer Menu', 'duck-behavior-journal'),
));
add_theme_support('custom-logo');
add_theme_support('custom-header', array(
'default-image' => get_template_directory_uri() . '/assets/img/hero.png',
'width' => 1920,
'height' => 1080,
'flex-height' => true,
'flex-width' => true,
));
add_theme_support('pagination');
}
add_action('after_setup_theme', 'duck_behavior_journal_setup');
function duck_behavior_journal_scripts()
{
wp_enqueue_style('bootstrap-css', get_template_directory_uri() . '/assets/dist/css/bootstrap.min.css');
wp_enqueue_style('mathjax-css', get_template_directory_uri() . '/assets/dist/css/mathjax.css');
wp_enqueue_style('theme-style', get_stylesheet_uri());
wp_enqueue_script('jquery', get_template_directory_uri() . '/assets/dist/js/jquery-3.7.1.min.js', array(), null, true);
wp_enqueue_script('bootstrap-js', get_template_directory_uri() . '/assets/dist/js/bootstrap.bundle.min.js', array(), null, true);
wp_enqueue_script('lightbox', get_template_directory_uri() . '/assets/js/lightbox.js', array(), null, true);
wp_enqueue_script('duckmode', get_template_directory_uri() . '/assets/js/duckmode.js', array(), null, true);
}
add_action('wp_enqueue_scripts', 'duck_behavior_journal_scripts');
require_once get_template_directory() . '/classes/navwalker.php';
function duck_behavior_journal_customizer($wp_customize)
{
// Hero Image Section
$wp_customize->add_section('hero_image_section', array(
'title' => __('Hero Section', 'duck-behavior-journal'),
'priority' => 30,
));
// Hero Image Setting
$wp_customize->add_setting('hero_image', array(
'default' => get_template_directory_uri() . '/assets/img/hero.png',
'transport' => 'refresh',
));
$wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, 'hero_image_control', array(
'label' => __('Hero Image', 'duck-behavior-journal'),
'section' => 'hero_image_section',
'settings' => 'hero_image',
)));
// Hero Title Setting
$wp_customize->add_setting('hero_title', array(
'default' => 'Advancing the Understanding of Duck Behavior',
'transport' => 'refresh',
));
$wp_customize->add_control('hero_title_control', array(
'label' => __('Hero Title', 'duck-behavior-journal'),
'section' => 'hero_image_section',
'settings' => 'hero_title',
'type' => 'text',
));
// Hero Subtitle Setting
$wp_customize->add_setting('hero_subtitle', array(
'default' => 'Through Rigorous Scientific Research',
'transport' => 'refresh',
));
$wp_customize->add_control('hero_subtitle_control', array(
'label' => __('Hero Subtitle', 'duck-behavior-journal'),
'section' => 'hero_image_section',
'settings' => 'hero_subtitle',
'type' => 'text',
));
// Hero Primary Button Text Setting
$wp_customize->add_setting('hero_primary_button_text', array(
'default' => 'Submit Your Research',
'transport' => 'refresh',
));
$wp_customize->add_control('hero_primary_button_text_control', array(
'label' => __('Hero Primary Button Text', 'duck-behavior-journal'),
'section' => 'hero_image_section',
'settings' => 'hero_primary_button_text',
'type' => 'text',
));
// Hero Primary Button URL Setting
$wp_customize->add_setting('hero_primary_button_url', array(
'default' => '#',
'transport' => 'refresh',
));
$wp_customize->add_control('hero_primary_button_url_control', array(
'label' => __('Hero Primary Button URL', 'duck-behavior-journal'),
'section' => 'hero_image_section',
'settings' => 'hero_primary_button_url',
'type' => 'url',
));
// Hero Secondary Button Text Setting
$wp_customize->add_setting('hero_secondary_button_text', array(
'default' => 'Subscribe to the Journal',
'transport' => 'refresh',
));
$wp_customize->add_control('hero_secondary_button_text_control', array(
'label' => __('Hero Secondary Button Text', 'duck-behavior-journal'),
'section' => 'hero_image_section',
'settings' => 'hero_secondary_button_text',
'type' => 'text',
));
// Hero Secondary Button URL Setting
$wp_customize->add_setting('hero_secondary_button_url', array(
'default' => '#',
'transport' => 'refresh',
));
$wp_customize->add_control('hero_secondary_button_url_control', array(
'label' => __('Hero Secondary Button URL', 'duck-behavior-journal'),
'section' => 'hero_image_section',
'settings' => 'hero_secondary_button_url',
'type' => 'url',
));
// Footer Section
$wp_customize->add_section('footer_section', array(
'title' => __('Footer', 'duck-behavior-journal'),
'priority' => 40,
));
// Footer Text Setting
$wp_customize->add_setting('footer_text', array(
'default' => '&copy; ' . date('Y') . ' Duck Behavior Journal. All rights reserved.',
'transport' => 'refresh',
));
$wp_customize->add_control('footer_text_control', array(
'label' => __('Footer Text', 'duck-behavior-journal'),
'section' => 'footer_section',
'settings' => 'footer_text',
'type' => 'textarea',
));
// Footer Social Media Links
$social_media = array('facebook', 'twitter', 'linkedin');
foreach ($social_media as $platform) {
$wp_customize->add_setting("footer_{$platform}_link", array(
'default' => '#',
'transport' => 'refresh',
));
$wp_customize->add_control("footer_{$platform}_link_control", array(
'label' => __(ucfirst($platform) . ' URL', 'duck-behavior-journal'),
'section' => 'footer_section',
'settings' => "footer_{$platform}_link",
'type' => 'url',
));
}
// DOI Prefix Section
$wp_customize->add_section('doi_prefix_section', array(
'title' => __('DOI Prefix', 'duck-behavior-journal'),
'priority' => 50,
));
$wp_customize->add_setting('doi_prefix', array(
'default' => '22.2222/DBJ/',
'transport' => 'refresh',
));
$wp_customize->add_control('doi_prefix_control', array(
'label' => __('DOI Prefix', 'duck-behavior-journal'),
'section' => 'doi_prefix_section',
'settings' => 'doi_prefix',
'type' => 'text',
));
}
add_action('customize_register', 'duck_behavior_journal_customizer');
function create_article_post_type()
{
$labels = array(
'name' => _x('Articles', 'Post type general name', 'duck-behavior-journal'),
'singular_name' => _x('Article', 'Post type singular name', 'duck-behavior-journal'),
'menu_name' => _x('Articles', 'Admin Menu text', 'duck-behavior-journal'),
'name_admin_bar' => _x('Article', 'Add New on Toolbar', 'duck-behavior-journal'),
'add_new' => __('Add New', 'duck-behavior-journal'),
'add_new_item' => __('Add New Article', 'duck-behavior-journal'),
'new_item' => __('New Article', 'duck-behavior-journal'),
'edit_item' => __('Edit Article', 'duck-behavior-journal'),
'view_item' => __('View Article', 'duck-behavior-journal'),
'all_items' => __('All Articles', 'duck-behavior-journal'),
'search_items' => __('Search Articles', 'duck-behavior-journal'),
'parent_item_colon' => __('Parent Articles:', 'duck-behavior-journal'),
'not_found' => __('No articles found.', 'duck-behavior-journal'),
'not_found_in_trash' => __('No articles found in Trash.', 'duck-behavior-journal'),
'featured_image' => _x('Featured Image', 'Overrides the “Featured Image” phrase for this post type. Added in 4.3', 'duck-behavior-journal'),
'set_featured_image' => _x('Set featured image', 'Overrides the “Set featured image” phrase for this post type. Added in 4.3', 'duck-behavior-journal'),
'remove_featured_image' => _x('Remove featured image', 'Overrides the “Remove featured image” phrase for this post type. Added in 4.3', 'duck-behavior-journal'),
'use_featured_image' => _x('Use as featured image', 'Overrides the “Use as featured image” phrase for this post type. Added in 4.3', 'duck-behavior-journal'),
'archives' => _x('Article archives', 'The post type archive label used in nav menus. Default “Post Archives”. Added in 4.4', 'duck-behavior-journal'),
'insert_into_item' => _x('Insert into article', 'Overrides the “Insert into post”/”Insert into page” phrase (used when inserting media into a post). Added in 4.4', 'duck-behavior-journal'),
'uploaded_to_this_item' => _x('Uploaded to this article', 'Overrides the “Uploaded to this post”/”Uploaded to this page” phrase (used when viewing media attached to a post). Added in 4.4', 'duck-behavior-journal'),
'filter_items_list' => _x('Filter articles list', 'Screen reader text for the filter links heading on the post type listing screen. Default “Filter posts list”/”Filter pages list”. Added in 4.4', 'duck-behavior-journal'),
'items_list_navigation' => _x('Articles list navigation', 'Screen reader text for the pagination heading on the post type listing screen. Default “Posts list navigation”/”Pages list navigation”. Added in 4.4', 'duck-behavior-journal'),
'items_list' => _x('Articles list', 'Screen reader text for the items list heading on the post type listing screen. Default “Posts list”/”Pages list”. Added in 4.4', 'duck-behavior-journal'),
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array('slug' => 'article'),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments'),
);
register_post_type('article', $args);
}
add_action('init', 'create_article_post_type');
function create_publication_status_taxonomy()
{
$labels = array(
'name' => _x('Publication Statuses', 'taxonomy general name', 'duck-behavior-journal'),
'singular_name' => _x('Publication Status', 'taxonomy singular name', 'duck-behavior-journal'),
'search_items' => __('Search Publication Statuses', 'duck-behavior-journal'),
'all_items' => __('All Publication Statuses', 'duck-behavior-journal'),
'parent_item' => __('Parent Publication Status', 'duck-behavior-journal'),
'parent_item_colon' => __('Parent Publication Status:', 'duck-behavior-journal'),
'edit_item' => __('Edit Publication Status', 'duck-behavior-journal'),
'update_item' => __('Update Publication Status', 'duck-behavior-journal'),
'add_new_item' => __('Add New Publication Status', 'duck-behavior-journal'),
'new_item_name' => __('New Publication Status Name', 'duck-behavior-journal'),
'menu_name' => __('Publication Status', 'duck-behavior-journal'),
);
$args = array(
'hierarchical' => true,
'labels' => $labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'publication-status'),
);
register_taxonomy('publication_status', array('article'), $args);
}
add_action('init', 'create_publication_status_taxonomy', 0);
// Add color picker to publication status taxonomy
function add_publication_status_color_field($term)
{
$color = get_term_meta($term->term_id, 'publication_status_color', true);
?>
<tr class="form-field">
<th scope="row" valign="top">
<label for="publication_status_color"><?php _e('Color', 'duck-behavior-journal'); ?></label>
</th>
<td>
<input type="text" name="publication_status_color" id="publication_status_color" value="<?php echo esc_attr($color) ? esc_attr($color) : '#ffffff'; ?>" class="color-field" />
<p class="description"><?php _e('Choose a color for this publication status.', 'duck-behavior-journal'); ?></p>
</td>
</tr>
<?php
}
add_action('publication_status_edit_form_fields', 'add_publication_status_color_field', 10, 2);
// Add color picker to add new term screen
function add_publication_status_color_field_new($term)
{
?>
<div class="form-field">
<label for="publication_status_color"><?php _e('Color', 'duck-behavior-journal'); ?></label>
<input type="text" name="publication_status_color" id="publication_status_color" value="#ffffff" class="color-field" />
<p class="description"><?php _e('Choose a color for this publication status.', 'duck-behavior-journal'); ?></p>
</div>
<?php
}
add_action('publication_status_add_form_fields', 'add_publication_status_color_field_new', 10, 2);
// Save the color meta data
function save_publication_status_color_meta($term_id)
{
if (isset($_POST['publication_status_color']) && !empty($_POST['publication_status_color'])) {
update_term_meta($term_id, 'publication_status_color', sanitize_hex_color($_POST['publication_status_color']));
} else {
delete_term_meta($term_id, 'publication_status_color');
}
}
add_action('edited_publication_status', 'save_publication_status_color_meta', 10, 2);
add_action('create_publication_status', 'save_publication_status_color_meta', 10, 2);
// Enqueue the color picker script
function enqueue_color_picker($hook_suffix)
{
// Load only on the term edit page
if (strpos($hook_suffix, 'edit-tags.php') === false) {
return;
}
wp_enqueue_style('wp-color-picker');
wp_enqueue_script('custom-color-picker', get_template_directory_uri() . '/assets/js/custom-color-picker.js', array('wp-color-picker'), false, true);
}
add_action('admin_enqueue_scripts', 'enqueue_color_picker');
function display_publication_status_terms($post_id)
{
$terms = get_the_terms($post_id, 'publication_status');
if (!empty($terms) && !is_wp_error($terms)) {
foreach ($terms as $term) {
$color = get_term_meta($term->term_id, 'publication_status_color', true);
$color_style = $color ? ' style="color:' . esc_attr($color) . ';"' : '';
echo '<span' . $color_style . '>' . esc_html($term->name) . '</span> ';
}
}
}
function add_article_meta_boxes()
{
add_meta_box(
'article_authors',
__('Article Authors', 'duck-behavior-journal'),
'render_article_authors_meta_box',
'article',
'side',
'default'
);
add_meta_box(
'article_doi',
__('Article DOI', 'duck-behavior-journal'),
'render_article_doi_meta_box',
'article',
'side',
'default'
);
add_meta_box(
'article_attachment',
__('File Attachment', 'duck-behavior-journal'),
'render_article_attachment_meta_box',
'article',
'side',
'default'
);
add_meta_box(
'article_open_access',
__('Open Access', 'duck-behavior-journal'),
'render_article_open_access_meta_box',
'article',
'side',
'default'
);
}
add_action('add_meta_boxes', 'add_article_meta_boxes');
function render_article_authors_meta_box($post)
{
$authors = get_post_meta($post->ID, 'article_authors', true);
?>
<div id="article-authors">
<div id="article-authors-list">
<?php
if (!empty($authors)) {
foreach ($authors as $index => $author) {
?>
<p>
<input type="text" name="article_authors[]" value="<?php echo esc_attr($author); ?>" />
<button type="button" class="button remove-author-button" data-index="<?php echo $index; ?>"><?php _e('Remove', 'duck-behavior-journal'); ?></button>
</p>
<?php
}
} else {
?>
<p><input type="text" name="article_authors[]" value="" /></p>
<?php
}
?>
</div>
<button type="button" id="add-author-button" class="button"><?php _e('Add Author', 'duck-behavior-journal'); ?></button>
</div>
<script>
jQuery(document).ready(function($) {
$('#add-author-button').on('click', function() {
$('#article-authors-list').append('<p><input type="text" name="article_authors[]" value="" /><button type="button" class="button remove-author-button"><?php _e('Remove', 'duck-behavior-journal'); ?></button></p>');
});
$(document).on('click', '.remove-author-button', function() {
$(this).parent().remove();
});
});
</script>
<?php
}
function render_article_doi_meta_box($post)
{
$doi = get_post_meta($post->ID, 'article_doi', true);
$doi_prefix = get_theme_mod('doi_prefix', '22.2222/DBJ/');
?>
<div id="article-doi">
<p>
<input type="text" name="article_doi" value="<?php echo esc_attr($doi); ?>" />
<button type="button" id="generate-doi-button" class="button"><?php _e('Generate DOI', 'duck-behavior-journal'); ?></button>
</p>
</div>
<script>
function generateRandomDOI(prefix) {
const randomString = Math.random().toString(36).substring(2, 10);
return prefix + randomString;
}
jQuery(document).ready(function($) {
$('#generate-doi-button').on('click', function() {
const doiPrefix = '<?php echo esc_js($doi_prefix); ?>';
const doi = generateRandomDOI(doiPrefix);
$('input[name="article_doi"]').val(doi);
});
});
</script>
<?php
}
function render_article_attachment_meta_box($post)
{
$attachment_id = get_post_meta($post->ID, 'article_attachment_id', true);
$attachment_url = $attachment_id ? wp_get_attachment_url($attachment_id) : '';
?>
<div id="article-attachment">
<p>
<input type="hidden" name="article_attachment_id" id="article_attachment_id" value="<?php echo esc_attr($attachment_id); ?>" />
<input type="url" name="article_attachment_url" id="article_attachment_url" value="<?php echo esc_url($attachment_url); ?>" readonly />
<button type="button" id="upload-attachment-button" class="button"><?php _e('Upload Attachment', 'duck-behavior-journal'); ?></button>
<button type="button" id="remove-attachment-button" class="button" <?php echo $attachment_id ? '' : 'style="display:none;"'; ?>><?php _e('Remove Attachment', 'duck-behavior-journal'); ?></button>
</p>
</div>
<script>
jQuery(document).ready(function($) {
var file_frame;
$('#upload-attachment-button').on('click', function(event) {
event.preventDefault();
if (file_frame) {
file_frame.open();
return;
}
file_frame = wp.media.frames.file_frame = wp.media({
title: '<?php _e('Select Attachment', 'duck-behavior-journal'); ?>',
button: {
text: '<?php _e('Use this file', 'duck-behavior-journal'); ?>',
},
multiple: false
});
file_frame.on('select', function() {
var attachment = file_frame.state().get('selection').first().toJSON();
$('#article_attachment_id').val(attachment.id);
$('#article_attachment_url').val(attachment.url);
$('#remove-attachment-button').show();
});
file_frame.open();
});
$('#remove-attachment-button').on('click', function(event) {
event.preventDefault();
$('#article_attachment_id').val('');
$('#article_attachment_url').val('');
$(this).hide();
});
});
</script>
<?php
}
function render_article_open_access_meta_box($post)
{
$open_access = get_post_meta($post->ID, 'article_open_access', true);
?>
<div id="article-open-access">
<p>
<label for="article_open_access">
<input type="checkbox" name="article_open_access" id="article_open_access" value="1" <?php checked($open_access, '1'); ?> />
<?php _e('This article is Open Access', 'duck-behavior-journal'); ?>
</label>
</p>
</div>
<?php
}
function add_keywords_meta_box()
{
add_meta_box(
'article_keywords',
__('Article Keywords', 'duck-behavior-journal'),
'render_keywords_meta_box',
'article',
'side',
'default'
);
}
add_action('add_meta_boxes', 'add_keywords_meta_box');
function render_keywords_meta_box($post)
{
$keywords = get_post_meta($post->ID, 'article_keywords', true);
?>
<div id="article-keywords">
<div id="article-keywords-list">
<?php
if (!empty($keywords)) {
foreach ($keywords as $index => $keyword) {
?>
<p>
<input type="text" name="article_keywords[]" value="<?php echo esc_attr($keyword); ?>" />
<button type="button" class="button remove-keyword-button" data-index="<?php echo $index; ?>"><?php _e('Remove', 'duck-behavior-journal'); ?></button>
</p>
<?php
}
} else {
?>
<p><input type="text" name="article_keywords[]" value="" /></p>
<?php
}
?>
</div>
<button type="button" id="add-keyword-button" class="button"><?php _e('Add Keyword', 'duck-behavior-journal'); ?></button>
</div>
<script>
jQuery(document).ready(function($) {
$('#add-keyword-button').on('click', function() {
$('#article-keywords-list').append('<p><input type="text" name="article_keywords[]" value="" /><button type="button" class="button remove-keyword-button"><?php _e('Remove', 'duck-behavior-journal'); ?></button></p>');
});
$(document).on('click', '.remove-keyword-button', function() {
$(this).parent().remove();
});
});
</script>
<?php
}
function save_article_meta_boxes($post_id)
{
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (!isset($_POST['article_authors'])) return;
$authors = array_map('sanitize_text_field', $_POST['article_authors']);
update_post_meta($post_id, 'article_authors', $authors);
if (isset($_POST['article_doi'])) {
$doi = sanitize_text_field($_POST['article_doi']);
update_post_meta($post_id, 'article_doi', $doi);
}
if (isset($_POST['article_attachment_id'])) {
$attachment_id = sanitize_text_field($_POST['article_attachment_id']);
update_post_meta($post_id, 'article_attachment_id', $attachment_id);
}
if (isset($_POST['article_keywords'])) {
$keywords = array_map('sanitize_text_field', $_POST['article_keywords']);
update_post_meta($post_id, 'article_keywords', $keywords);
}
$open_access = isset($_POST['article_open_access']) ? '1' : '0';
update_post_meta($post_id, 'article_open_access', $open_access);
}
add_action('save_post', 'save_article_meta_boxes');
function add_doi_rewrite_rule()
{
add_rewrite_rule('^([0-9]{2})\.([0-9]{4,})/([a-zA-Z0-9_\-\/]+)?$', 'index.php?doi=$matches[1].$matches[2]/$matches[3]', 'top');
}
add_action('init', 'add_doi_rewrite_rule');
function add_doi_query_var($vars)
{
$vars[] = 'doi';
return $vars;
}
add_filter('query_vars', 'add_doi_query_var');
function redirect_doi_to_article($query)
{
if (isset($query->query_vars['doi'])) {
$doi = $query->query_vars['doi'];
$args = array(
'post_type' => 'article',
'meta_query' => array(
array(
'key' => 'article_doi',
'value' => $doi,
'compare' => '='
)
)
);
$articles = new WP_Query($args);
if ($articles->have_posts()) {
$articles->the_post();
wp_redirect(get_permalink(), 301);
exit;
}
}
}
add_action('parse_query', 'redirect_doi_to_article');
function create_letter_post_type()
{
$labels = array(
'name' => _x('Letters to the Editor', 'Post type general name', 'duck-behavior-journal'),
'singular_name' => _x('Letter to the Editor', 'Post type singular name', 'duck-behavior-journal'),
'menu_name' => _x('Letters to the Editor', 'Admin Menu text', 'duck-behavior-journal'),
'name_admin_bar' => _x('Letter to the Editor', 'Add New on Toolbar', 'duck-behavior-journal'),
'add_new' => __('Add New', 'duck-behavior-journal'),
'add_new_item' => __('Add New Letter', 'duck-behavior-journal'),
'new_item' => __('New Letter', 'duck-behavior-journal'),
'edit_item' => __('Edit Letter', 'duck-behavior-journal'),
'view_item' => __('View Letter', 'duck-behavior-journal'),
'all_items' => __('All Letters', 'duck-behavior-journal'),
'search_items' => __('Search Letters', 'duck-behavior-journal'),
'parent_item_colon' => __('Parent Letters:', 'duck-behavior-journal'),
'not_found' => __('No letters found.', 'duck-behavior-journal'),
'not_found_in_trash' => __('No letters found in Trash.', 'duck-behavior-journal'),
'featured_image' => _x('Featured Image', 'Overrides the “Featured Image” phrase for this post type. Added in 4.3', 'duck-behavior-journal'),
'set_featured_image' => _x('Set featured image', 'Overrides the “Set featured image” phrase for this post type. Added in 4.3', 'duck-behavior-journal'),
'remove_featured_image' => _x('Remove featured image', 'Overrides the “Remove featured image” phrase for this post type. Added in 4.3', 'duck-behavior-journal'),
'use_featured_image' => _x('Use as featured image', 'Overrides the “Use as featured image” phrase for this post type. Added in 4.3', 'duck-behavior-journal'),
'archives' => _x('Letter archives', 'The post type archive label used in nav menus. Default “Post Archives”. Added in 4.4', 'duck-behavior-journal'),
'insert_into_item' => _x('Insert into letter', 'Overrides the “Insert into post”/”Insert into page” phrase (used when inserting media into a post). Added in 4.4', 'duck-behavior-journal'),
'uploaded_to_this_item' => _x('Uploaded to this letter', 'Overrides the “Uploaded to this post”/”Uploaded to this page” phrase (used when viewing media attached to a post). Added in 4.4', 'duck-behavior-journal'),
'filter_items_list' => _x('Filter letters list', 'Screen reader text for the filter links heading on the post type listing screen. Default “Filter posts list”/”Filter pages list”. Added in 4.4', 'duck-behavior-journal'),
'items_list_navigation' => _x('Letters list navigation', 'Screen reader text for the pagination heading on the post type listing screen. Default “Posts list navigation”/”Pages list navigation”. Added in 4.4', 'duck-behavior-journal'),
'items_list' => _x('Letters list', 'Screen reader text for the items list heading on the post type listing screen. Default “Posts list”/”Pages list”. Added in 4.4', 'duck-behavior-journal'),
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array('slug' => 'letter'),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'supports' => array('title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments'),
);
register_post_type('letter', $args);
}
add_action('init', 'create_letter_post_type');
function add_letter_meta_boxes()
{
add_meta_box(
'article_authors',
__('Authors', 'duck-behavior-journal'),
'render_article_authors_meta_box',
array('letter'),
'side',
'default'
);
}
add_action('add_meta_boxes', 'add_letter_meta_boxes');
function disable_comments_post_types_support()
{
$post_types = get_post_types();
foreach ($post_types as $post_type) {
if (post_type_supports($post_type, 'comments')) {
remove_post_type_support($post_type, 'comments');
remove_post_type_support($post_type, 'trackbacks');
}
}
}
add_action('admin_init', 'disable_comments_post_types_support');
function disable_comments_status()
{
return false;
}
add_filter('comments_open', 'disable_comments_status', 20, 2);
add_filter('pings_open', 'disable_comments_status', 20, 2);
function disable_comments_hide_existing_comments($comments)
{
$comments = array();
return $comments;
}
add_filter('comments_array', 'disable_comments_hide_existing_comments', 10, 2);
function disable_comments_admin_menu()
{
remove_menu_page('edit-comments.php');
}
add_action('admin_menu', 'disable_comments_admin_menu');
function disable_comments_admin_menu_redirect()
{
global $pagenow;
if ($pagenow === 'edit-comments.php') {
wp_redirect(admin_url());
exit;
}
}
add_action('admin_init', 'disable_comments_admin_menu_redirect');
function disable_comments_dashboard()
{
remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal');
}
add_action('admin_init', 'disable_comments_dashboard');
function disable_comments_admin_bar()
{
if (is_admin_bar_showing()) {
remove_action('admin_bar_menu', 'wp_admin_bar_comments_menu', 60);
}
}
add_action('init', 'disable_comments_admin_bar');
function rename_excerpt_to_abstract($translated)
{
$translated = str_ireplace('Excerpt', 'Abstract', $translated);
return $translated;
}
add_filter('gettext', 'rename_excerpt_to_abstract');
function add_custom_download_endpoint()
{
add_rewrite_rule('^download/([0-9]+)/?', 'index.php?download_file=$matches[1]', 'top');
}
add_action('init', 'add_custom_download_endpoint');
function add_download_query_var($vars)
{
$vars[] = 'download_file';
return $vars;
}
add_filter('query_vars', 'add_download_query_var');
function handle_file_download()
{
$file_id = get_query_var('download_file');
if ($file_id && is_numeric($file_id)) {
if (!is_user_logged_in()) {
wp_redirect(wp_login_url());
exit;
}
$file_path = get_attached_file($file_id);
if (file_exists($file_path)) {
$file_url = wp_get_attachment_url($file_id);
$file_info = pathinfo($file_url);
$file_name = $file_info['basename'];
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file_name));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
exit;
}
}
}
add_action('template_redirect', 'handle_file_download');
function custom_login_logo()
{
$custom_logo_id = get_theme_mod('custom_logo');
$logo_url = wp_get_attachment_image_url($custom_logo_id, 'full');
?>
<style type="text/css">
#login h1 a,
.login h1 a {
background-image: url(<?php echo esc_url($logo_url); ?>);
height: 65px;
width: auto;
background-size: contain;
background-repeat: no-repeat;
padding-bottom: 30px;
}
</style>
<?php
}
add_action('login_enqueue_scripts', 'custom_login_logo');
function custom_login_logo_url()
{
return home_url();
}
add_filter('login_headerurl', 'custom_login_logo_url');
function custom_login_logo_url_title()
{
return get_bloginfo('name');
}
add_filter('login_headertext', 'custom_login_logo_url_title');
// Check if TCPDF is available
function is_tcpdf_available()
{
if (is_autoloader_available()) {
require_once get_template_directory() . '/vendor/autoload.php';
}
return class_exists('TCPDF');
}
// Check if the Composer autoloader is available
function is_autoloader_available()
{
return file_exists(get_template_directory() . '/vendor/autoload.php');
}
// Display admin notice if TCPDF or autoloader is missing
function tcpdf_missing_notice()
{
if (!is_autoloader_available()) {
echo '<div class="notice notice-error"><p>';
_e('Composer autoloader is missing. Please run "composer install" to install the required dependencies.', 'duck-behavior-journal');
echo '</p></div>';
} elseif (!is_tcpdf_available()) {
echo '<div class="notice notice-error"><p>';
_e('TCPDF library is missing. Please install it via Composer to enable the PDF download feature.', 'duck-behavior-journal');
echo '</p></div>';
}
}
add_action('admin_notices', 'tcpdf_missing_notice');
// Add custom endpoint for PDF download
function add_pdf_download_endpoint()
{
add_rewrite_rule('^download-pdf/([0-9]+)/?', 'index.php?download_pdf=$matches[1]', 'top');
}
add_action('init', 'add_pdf_download_endpoint');
// Add query vars for PDF download
function add_pdf_query_vars($vars)
{
$vars[] = 'download_pdf';
return $vars;
}
add_filter('query_vars', 'add_pdf_query_vars');
// Handle PDF download
function handle_pdf_download()
{
if (is_autoloader_available()) {
require_once get_template_directory() . '/vendor/autoload.php';
}
if (is_tcpdf_available()) {
require_once get_template_directory() . '/classes/paperpdf.php';
$post_id = get_query_var('download_pdf');
if ($post_id && is_numeric($post_id)) {
$post = get_post($post_id);
if ($post && $post->post_type == 'article') {
// Create new PDF document
$pdf = new PaperPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// Set document information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor(get_bloginfo('name'));
$pdf->SetTitle($post->post_title);
$pdf->SetSubject('Scientific Paper');
$pdf->SetMargins(PDF_MARGIN_LEFT, 50, PDF_MARGIN_RIGHT);
// Add a page
$pdf->AddPage();
// Set title
$pdf->SetFont('helvetica', 'B', 20);
$pdf->writeHTML('<h1>' . $post->post_title . '</h1>', true, false, false, false, 'C');
// Set authors
$pdf->SetFont('helvetica', '', 12);
$authors = get_post_meta($post_id, 'article_authors', true);
if (!empty($authors)) {
$pdf->Ln(10);
$pdf->writeHTML(implode(',<br/>', array_map('esc_html', $authors)), true, false, false, false, 'C');
}
// Set abstract
if ($post->post_excerpt) {
$pdf->Ln(10);
$pdf->SetFont('helvetica', '', 12);
$pdf->setTextColor(128);
$pdf->writeHTML("<b>Abstract:</b> " . $post->post_excerpt);
}
// Set keywords
$keywords = get_post_meta($post_id, 'article_keywords', true);
if (!empty($keywords)) {
$pdf->Ln(10);
$pdf->SetFont('helvetica', 'I', 12);
$pdf->writeHTML('<b>Keywords:</b> ' . implode(', ', array_map('esc_html', $keywords)));
}
// Set content
$pdf->setTextColor(0);
$pdf->Ln(10);
$pdf->SetFont('helvetica', '', 12);
$content = apply_filters('the_content', $post->post_content);
$mathjax_css = file_get_contents(get_template_directory() . '/assets/dist/css/mathjax.css');
$content = "<style>$mathjax_css</style>$content";
$pdf->writeHTML($content);
// Output PDF document
$pdf->Output(sanitize_title($post->post_title) . '.pdf', 'D');
exit;
}
}
}
}
add_action('template_redirect', 'handle_pdf_download');
function allow_more_uploads($mime_types)
{
$mime_types['py'] = 'text/x-python';
return $mime_types;
}
add_filter('upload_mimes', 'allow_more_uploads');
function disable_real_mime_check($data, $file, $filename, $mimes)
{
$wp_filetype = wp_check_filetype($filename, $mimes);
$ext = $wp_filetype['ext'];
$type = $wp_filetype['type'];
$proper_filename = $data['proper_filename'];
return compact('ext', 'type', 'proper_filename');
}
add_filter('wp_check_filetype_and_ext', 'disable_real_mime_check', 10, 4);
function custom_articles_per_page($query)
{
if (!is_admin() && $query->is_main_query()) {
if (is_post_type_archive('article')) {
$query->set('posts_per_page', 9);
}
}
}
add_action('pre_get_posts', 'custom_articles_per_page');
function mathjax_customizer_settings($wp_customize)
{
// Add a section for MathJax settings
$wp_customize->add_section('mathjax_settings', [
'title' => __('MathJax Settings', 'duck-behavior-journal'),
'priority' => 30,
'description' => __('Specify the URL of your MathJax-node server application. The required server application can be found at <a href="https://git.private.coffee/privatecoffee/mathjax-server" target="_blank">https://git.private.coffee/privatecoffee/mathjax-server</a>.', 'duck-behavior-journal'),
]);
// Add a setting for the MathJax-node server URL
$wp_customize->add_setting('mathjax_server_url', [
'default' => '',
'sanitize_callback' => 'esc_url_raw',
]);
// Add a control for the MathJax-node server URL
$wp_customize->add_control('mathjax_server_url', [
'label' => __('MathJax-node Server URL', 'duck-behavior-journal'),
'section' => 'mathjax_settings',
'type' => 'url',
]);
}
add_action('customize_register', 'mathjax_customizer_settings');
function renderMathJax($latex)
{
$url = get_theme_mod('mathjax_server_url', '');
if (empty($url)) {
return '<span class="error">' . htmlspecialchars($latex) . '</span>';
}
$data = json_encode(['tex' => $latex]);
$options = [
'http' => [
'header' => "Content-Type: application/json\r\n" .
"Content-Length: " . strlen($data) . "\r\n",
'method' => 'POST',
'content' => $data,
],
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) {
return '<span class="error">Error rendering LaTeX</span>';
}
$response = json_decode($result, true);
if (isset($response['error'])) {
return '<span class="error">Error rendering LaTeX: ' . implode(', ', $response['error']) . '</span>';
}
return $response['html'];
}
function convertMathJaxInHTML($html)
{
$url = get_theme_mod('mathjax_server_url', '');
if (empty($url)) {
return $html; // If the URL is not specified, return the original HTML
}
// Use a regular expression to find LaTeX expressions within the HTML
$pattern = '/\$\$(.*?)\$\$/';
$callback = function ($matches) {
$latex = $matches[1];
try {
// Render the LaTeX to HTML using the MathJax-node server
$rendered = renderMathJax($latex);
return $rendered;
} catch (Exception $e) {
// Handle rendering errors
return '<span class="error">' . htmlspecialchars($latex) . '</span>';
}
};
// Replace all LaTeX expressions in the HTML with rendered HTML
$convertedHtml = preg_replace_callback($pattern, $callback, $html);
return $convertedHtml;
}
function preprocess_mathjax_content($content)
{
return convertMathJaxInHTML($content);
}
add_filter('the_content', 'preprocess_mathjax_content');
function customize_register($wp_customize)
{
// Add setting to disable posts
$wp_customize->add_setting('disable_posts', array(
'default' => false,
'transport' => 'refresh',
));
// Add control for the setting
$wp_customize->add_control('disable_posts_control', array(
'label' => __('Disable Post content type', 'duck_behavior_journal'),
'section' => 'title_tagline',
'settings' => 'disable_posts',
'type' => 'checkbox',
));
}
add_action('customize_register', 'customize_register');
function process_unregister_post_type()
{
// Get the customizer setting
$disable_posts = get_theme_mod('disable_posts', false);
// If the setting is enabled, unregister the post type
if ($disable_posts) {
unregister_post_type('post');
}
}
add_action('init', 'process_unregister_post_type', 20);
function remove_post_menu_item()
{
$disable_posts = get_theme_mod('disable_posts', false);
if ($disable_posts) {
remove_menu_page('edit.php');
}
}
add_action('admin_menu', 'remove_post_menu_item');
function exclude_posts_from_queries($query)
{
if (!is_admin() && $query->is_main_query()) {
$disable_posts = get_theme_mod('disable_posts', false);
if ($disable_posts && $query->get('post_type') === 'post') {
$query->set('post_type', 'page');
}
}
}
add_action('pre_get_posts', 'exclude_posts_from_queries');
function remove_posts_from_toolbar($wp_admin_bar)
{
$disable_posts = get_theme_mod('disable_posts', false);
if ($disable_posts) {
$wp_admin_bar->remove_node('new-post');
}
}
add_action('admin_bar_menu', 'remove_posts_from_toolbar', 999);
function duck_behavior_journal_redirect_post_new()
{
global $pagenow;
$disable_posts = get_theme_mod('disable_posts', false);
if ($disable_posts) {
// Check if the current page is 'post-new.php' and 'post_type' parameter is missing
if ($pagenow == 'post-new.php' && !isset($_GET['post_type'])) {
wp_redirect(admin_url('post-new.php?post_type=article'));
exit;
}
}
}
add_action('admin_init', 'duck_behavior_journal_redirect_post_new');
// Add custom columns to the articles admin list view
function add_article_columns($columns)
{
// Add a new column for the lead author
$columns['lead_author'] = __('Lead Author', 'duck-behavior-journal');
// Remove the default author column
unset($columns['author']);
return $columns;
}
add_filter('manage_article_posts_columns', 'add_article_columns');
// Populate the custom columns for articles
function custom_article_column($column, $post_id)
{
if ($column == 'lead_author') {
$authors = get_post_meta($post_id, 'article_authors', true);
if (!empty($authors) && is_array($authors) && !empty($authors[0])) {
echo esc_html($authors[0]);
} else {
echo __('Unknown', 'duck-behavior-journal');
}
}
}
add_action('manage_article_posts_custom_column', 'custom_article_column', 10, 2);
// Add custom columns to the letters admin list view
function add_letter_columns($columns)
{
// Add a new column for the lead author
$columns['lead_author'] = __('Lead Author', 'duck-behavior-journal');
// Remove the default author column
unset($columns['author']);
return $columns;
}
add_filter('manage_letter_posts_columns', 'add_letter_columns');
// Populate the custom columns for letters
function custom_letter_column($column, $post_id)
{
if ($column == 'lead_author') {
$authors = get_post_meta($post_id, 'article_authors', true);
if (!empty($authors) && is_array($authors) && !empty($authors[0])) {
echo esc_html($authors[0]);
} else {
echo __('Unknown', 'duck-behavior-journal');
}
}
}
add_action('manage_letter_posts_custom_column', 'custom_letter_column', 10, 2);