current_time( 'mysql', 1 ), 'last_update_version' => '', 'last_update_nag' => current_time( 'mysql', 1 ), 'last_update_notes' => '', 'last_version_download_url' => '', 'setup' => 0, 'version' => CHILD_VERSION ); update_option( 'fcnmm_theme_info', $info, 'yes' ); } // Merge with defaults (in case of incomplete data) $info = array_merge( array( 'last_update_check' => current_time( 'mysql', 1 ), 'last_update_version' => '', 'last_update_nag' => '', 'last_update_notes' => '', 'last_version_download_url' => '', 'setup' => 0, 'version' => CHILD_VERSION ), $info ); // Return info return $info; } /** * Check Github repository for a new release of the child theme * * 1.0.0 * * @return boolean True if there is a newer version, false if not. */ function fcnmm_check_for_updates() { global $pagenow; // Setup $theme_info = fcnmm_get_theme_info(); $last_check_timestamp = strtotime( $theme_info['last_update_check'] ?? 0 ); $remote_version = $theme_info['last_update_version']; $is_updates_page = $pagenow === 'update-core.php'; // Only call API every n seconds, otherwise check database if ( ( ! $is_updates_page && current_time( 'timestamp', true ) < $last_check_timestamp + FCNMM_UPDATE_CHECK_TIMEOUT ) || ( $_GET['action'] ?? 0 ) === 'do-plugin-upgrade' ) { if ( ! $remote_version ) { return false; } return version_compare( $remote_version, CHILD_RELEASE_TAG, '>' ); } // Remember this check $theme_info['last_update_check'] = current_time( 'mysql', 1 ); // Request to repository $response = wp_remote_get( 'https://api.github.com/repos/Tetrakern/fictioneer-minimalist/releases/latest', array( 'headers' => array( 'User-Agent' => 'FICTIONEER-MINIMALIST', 'Accept' => 'application/vnd.github+json', 'X-GitHub-Api-Version' => '2022-11-28' ) ) ); // Abort if request failed or is not a 2xx success status code if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) >= 300 ) { // Remember check to avoid continuous tries on each page load update_option( 'fcnmm_theme_info', $theme_info ); return false; } // Decode JSON to array $release = json_decode( wp_remote_retrieve_body( $response ), true ); $release_tag = sanitize_text_field( $release['tag_name'] ?? '' ); // Abort if request did not return expected data if ( ! $release_tag ) { return false; } // Add to theme info $theme_info['last_update_version'] = $release_tag; $theme_info['last_update_notes'] = sanitize_textarea_field( $release['body'] ?? '' ); $theme_info['last_update_nag'] = ''; // Reset if ( ( $release['assets'] ?? 0 ) && function_exists( 'fictioneer_sanitize_url' ) ) { $theme_info['last_version_download_url'] = fictioneer_sanitize_url( $release['assets'][0]['browser_download_url'] ?? '' ); } else { $theme_info['last_version_download_url'] = ''; } // Update info in database update_option( 'fcnmm_theme_info', $theme_info ); // Compare with currently installed version return version_compare( $release_tag, CHILD_RELEASE_TAG, '>' ); } /** * Show notice when a newer version of the child theme is available * * @since 1.0.0 */ function fcnmm_admin_update_notice() { // Guard if ( ! current_user_can( 'install_themes' ) || ( $_GET['action'] ?? 0 ) === 'upload-theme' || ! fcnmm_check_for_updates() ) { return; } global $pagenow; // Setup $theme_info = fcnmm_get_theme_info(); $last_update_nag = strtotime( $theme_info['last_update_nag'] ?? 0 ); $is_updates_page = $pagenow == 'update-core.php'; // Show only once every n seconds if ( ! $is_updates_page && current_time( 'timestamp', true ) < $last_update_nag + 60 ) { return; } // Render notice if ( function_exists( 'fictioneer_prepare_release_notes' ) ) { $notes = fictioneer_prepare_release_notes( $theme_info['last_update_notes'] ?? '' ); } else { $notes = sanitize_textarea_field( $theme_info['last_update_notes'] ?? '' ); } wp_admin_notice( sprintf( __( 'Fictioneer Minimalist %1$s is available. Please download and install the latest version at your next convenience.%3$s', 'fcnmm' ), $theme_info['last_update_version'], 'https://github.com/Tetrakern/fictioneer-minimalist/releases', $notes ? '
' . __( 'Release Notes', 'fcnmm' ) . '' . $notes . '
' : '' ), array( 'type' => 'warning', 'dismissible' => true, 'additional_classes' => ['fictioneer-update-notice'] ) ); // Remember notice $theme_info['last_update_nag'] = current_time( 'mysql', 1 ); // Update info in database update_option( 'fcnmm_theme_info', $theme_info ); } add_action( 'admin_notices', 'fcnmm_admin_update_notice' ); // ============================================================================= // CUSTOMIZER // ============================================================================= /** * Modify the theme customizer * * @since 1.0.0 * * @param WP_Customize_Manager $manager The customizer instance. */ function fcnmm_modify_customizers( $manager ) { // Site width $manager->add_setting( 'site_width', array( 'capability' => 'edit_theme_options', 'sanitize_callback' => 'absint', 'default' => 896 ) ); $manager->add_control( 'site_width', array( 'type' => 'number', 'priority' => 2, 'section' => 'layout', 'label' => __( 'Site Width', 'fictioneer' ), 'description' => __( 'Maximum site width in pixels, should not be less than 832. Default 896.', 'fcnmm' ), 'input_attrs' => array( 'placeholder' => '896', 'min' => 832, 'style' => 'width: 80px' ) ) ); // Header tagline color fictioneer_add_color_theme_option( $manager, array( 'section' => 'dark_mode_colors', 'setting' => 'dark_header_tagline_color', 'label' => __( 'Dark Header Tagline', 'fictioneer' ), 'priority' => 7, 'default' => '#9097a7' ) ); // Remove controls $manager->remove_control( 'inset_header_image' ); $manager->remove_control( 'header_style' ); $manager->remove_control( 'title_text_shadow' ); $manager->remove_control( 'header_post_content_id' ); $manager->remove_control( 'header_height_min' ); $manager->remove_control( 'header_height_max' ); $manager->remove_control( 'page_style' ); $manager->remove_control( 'page_shadow' ); } add_action( 'customize_register', 'fcnmm_modify_customizers', 99 ); /** * Always sets inset_header_image to true * * @since 1.0.0 * * @param string $mod Value of the theme mod. * * @return string Updated value of the theme mod. */ function fcnmm_modify_inset_header_image( $mod ) { return true; } add_filter( 'theme_mod_inset_header_image', 'fcnmm_modify_inset_header_image' ); /** * Overrides default cover position on story pages * * @since 1.0.0 * * @param string $mod Value of the theme mod. * * @return string Updated value of the theme mod. */ function fcnmm_modify_story_cover_position_fix_default( $mod ) { if ( ! $mod || $mod === 'top-left-overflow' ) { return 'float-top-left'; } return $mod; } add_filter( 'theme_mod_story_cover_position', 'fcnmm_modify_story_cover_position_fix_default' ); /** * Changes default cover position in the Customizer * * @since 1.0.0 * * @param string $default Default value * * @return string Changed default value. */ function fcnmm_change_story_cover_position_default( $default ) { return 'float-top-left'; } add_filter( 'fictioneer_filter_customizer_story_cover_position_default', 'fcnmm_change_story_cover_position_default' ); /** * Removes top-left-overflow story cover position option * * @since 1.0.0 * * @param array $options Customizer options for the story cover position. * * @return array Updated options. */ function fcnmm_modify_story_cover_position_options( $options ) { unset( $options['top-left-overflow'] ); $options['float-top-left'] = _x( 'Floating Top-Left (Default)', 'Customizer story cover position option.', 'fcnmm' ); return $options; } add_filter( 'fictioneer_filter_customizer_story_cover_position', 'fcnmm_modify_story_cover_position_options' ); // ============================================================================= // SITE HEADER & NAVIGATION // ============================================================================= /** * Outputs the HTML for the child theme header * * @since 1.0.0 * * @param int|null $args['post_id'] Optional. Current post ID. * @param int|null $args['story_id'] Optional. Current story ID (if chapter). * @param string|boolean $args['header_image_url'] URL of the filtered header image or false. * @param array $args['header_args'] Arguments passed to the header.php partial. */ function fcnmm_header( $args ) { // Return early if... if ( $args['header_args']['blank'] ?? 0 ) { return; } // Setup $home_url = home_url(); $title = get_bloginfo( 'name' ); $tagline = get_bloginfo( 'description' ); $title_tag = is_front_page() ? 'h1' : 'h3'; $sub_tag = is_front_page() ? 'h2' : 'h4'; $classes = []; // CSS classes if ( ! display_header_text() || empty( $title ) ) { $classes[] = '_no-title'; } if ( empty( $tagline ) ) { $classes[] = '_no-tagline'; } if ( ! has_custom_logo() ) { $classes[] = '_no-logo'; } // Render Elementor or theme header if ( ! function_exists( 'elementor_theme_do_location' ) || ! elementor_theme_do_location( 'header' ) ) { // Start HTML ---> ?>
{$title}"; } if ( $tagline ) { echo "<{$sub_tag} class='fcnmm-header__tagline'>{$tagline}"; } } ?>
'in-navigation' ) ); ?>
?> 0 ) { $extra_classes[] = '_fading-bottom'; } if ( get_theme_mod( 'header_image_shadow', true ) ) { $extra_classes[] = '_shadow'; } // Start HTML ---> ?>
Header Image