introduce
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
/**
|
||||
* Theme Customizer Core
|
||||
*
|
||||
* @package zeitfresser
|
||||
*/
|
||||
|
||||
function zeitfresser_customize_register( $wp_customize ) {
|
||||
|
||||
// Live Preview support
|
||||
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
|
||||
|
||||
if ( isset( $wp_customize->selective_refresh ) ) {
|
||||
$wp_customize->selective_refresh->add_partial(
|
||||
'blogname',
|
||||
array(
|
||||
'selector' => '.site-title a',
|
||||
'render_callback' => 'zeitfresser_customize_partial_blogname',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->selective_refresh->add_partial(
|
||||
'blogdescription',
|
||||
array(
|
||||
'selector' => '.site-description',
|
||||
'render_callback' => 'zeitfresser_customize_partial_blogdescription',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performance Tools Section
|
||||
*/
|
||||
$wp_customize->add_section(
|
||||
'ztfr_performance_tools',
|
||||
array(
|
||||
'title' => 'Performance Tools Settings',
|
||||
'priority' => 160,
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Auto Optimize
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'ztfr_auto_optimize',
|
||||
array(
|
||||
'default' => true,
|
||||
'sanitize_callback' => 'wp_validate_boolean',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'ztfr_auto_optimize',
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'section' => 'ztfr_performance_tools',
|
||||
'label' => 'Auto Optimize Pictures on Upload',
|
||||
'description' => 'Automatically converts images to AVIF/WebP.',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Auto Delete
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'ztfr_auto_delete',
|
||||
array(
|
||||
'default' => false,
|
||||
'sanitize_callback' => 'wp_validate_boolean',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'ztfr_auto_delete',
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'section' => 'ztfr_performance_tools',
|
||||
'label' => 'Auto Delete Original Pictures',
|
||||
'description' => 'Deletes originals after optimization.',
|
||||
)
|
||||
);
|
||||
}
|
||||
add_action( 'customize_register', 'zeitfresser_customize_register' );
|
||||
|
||||
/**
|
||||
* Partial refresh helpers
|
||||
*/
|
||||
function zeitfresser_customize_partial_blogname() {
|
||||
bloginfo( 'name' );
|
||||
}
|
||||
|
||||
function zeitfresser_customize_partial_blogdescription() {
|
||||
bloginfo( 'description' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Live preview JS
|
||||
*/
|
||||
function zeitfresser_customize_preview_js() {
|
||||
wp_enqueue_script(
|
||||
'zeitfresser-customizer',
|
||||
get_template_directory_uri() . '/js/customizer.js',
|
||||
array( 'customize-preview' ),
|
||||
ZEITFRESSER_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
add_action( 'customize_preview_init', 'zeitfresser_customize_preview_js' );
|
||||
|
||||
/**
|
||||
* Dependency UI logic
|
||||
*/
|
||||
function zeitfresser_customize_controls_dependency_js() {
|
||||
?>
|
||||
<script>
|
||||
(function() {
|
||||
|
||||
function getOptimizeInput() {
|
||||
return document.querySelector('#customize-control-ztfr_auto_optimize input');
|
||||
}
|
||||
|
||||
function getDeleteInput() {
|
||||
return document.querySelector('#customize-control-ztfr_auto_delete input');
|
||||
}
|
||||
|
||||
function getDeleteControl() {
|
||||
return document.getElementById('customize-control-ztfr_auto_delete');
|
||||
}
|
||||
|
||||
function ensureStatusBox() {
|
||||
|
||||
let box = document.getElementById('ztfr-auto-status-box');
|
||||
|
||||
if (box) return box;
|
||||
|
||||
const optimizeControl = document.getElementById('customize-control-ztfr_auto_optimize');
|
||||
|
||||
if (!optimizeControl || !optimizeControl.parentNode) return null;
|
||||
|
||||
box = document.createElement('li');
|
||||
box.id = 'ztfr-auto-status-box';
|
||||
box.className = 'customize-control';
|
||||
box.innerHTML =
|
||||
'<span style="display:block;font-weight:600;margin-bottom:6px;">Current Mode</span>' +
|
||||
'<span id="ztfr-auto-status-text">Checking...</span>';
|
||||
|
||||
optimizeControl.parentNode.insertBefore(box, optimizeControl);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
function updateState() {
|
||||
const optimizeInput = getOptimizeInput();
|
||||
const deleteInput = getDeleteInput();
|
||||
const deleteControl = getDeleteControl();
|
||||
const statusBox = ensureStatusBox();
|
||||
const statusText = document.getElementById('ztfr-auto-status-text');
|
||||
|
||||
if (!optimizeInput || !deleteInput || !deleteControl || !statusBox || !statusText) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!optimizeInput.checked) {
|
||||
deleteInput.checked = false;
|
||||
deleteInput.disabled = true;
|
||||
deleteControl.style.opacity = '0.5';
|
||||
statusText.textContent = '⚪ Manual Mode (no automation)';
|
||||
} else {
|
||||
deleteInput.disabled = false;
|
||||
deleteControl.style.opacity = '1';
|
||||
|
||||
if (deleteInput.checked) {
|
||||
statusText.textContent = '🟢 Full Auto Mode (optimize + delete)';
|
||||
} else {
|
||||
statusText.textContent = '🟡 Auto Optimize enabled (originals kept)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
let attempts = 0;
|
||||
|
||||
function tryInit() {
|
||||
const optimize = getOptimizeInput();
|
||||
const del = getDeleteInput();
|
||||
|
||||
if (optimize && del) {
|
||||
updateState();
|
||||
return;
|
||||
}
|
||||
|
||||
// Retry max 10x
|
||||
if (attempts < 10) {
|
||||
attempts++;
|
||||
setTimeout(tryInit, 200);
|
||||
}
|
||||
}
|
||||
|
||||
tryInit();
|
||||
|
||||
document.addEventListener('change', function(e) {
|
||||
if (
|
||||
e.target &&
|
||||
(
|
||||
e.target.matches('#customize-control-ztfr_auto_optimize input') ||
|
||||
e.target.matches('#customize-control-ztfr_auto_delete input')
|
||||
)
|
||||
) {
|
||||
updateState();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
add_action( 'customize_controls_enqueue_scripts', 'zeitfresser_customize_controls_dependency_js' );
|
||||
|
||||
/**
|
||||
* Small UI polish
|
||||
*/
|
||||
add_action( 'customize_controls_enqueue_scripts', function() {
|
||||
?>
|
||||
<style>
|
||||
#customize-control-ztfr_auto_optimize > label,
|
||||
#customize-control-ztfr_auto_delete > label {
|
||||
display:flex;
|
||||
align-items:flex-start;
|
||||
gap:6px;
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* General Theme Options
|
||||
*
|
||||
* @package zeitfresser
|
||||
*/
|
||||
|
||||
add_action( 'customize_register', 'zeitfresser_general_options' );
|
||||
|
||||
function zeitfresser_general_options( $wp_customize ) {
|
||||
|
||||
/**
|
||||
* General Section (falls nicht schon vorhanden)
|
||||
*/
|
||||
if ( ! $wp_customize->get_section( 'ztfr_general' ) ) {
|
||||
$wp_customize->add_section(
|
||||
'ztfr_general',
|
||||
array(
|
||||
'title' => 'General Options',
|
||||
'priority' => 30,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Excerpt Length
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'post_snippet_excerpt_size',
|
||||
array(
|
||||
'default' => 20,
|
||||
'sanitize_callback' => 'absint',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'post_snippet_excerpt_size',
|
||||
array(
|
||||
'type' => 'number',
|
||||
'section' => 'ztfr_general',
|
||||
'label' => 'Excerpt Length (Post Cards)',
|
||||
'description' => 'Number of words shown in post previews.',
|
||||
'input_attrs' => array(
|
||||
'min' => 5,
|
||||
'max' => 100,
|
||||
'step' => 1,
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Show Site Title
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'show_hide_site_title',
|
||||
array(
|
||||
'default' => true,
|
||||
'sanitize_callback' => 'wp_validate_boolean',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'show_hide_site_title',
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'section' => 'ztfr_general',
|
||||
'label' => 'Show Site Title',
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Show Tagline
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'show_hide_site_tagline',
|
||||
array(
|
||||
'default' => true,
|
||||
'sanitize_callback' => 'wp_validate_boolean',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'show_hide_site_tagline',
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'section' => 'ztfr_general',
|
||||
'label' => 'Show Tagline',
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Layout / Container Settings
|
||||
*
|
||||
* @package zeitfresser
|
||||
*/
|
||||
|
||||
add_action( 'customize_register', 'zeitfresser_layout_options' );
|
||||
|
||||
function zeitfresser_layout_options( $wp_customize ) {
|
||||
|
||||
/**
|
||||
* Container Width
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'container_width',
|
||||
array(
|
||||
'default' => 1400,
|
||||
'sanitize_callback' => 'absint',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'container_width',
|
||||
array(
|
||||
'type' => 'number',
|
||||
'section' => 'ztfr_general',
|
||||
'label' => esc_html__( 'Container Width', 'zeitfresser' ),
|
||||
'description' => esc_html__( 'Maximum width of the content container in pixels.', 'zeitfresser' ),
|
||||
'priority' => 10,
|
||||
'input_attrs' => array(
|
||||
'min' => 800,
|
||||
'max' => 2000,
|
||||
'step' => 10,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply container width via CSS variable
|
||||
*/
|
||||
add_action( 'wp_head', 'zeitfresser_container_width_dynamic_css' );
|
||||
|
||||
function zeitfresser_container_width_dynamic_css() {
|
||||
|
||||
$container_width = (int) get_theme_mod( 'container_width' );
|
||||
|
||||
if ( $container_width <= 0 ) {
|
||||
$container_width = 1140;
|
||||
}
|
||||
|
||||
echo '<style>:root{--container-width:' . esc_attr( $container_width ) . 'px;}</style>';
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* Social Links Customizer Options
|
||||
*
|
||||
* @package zeitfresser
|
||||
*/
|
||||
|
||||
if ( ! function_exists( 'zeitfresser_get_social_links' ) ) {
|
||||
/**
|
||||
* Return supported social networks.
|
||||
*
|
||||
* @return array<string,string>
|
||||
*/
|
||||
function zeitfresser_get_social_links() {
|
||||
return array(
|
||||
'facebook' => esc_html__( 'Facebook', 'zeitfresser' ),
|
||||
'instagram' => esc_html__( 'Instagram', 'zeitfresser' ),
|
||||
'youtube' => esc_html__( 'YouTube', 'zeitfresser' ),
|
||||
'linkedin' => esc_html__( 'LinkedIn', 'zeitfresser' ),
|
||||
'twitter' => esc_html__( 'Twitter', 'zeitfresser' ),
|
||||
'pinterest' => esc_html__( 'Pinterest', 'zeitfresser' ),
|
||||
'tiktok' => esc_html__( 'TikTok', 'zeitfresser' ),
|
||||
'mastodon' => esc_html__( 'Mastodon', 'zeitfresser' ),
|
||||
'github' => esc_html__( 'GitHub', 'zeitfresser' ),
|
||||
'matrix' => esc_html__( 'Matrix.org', 'zeitfresser' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'customize_register', 'zeitfresser_social_links' );
|
||||
|
||||
function zeitfresser_social_links( $wp_customize ) {
|
||||
|
||||
$social_links = zeitfresser_get_social_links();
|
||||
|
||||
/**
|
||||
* Section Divider
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'ztfr_social_heading',
|
||||
array(
|
||||
'sanitize_callback' => 'wp_kses_post',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'ztfr_social_heading',
|
||||
array(
|
||||
'section' => 'ztfr_general',
|
||||
'type' => 'hidden',
|
||||
'description' => '<hr><strong>' . esc_html__( 'Social Links', 'zeitfresser' ) . '</strong>',
|
||||
'priority' => 30,
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Social URLs
|
||||
*/
|
||||
$priority = 31;
|
||||
|
||||
foreach ( $social_links as $key => $label ) {
|
||||
|
||||
$wp_customize->add_setting(
|
||||
'social_links_' . $key,
|
||||
array(
|
||||
'default' => '',
|
||||
'sanitize_callback' => 'esc_url_raw',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'social_links_' . $key,
|
||||
array(
|
||||
'type' => 'url',
|
||||
'section' => 'ztfr_general',
|
||||
'label' => $label,
|
||||
'priority' => $priority++,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* TOC Customizer Options
|
||||
*
|
||||
* @package zeitfresser
|
||||
*/
|
||||
|
||||
add_action( 'customize_register', 'zeitfresser_toc_options' );
|
||||
|
||||
function zeitfresser_toc_options( $wp_customize ) {
|
||||
|
||||
/**
|
||||
* Section Divider (UI only)
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'ztfr_toc_heading',
|
||||
array(
|
||||
'sanitize_callback' => 'wp_kses_post',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'ztfr_toc_heading',
|
||||
array(
|
||||
'section' => 'ztfr_general',
|
||||
'type' => 'hidden',
|
||||
'description' => '<hr><strong>' . esc_html__( 'Article TOC', 'zeitfresser' ) . '</strong>',
|
||||
'priority' => 20,
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Toggle TOC
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'show_article_toc',
|
||||
array(
|
||||
'default' => true,
|
||||
'sanitize_callback' => 'wp_validate_boolean',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'show_article_toc',
|
||||
array(
|
||||
'type' => 'checkbox',
|
||||
'section' => 'ztfr_general',
|
||||
'label' => esc_html__( 'Show Article TOC', 'zeitfresser' ),
|
||||
'description' => esc_html__( 'Enable floating TOC on single posts.', 'zeitfresser' ),
|
||||
'priority' => 21,
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Minimum headlines threshold
|
||||
*/
|
||||
$wp_customize->add_setting(
|
||||
'article_toc_min_headlines',
|
||||
array(
|
||||
'default' => 3,
|
||||
'sanitize_callback' => 'absint',
|
||||
)
|
||||
);
|
||||
|
||||
$wp_customize->add_control(
|
||||
'article_toc_min_headlines',
|
||||
array(
|
||||
'type' => 'number',
|
||||
'section' => 'ztfr_general',
|
||||
'label' => esc_html__( 'Minimum Headlines for TOC', 'zeitfresser' ),
|
||||
'description' => esc_html__( 'TOC appears only if this number of headings is reached.', 'zeitfresser' ),
|
||||
'priority' => 22,
|
||||
'input_attrs' => array(
|
||||
'min' => 1,
|
||||
'max' => 50,
|
||||
'step' => 1,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user