61 Commits

Author SHA1 Message Date
Dome 843d195cc6 Update readme.md 2026-05-08 09:08:44 +02:00
Dome 282523fb9c test 2026-05-08 00:15:04 +02:00
Dome 71db3f5ff2 Merge branch 'main' of https://github.com/Domoel/Zeitfresser-Wordpress-Theme 2026-05-06 18:33:32 +02:00
Dome 03253bed9b Update style.css 2026-05-06 18:33:24 +02:00
Dome 59fcc487bf fixed social icon behavior on mobile 2026-05-06 18:14:04 +02:00
Dome 04d6ba2079 Update style.css 2026-05-06 17:58:48 +02:00
Dome 7c21552f05 apply various design tweaks 2026-05-06 17:57:59 +02:00
Dome 98039df80e Merge branch 'main' of https://github.com/Domoel/Zeitfresser-Wordpress-Theme 2026-05-03 09:27:09 +02:00
Dome db32925598 design tweaking to align certain elements 2026-05-03 09:27:07 +02:00
Dome 74e4b59a31 Update style.css 2026-05-03 01:15:34 +02:00
Dome 0a2bbcbef8 refactor: modularize theme structure and clean up functions.php
- moved performance-related logic into /inc/performance/performance.php
- relocated image optimization logic into dedicated image-optimizer module
- simplified functions.php to act as bootstrap and theme setup only
- introduced consistent module loading via require_once
- improved file structure with clear separation of concerns (customizer, utilities, tools, performance)

theme setup improvements:
- consolidated editor styles setup into zeitfresser_setup()
- removed redundant hooks and improved readability

assets:
- added script dependency (scripts -> navigation) to prevent load order issues
- improved stylesheet dependency handling

result:
- cleaner architecture
- better maintainability and scalability
- reduced risk of side effects during future feature development
2026-05-03 01:07:15 +02:00
Dome 61da5b15e5 fix file conflict 2026-05-03 00:24:39 +02:00
Dome ca7101489a Update code-block.php 2026-05-03 00:23:21 +02:00
Dome eda333d17a feat: add native code block feature and optimize asset loading
- Implemented custom code block system with Prism.js highlighting (YAML)
- Added Gutenberg block with modal editor for better handling of large code snippets
- Added Classic Editor button with dialog for structured code input
- Implemented copy-to-clipboard functionality with hover-based UI
- Introduced dedicated styling (code.css)

Performance improvements:
- Load Prism.js and code block assets only when a code block is present
- Reduced unnecessary JS and CSS on pages without code snippets
- Improved overall frontend performance and resource efficiency

UI/UX improvements:
- Adapted code block styling to match theme design (rectangular layout, accent border, integrated color scheme)
- Refactored sidebar search styling for consistent appearance
- Removed conflicting wrapper borders causing double border rendering
- Applied single-border input pattern with clean focus state
- Fixed invalid CSS !important syntax issues
- Aligned search input design with comments and code block components

Result:
- Cleaner UI with consistent component styling
- Improved performance through conditional asset loading
- Better authoring experience for structured YAML content
2026-05-03 00:22:55 +02:00
Dome 1ee3574d03 load code-block code only if needed 2026-05-02 17:37:19 +02:00
Dome b51ce9ab3f feat: add native code block feature with Prism highlighting and editor integration
- Implemented custom code block system for frontend and editors
- Integrated Prism.js for syntax highlighting (YAML + HTML support)
- Added copy-to-clipboard functionality with hover-based UI
- Introduced custom Gutenberg block for code input
- Added Classic Editor button for quick code insertion
- Implemented server-side rendering via the_content filter
- Added dedicated styling (code.css) with Dracula-inspired theme
- Added editor preview styling (editor.css) for visual consistency
- Ensured accessibility and keyboard support for copy button
- Optimized asset loading and versioning using filemtime()

This feature provides a lightweight, theme-native alternative to external code highlighting plugins.
2026-05-02 15:50:33 +02:00
Dome 3150f4da51 Merge branch 'main' of https://github.com/Domoel/Zeitfresser-Wordpress-Theme 2026-04-30 21:41:30 +02:00
Dome 1020442c06 refactor(inc, image-optimizer): restructure /inc architecture and standardize image optimizer module
- reorganized /inc directory structure for improved separation of concerns
  - grouped files into customizer, utilities, and tools
  - improved naming consistency across files (e.g. *-settings, template-tags, etc.)
  - simplified functions.php includes for better readability and maintainability

- refactored Customizer structure
  - extracted image optimizer settings from core-settings into dedicated module
  - consolidated settings, UI logic, and styles into a single feature file
  - improved naming consistency for hooks and functions

- standardized Image Optimizer admin tool
  - renamed "Performance Tools" to "Image Optimizer" across UI and hooks
  - updated admin page registration, callback names, and menu labels
  - aligned AJAX nonce naming for consistency and clarity

- preserved all existing logic and behavior (no functional changes)
- improved overall code organization and long-term maintainability

no breaking changes
2026-04-30 21:41:19 +02:00
Dome 81ed7efa1a enforce justify via css 2026-04-30 11:44:58 +02:00
Dome 84b2b85bf6 more robust toc scroll 2026-04-30 00:14:19 +02:00
Dome 3bcf9f47fb fixed toc progressbar 2026-04-29 23:23:31 +02:00
Dome 8ec3992945 fixec comment count alignment 2026-04-29 22:35:24 +02:00
Dome cac17ab39d fixed alignment and spacing, and highlight issues 2026-04-29 22:22:05 +02:00
Dome 042547c98f fixed fonts issue 2026-04-29 19:32:01 +02:00
Dome 33df5bbe2e refactor(css): restructure stylesheet, remove duplicates, and improve maintainability
* reorganized CSS into clear sections (Root, Base, Layout, Typography, Components, Utilities)
* removed redundant and duplicate rules (header, branding, search, media, etc.)
* consolidated repeated selectors into single sources of truth
* unified form styles (comments + CF7)
* cleaned up sidebar/widget styles and resolved conflicting rules
* fixed related posts grid issue (min-width: 0 for grid children)
* improved TOC structure and extracted shared calculations
* simplified social links and hover behavior
* removed unsafe global performance hint (will-change)
* added prefers-reduced-motion support for accessibility
* improved overall cascade predictability and reduced specificity conflicts

No visual changes intended (safe refactor).
2026-04-29 19:24:55 +02:00
Dome 798d3f9e1f Delete assets/community-badge.png 2026-04-27 09:24:12 +02:00
Dome d477c95917 Update readme.md 2026-04-27 09:23:44 +02:00
Dome 6bf38ae05d refactor(toc, customizer): improve TOC architecture and reorganize customizer settings
- Reorganized Customizer structure for improved clarity and maintainability
- Introduced consistent default values for all settings to ensure stable fallbacks
  when no user preferences are defined

- Refactored scroll-driven TOC implementation:
  - Optimized scroll handling using requestAnimationFrame
  - Reduced layout thrashing and unnecessary DOM reads
  - Improved heading detection logic (deterministic viewport trigger)
  - Enhanced positioning logic (responsive alignment + sidebar awareness)
  - Improved footer collision handling for more robust layout behavior

- Added optional IntersectionObserver-based TOC implementation:
  - Event-driven alternative to scroll-based approach
  - Currently not enabled by default
  - May not be supported long-term due to less deterministic behavior

- General cleanup and internal consistency improvements

chore: bump version to 2.4.0
2026-04-26 18:48:28 +02:00
Dome 36cad12351 Update style.css 2026-04-26 14:01:12 +02:00
Dome a9f1e799d4 refactor(toc): fix alignment and improve layout responsiveness
- add heuristic sidebar detection
- improve TOC positioning and width calculation
- enhance layout robustness across themes
2026-04-26 14:00:35 +02:00
Dome dbdaaff9f2 Update style.css 2026-04-26 08:44:15 +02:00
Dome 00341252a1 fix(toc): correct floating TOC alignment by resolving wrong sidebar reference
The floating TOC positioning logic assumed a correct sidebar reference
when calculating the horizontal offset. However, the selector used
(`aside, .sidebar, #secondary`) could match non-layout elements such as
hidden containers, mobile sidebars, or unrelated widgets.

This resulted in incorrect `getBoundingClientRect()` values and caused
the TOC to be positioned too far left or right, depending on which
element was matched.

Solution:
- Introduced a `getRealSidebar()` helper to dynamically detect the
  visually relevant sidebar element.
- Filters out non-visible or irrelevant elements based on size.
- Selects the right-most valid candidate, ensuring correct layout context.
- Uses the actual gap between content and sidebar to position the TOC
  symmetrically on the opposite side of the content.

Additional improvements:
- Cached sidebar lookup to avoid repeated DOM queries during scroll.
- Stabilized gap calculation with clamping to prevent layout drift.

Result:
The TOC now consistently aligns with the content column and mirrors
the sidebar spacing correctly across different layouts and breakpoints.
2026-04-26 07:27:52 +02:00
Dome 05de6f2028 fix(toc): restore correct floating TOC positioning after layout refactor
Fix incorrect TOC alignment caused by outdated DOM selector in toc.js.
The content reference element changed during layout refactor, breaking
position calculations for the floating TOC.

Updated contentColumn selector to use .main-wrapper/.container fallback,
ensuring correct left offset and responsive positioning.

Also adds a more robust fallback chain to prevent future regressions
when layout structure changes.
2026-04-26 04:43:04 +02:00
Dome 4408a738ec Update readme.md 2026-04-26 04:17:10 +02:00
Dome e5c716740c Merge branch 'main' of https://github.com/Domoel/Zeitfresser-Wordpress-Theme 2026-04-26 04:06:20 +02:00
Dome 001390457b Sync 2026-04-26 04:06:01 +02:00
Dome f479530c4c Merge branch 'main' of https://github.com/Domoel/Zeitfresser-Wordpress-Theme 2026-04-26 03:57:36 +02:00
Dome e3302b79a3 Update functions.php 2026-04-26 03:57:22 +02:00
Dome 2a28d94b4d introduce 2026-04-26 03:56:28 +02:00
Dome fafc46e007 up version 2026-04-26 03:17:02 +02:00
Dome 9f92958651 refactor(core): introduce modular architecture and restructure theme into clean, maintainable components
This commit introduces a complete internal refactoring of the theme architecture,
transitioning from a monolithic functions.php structure to a modular, scalable system.

### Key Changes

#### 1. Modular Architecture
- Extracted core logic into dedicated modules under `/inc/`
- Introduced clear separation of concerns:
  - `helpers/` → shared utility functions
  - `performance/` → optimization and media processing logic
  - `customizer/` → fully modularized Customizer structure
  - `template-*` → presentation and template-related logic

#### 2. Customizer Refactor
- Replaced legacy monolithic customizer with modular system:
  - `core.php` → base setup
  - `general.php`, `layout.php`, `toc.php`, `social.php` → feature-based modules
- Improved maintainability and extensibility for future settings

#### 3. Performance Layer Separation
- Moved performance-related logic into `/inc/performance/`
- Clearly separated:
  - frontend performance tweaks (scripts, CSS, cleanup)
  - media optimization tools (batch processing, cleanup UI)
- Reduced coupling between UI, logic, and processing

#### 4. Media Optimization Pipeline Stabilization
- Re-aligned upload pipeline with WordPress native flow
- Restored proper use of `wp_generate_attachment_metadata`
- Ensured compatibility with:
  - format conversion (AVIF/WebP)
  - responsive image generation
  - WordPress core image handling

#### 5. Cleaner Hook Management
- Removed duplicated hooks and redundant filters
- Standardized hook priorities and responsibilities
- Ensured consistent use of feature toggles (`get_theme_mod`)

#### 6. Improved Code Quality
- Reduced function duplication
- Standardized naming conventions
- Improved readability and inline documentation
- Removed legacy patterns and implicit dependencies

#### 7. Asset Handling Improvements
- Introduced centralized asset versioning via `filemtime`
- Improved script loading strategy (defer non-critical JS)
- Cleaner enqueue structure for styles and scripts

#### 8. Foundation for Future Development
This refactor lays the groundwork for:
- easier feature expansion
- better testability
- improved debugging capabilities
- long-term maintainability

### Breaking Changes
- Internal file structure has changed significantly
- Direct modifications to old functions.php logic may no longer apply
- Customizer extensions must now hook into modular structure

---

This is a purely structural and architectural release.
No intentional changes to frontend behavior were introduced,
but the internal system is now significantly more robust and maintainable.
2026-04-26 03:16:00 +02:00
Dome 787cdb31aa up version 2026-04-25 15:09:49 +02:00
Dome 7b5bd18dcd fix(performance): correctly disable cleanup button when no actionable items remain
- Fix initial state where cleanup button stayed enabled after full cleanup
- Extend logic to detect "nothing to clean" cases:
  - no optimized images available for cleanup
  - all originals already deleted
- Align PHP initial render logic with runtime JS behavior
- Improve UX consistency between page load and live updates
2026-04-25 15:07:21 +02:00
Dome 937b36b27f up version 2026-04-25 10:22:58 +02:00
Dome 76902390e4 Merge branch 'main' of https://github.com/Domoel/Zeitfresser-Wordpress-Theme 2026-04-25 10:19:45 +02:00
Dome e1f7db91f8 fix(performance): delete all original image subsizes during cleanup
- Extend cleanup logic to remove full original image family (including subsizes)
- Fix issue where only the main original file was deleted
- Ensure consistent behavior for both manual batch processing and auto-delete
- Improve cleanup safety by validating optimization state before deletion
2026-04-25 10:19:33 +02:00
Dome 05c9a70e01 Update readme.md 2026-04-25 02:34:55 +02:00
Dome af8a9447b0 Update customizer.php 2026-04-25 02:26:19 +02:00
Dome b0eb1d9526 feat(performance): introduce image optimization pipeline with optional automation and cleanup
- Add AVIF/WebP conversion for uploads and legacy media
- Implement manual batch optimizer via Performance Tools dashboard
- Introduce automatic optimization toggle via Customizer
- Add optional automatic deletion of original images after optimization
- Ensure safe processing with versioned metadata and idempotent operations
- Decouple manual optimization from automation logic using force flag
- Add live progress UI for optimization and cleanup processes
- Improve UX with status indicators, dependency handling and warnings
2026-04-25 02:18:25 +02:00
Dome c6b0919eb3 Update readme.md 2026-04-23 23:32:07 +02:00
Dome 4f87ca1475 Update readme.md 2026-04-23 23:30:48 +02:00
Dome 271b7fef7f Update readme.md 2026-04-23 23:30:07 +02:00
Dome 32f17f6e9d Update readme.md 2026-04-23 23:29:14 +02:00
Dome a7c71933a8 cleanup fonts.css 2026-04-23 23:15:33 +02:00
Dome a3f69b4118 Update style.css 2026-04-23 21:14:47 +02:00
Dome 84ebfcadf2 Update fonts.css 2026-04-23 21:13:40 +02:00
Dome 5152784a20 feat(typography): migrate from Google Fonts to local font hosting
feat(typography): migrate from Google Fonts to local font hosting

Replaced external Google Fonts integration with locally hosted font files
for Oswald and Roboto.

- Added local @font-face definitions for Oswald (400, 500, 700)
- Added local @font-face definitions for Roboto (400, 500, 700)
- Removed Google Fonts enqueue and external requests
- Implemented unicode-range optimized font loading (latin subset)
- Fixed font file path inconsistencies causing fallback rendering
- Ensured correct font-weight mapping across all variants
- Maintained existing typography system via CSS variables

Result:
- No external font requests (fonts.googleapis.com / fonts.gstatic.com removed)
- Improved performance and privacy (GDPR compliant)
- Consistent rendering with original Google Fonts appearance
- Full control over font loading and optimization
2026-04-23 21:00:32 +02:00
Dome d066342413 Update style.css 2026-04-23 19:28:31 +02:00
Dome eaf31ba27e Update style.css 2026-04-23 18:52:29 +02:00
Dome 0d6ff33a68 functions.php fix 2026-04-23 18:45:30 +02:00
Dome d925911261 refactor(theme): remove dynamic styling systems and migrate to static CSS architecture
This commit introduces a major internal refactor of the theme, replacing all
dynamic styling mechanisms with a fully static, CSS-based system.

The previous implementation relied on WordPress Customizer settings, PHP-based
style generation, and inline CSS injection for fonts, colors, and header behavior.
These systems have been completely removed and replaced with a deterministic
architecture using CSS variables and dedicated stylesheets.

Key changes:
- Removed dynamic font system (Google/local/inline CSS)
- Removed dynamic color system and Customizer controls
- Removed legacy compatibility layer (legacy-aliases.php)
- Removed custom header support and related UI (header image, text color)
- Eliminated inline <style> injection in wp_head
- Introduced static typography system via fonts.css
- Introduced static color system via colors.css
- Refactored style.css to rely entirely on CSS variables
- Cleaned up conflicting font declarations and redundant rules
- Simplified theme structure and reduced PHP overhead
- Aligned translation template with theme slug (zeitfresser.pot)

Result:
- Improved frontend performance and caching behavior
- Reduced PHP execution and complexity
- Fully deterministic rendering without runtime style mutations
- Cleaner, more maintainable codebase

No visual changes intended.
2026-04-23 17:00:13 +02:00
131 changed files with 6396 additions and 39177 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 KiB

+173
View File
@@ -0,0 +1,173 @@
/**
* Code block styles
*
* Frontend and editor preview styles for the Zeitfresser code block feature.
* The selectors are scoped to avoid leaking into unrelated blocks or plugins.
*/
/* -------------------------------------------------------------------------
Code block wrapper
------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------
Code block wrapper
------------------------------------------------------------------------- */
.ztfr-code {
position: relative;
background-color: var(--footer-color);
color: var(--light-color);
padding: 1rem 1.2rem;
margin: 1rem 0;
border-radius: 0;
border: 1px solid rgba(248, 248, 242, 0.08);
border-left: 4px solid var(--hover-color);
max-width: 100%;
overflow-x: auto;
font-family: var(--secondary-font);
font-size: 0.85rem;
line-height: 1.6;
font-weight: 400;
box-shadow: none;
}
/* -------------------------------------------------------------------------
Prism overrides
------------------------------------------------------------------------- */
.ztfr-code pre,
.ztfr-code code {
background: transparent;
color: inherit;
}
.ztfr-code pre[class*="language-"],
.ztfr-code code[class*="language-"] {
background: transparent !important;
padding: 0 !important;
margin: 0 !important;
white-space: pre-wrap !important;
word-break: break-word !important;
overflow-wrap: break-word !important;
}
.ztfr-code pre[class*="language-"] {
overflow-x: visible !important;
}
.ztfr-code pre code {
display: block;
padding: 1rem;
overflow-x: auto;
white-space: pre-wrap;
word-break: break-word;
overflow-wrap: break-word;
}
/* -------------------------------------------------------------------------
Copy button
------------------------------------------------------------------------- */
.ztfr-code__copy {
position: absolute;
top: 0.75rem;
right: 0.75rem;
background-color: var(--footer-color);
color: var(--light-color);
border: 1px solid rgba(248, 248, 242, 0.12);
border-radius: 4px;
font-size: 0.72rem;
line-height: 1;
padding: 0.45rem 0.65rem;
cursor: pointer;
opacity: 0;
pointer-events: none;
transition:
opacity 0.2s ease,
background-color 0.2s ease,
color 0.2s ease,
border-color 0.2s ease;
}
.ztfr-code:hover .ztfr-code__copy {
opacity: 1;
pointer-events: auto;
}
.ztfr-code__copy:hover {
background-color: var(--hover-color);
color: #f8f8f2;
}
.ztfr-code__copy:focus {
opacity: 1;
pointer-events: auto;
outline: 2px solid #bd93f9;
outline-offset: 2px;
}
/* -------------------------------------------------------------------------
Dracula token colors
------------------------------------------------------------------------- */
.ztfr-code .token.comment,
.ztfr-code .token.prolog,
.ztfr-code .token.doctype,
.ztfr-code .token.cdata {
color: #6272a4;
}
.ztfr-code .token.punctuation {
color: #f8f8f2;
}
.ztfr-code .token.tag,
.ztfr-code .token.constant,
.ztfr-code .token.symbol,
.ztfr-code .token.deleted {
color: #ff79c6;
}
.ztfr-code .token.attr-name,
.ztfr-code .token.property,
.ztfr-code .token.selector,
.ztfr-code .token.important,
.ztfr-code .token.atrule {
color: #8be9fd;
}
.ztfr-code .token.attr-value,
.ztfr-code .token.string,
.ztfr-code .token.char,
.ztfr-code .token.inserted {
color: #f1fa8c;
}
.ztfr-code .token.keyword,
.ztfr-code .token.boolean,
.ztfr-code .token.number {
color: #bd93f9;
}
.ztfr-code .token.operator,
.ztfr-code .token.entity,
.ztfr-code .token.url {
color: #f8f8f2;
}
.ztfr-code .token.function,
.ztfr-code .token.class-name {
color: #50fa7b;
}
.block-editor-block-list__layout .ztfr-code,
.editor-styles-wrapper .ztfr-code {
margin: 0;
}
+11
View File
@@ -0,0 +1,11 @@
:root {
--light-color: #f7f7fa;
--dark-color: #1e1f29;
--footer-color: #2f313d;
--hover-color: #bd93f9;
}
body {
background-color: #1e1f29;
}
+116
View File
@@ -0,0 +1,116 @@
/**
* Editor styles
*
* Scoped styles for Gutenberg and Classic Editor.
*/
/* -------------------------------------------------------------------------
Editor base
------------------------------------------------------------------------- */
.editor-styles-wrapper,
.mce-content-body {
font-family: var(--secondary-font);
line-height: 1.7;
}
/* -------------------------------------------------------------------------
Shared code block preview
------------------------------------------------------------------------- */
.editor-styles-wrapper .ztfr-code,
.editor-styles-wrapper pre.language-yaml,
.mce-content-body pre.language-yaml {
position: relative;
background-color: #282a36;
color: #f8f8f2;
border: 1px solid rgba(248, 248, 242, 0.08);
border-radius: 6px;
padding: 1rem 1.2rem;
margin: 1rem 0;
max-width: 100%;
overflow-x: auto;
font-family: var(--secondary-font);
font-size: 0.95rem;
line-height: 1.7;
box-sizing: border-box;
}
/* -------------------------------------------------------------------------
Gutenberg preview
------------------------------------------------------------------------- */
.editor-styles-wrapper .ztfr-code pre,
.editor-styles-wrapper .ztfr-code code {
background: transparent;
color: inherit;
}
.editor-styles-wrapper .ztfr-code pre.language-yaml,
.editor-styles-wrapper .ztfr-code code.language-yaml {
background: transparent !important;
padding: 0 !important;
margin: 0 !important;
white-space: pre-wrap !important;
word-break: break-word !important;
overflow-wrap: break-word !important;
}
.editor-styles-wrapper .ztfr-code pre code {
display: block;
white-space: pre-wrap;
word-break: break-word;
overflow-wrap: break-word;
}
/* -------------------------------------------------------------------------
Classic Editor preview
------------------------------------------------------------------------- */
.mce-content-body pre.language-yaml {
white-space: pre-wrap;
word-break: break-word;
overflow-wrap: break-word;
}
.mce-content-body pre.language-yaml code.language-yaml {
display: block;
background: transparent;
color: inherit;
padding: 0;
margin: 0;
white-space: pre-wrap;
word-break: break-word;
overflow-wrap: break-word;
}
/* -------------------------------------------------------------------------
Editor label
------------------------------------------------------------------------- */
.editor-styles-wrapper .ztfr-code.is-editor-preview::before,
.mce-content-body pre.language-yaml::before {
content: "YAML";
display: inline-block;
margin-bottom: 0.75rem;
padding: 0.2rem 0.45rem;
border-radius: 4px;
background: #44475a;
color: #f8f8f2;
font-size: 0.72rem;
line-height: 1;
letter-spacing: 0.03em;
}
/* -------------------------------------------------------------------------
Lists
------------------------------------------------------------------------- */
.editor-styles-wrapper ul,
.editor-styles-wrapper ol,
.mce-content-body ul,
.mce-content-body ol {
margin-left: 0;
padding-left: 1.25em;
list-style-position: outside;
}
+121
View File
@@ -0,0 +1,121 @@
/* =========================
Local Fonts
========================= */
/* OSWALD */
@font-face {
font-family: 'Oswald';
src: url('../fonts/oswald-400.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Oswald';
src: url('../fonts/oswald-500.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Oswald';
src: url('../fonts/oswald-700.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* ROBOTO */
@font-face {
font-family: 'Roboto';
src: url('../fonts/roboto-400.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/roboto-500.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Roboto';
src: url('../fonts/roboto-700.woff2') format('woff2');
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* =========================
Typography System
========================= */
:root {
--primary-font: 'Oswald', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--secondary-font: 'Roboto', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
--site-identity-font-size: 40px;
--font-weight: 400;
--line-height: 1.6;
}
/* =========================
Base Typography
========================= */
body {
font-family: var(--secondary-font);
font-weight: var(--font-weight);
line-height: var(--line-height);
}
/* =========================
Headlines
========================= */
h1, h2, h3, h4, h5, h6,
.entry-title {
font-family: var(--primary-font);
font-weight: 500;
line-height: 1.3;
}
/* =========================
Site Title
========================= */
.site-title,
.site-title a {
font-family: var(--primary-font);
font-size: var(--site-identity-font-size);
font-weight: 700;
line-height: 1.2;
}
/* =========================
Content Typography
========================= */
.site-description,
.entry-content,
.post-content,
.inner-article-content {
font-family: var(--secondary-font);
}
html {
font-synthesis: none;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

+94
View File
@@ -0,0 +1,94 @@
/**
* Code Block UI Enhancements
*
* Handles:
* - Copy button
* - Prism highlight trigger
*/
(function () {
'use strict';
function copyText(text, onSuccess, onError) {
if (!text) {
return;
}
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(text).then(onSuccess).catch(onError);
return;
}
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', 'readonly');
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
textarea.style.pointerEvents = 'none';
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
document.execCommand('copy');
onSuccess();
} catch (error) {
onError();
}
document.body.removeChild(textarea);
}
function initCodeUI() {
const wrappers = document.querySelectorAll('.ztfr-code');
if (!wrappers.length) {
return;
}
wrappers.forEach(function (wrapper) {
const code = wrapper.querySelector('code');
if (!code) {
return;
}
if (!wrapper.querySelector('.ztfr-code__copy')) {
const button = document.createElement('button');
button.className = 'ztfr-code__copy';
button.type = 'button';
button.setAttribute('aria-label', 'Copy code');
button.textContent = 'Copy';
button.addEventListener('click', function () {
const text = code.textContent;
copyText(
text,
function () {
button.textContent = 'Copied';
window.setTimeout(function () {
button.textContent = 'Copy';
}, 2000);
},
function () {
button.textContent = 'Error';
window.setTimeout(function () {
button.textContent = 'Copy';
}, 2000);
}
);
});
wrapper.appendChild(button);
}
});
if (typeof Prism !== 'undefined') {
Prism.highlightAll();
}
}
document.addEventListener('DOMContentLoaded', initCodeUI);
})();
+219
View File
@@ -0,0 +1,219 @@
(function () {
'use strict';
/**
* Escape HTML before saving it into the code block markup.
*
* @param {string} text Raw code.
* @returns {string} Escaped code.
*/
function escapeHtml(text) {
return String(text)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
/**
* Gutenberg block
*/
if (
window.wp &&
window.wp.blocks &&
window.wp.element &&
window.wp.i18n &&
window.wp.components &&
window.wp.blockEditor
) {
const blocks = window.wp.blocks;
const element = window.wp.element;
const i18n = window.wp.i18n;
const blockEditor = window.wp.blockEditor;
const components = window.wp.components;
const el = element.createElement;
const __ = i18n.__;
const PlainText = blockEditor.PlainText;
const Button = components.Button;
const Modal = components.Modal;
const TextareaControl = components.TextareaControl;
const useState = element.useState;
const useEffect = element.useEffect;
const Fragment = element.Fragment;
function EditCodeBlock(props) {
const content = props.attributes.content || '';
const setAttributes = props.setAttributes;
const state = useState(false);
const isDialogOpen = state[0];
const setDialogOpen = state[1];
function updateCode(value) {
setAttributes({ content: value });
}
useEffect(function () {
if (!isDialogOpen) {
return;
}
window.setTimeout(function () {
const textarea = document.querySelector('.ztfr-code__modal-textarea textarea');
if (textarea) {
textarea.focus();
textarea.setSelectionRange(textarea.value.length, textarea.value.length);
}
}, 50);
}, [isDialogOpen]);
return el(
Fragment,
null,
el(
'div',
{
className: 'ztfr-code is-editor-preview',
'data-language': 'yaml'
},
el(
'div',
{ className: 'ztfr-code__editor-actions' },
el(
Button,
{
variant: 'secondary',
onClick: function () {
setDialogOpen(true);
}
},
__('Edit code', 'zeitfresser')
)
),
el(
'pre',
{ className: 'language-yaml' },
el(PlainText, {
tagName: 'code',
className: 'language-yaml',
value: content,
placeholder: __('Write or paste YAML code here…', 'zeitfresser'),
onChange: updateCode
})
)
),
isDialogOpen &&
el(
Modal,
{
title: __('Edit code block', 'zeitfresser'),
onRequestClose: function () {
setDialogOpen(false);
},
className: 'ztfr-code__modal'
},
el(TextareaControl, {
label: __('Code', 'zeitfresser'),
value: content,
onChange: updateCode,
help: __('Paste your YAML code here. Indentation and line breaks are preserved.', 'zeitfresser'),
rows: 18,
className: 'ztfr-code__modal-textarea'
}),
el(
'div',
{ className: 'ztfr-code__modal-actions' },
el(
Button,
{
variant: 'primary',
onClick: function () {
setDialogOpen(false);
}
},
__('Done', 'zeitfresser')
)
)
)
);
}
blocks.registerBlockType('ztfr/code-block', {
title: __('Code', 'zeitfresser'),
icon: 'editor-code',
category: 'formatting',
description: __('Insert a styled YAML code block.', 'zeitfresser'),
supports: {
html: false
},
attributes: {
content: {
type: 'string',
default: ''
}
},
edit: EditCodeBlock,
save: function (props) {
const content = props.attributes.content || '';
return el(
'pre',
{ className: 'language-yaml' },
el(
'code',
{ className: 'language-yaml' },
content
)
);
}
});
}
/**
* Classic Editor TinyMCE button
*/
if (window.tinymce && window.tinymce.PluginManager) {
window.tinymce.PluginManager.add('ztfr_code_block', function (editor) {
function insertCodeBlockFromDialog() {
editor.windowManager.open({
title: 'Insert code block',
body: [
{
type: 'textbox',
name: 'code',
label: 'Code',
multiline: true,
minWidth: 700,
minHeight: 350,
value: ''
}
],
onsubmit: function (event) {
const code = event.data.code || 'your_key: your_value';
const safeCode = escapeHtml(code);
editor.insertContent(
'<pre class="language-yaml"><code class="language-yaml">' +
safeCode +
'</code></pre><p></p>'
);
editor.focus();
return true;
}
});
}
editor.addButton('ztfr_code_block', {
text: 'Code',
icon: false,
onclick: insertCodeBlockFromDialog
});
});
}
})();
File diff suppressed because one or more lines are too long
@@ -0,0 +1,325 @@
/**
* Floating TOC (Scroll-Driven Implementation)
*
* This implementation uses a scroll-based approach combined with
* requestAnimationFrame to determine the currently active heading.
* The active section is calculated based on a fixed viewport trigger
* (offset from the top), ensuring predictable and stable behavior.
*
* Design Goals:
* - Deterministic highlighting (no competing states)
* - Visual stability (no flickering or race conditions)
* - Theme compatibility (no reliance on experimental APIs)
* - Maintainable and debuggable logic
*
* Characteristics:
* - Uses a cached list of headings for efficient iteration
* - Throttles scroll handling via requestAnimationFrame
* - Minimizes DOM writes and layout recalculations
* - Separates layout (positioning) from state (active link)
*
* Trade-offs:
* - Runs continuously during scroll (minor CPU overhead)
* - Relies on getBoundingClientRect for visibility detection
* - Less "event-driven" than IntersectionObserver-based approaches
*
* Notes:
* This approach was chosen over IntersectionObserver to guarantee
* consistent ordering, eliminate flickering edge cases, and provide
* fully deterministic behavior across all layouts and browsers.
*/
document.addEventListener('DOMContentLoaded', function () {
var toc = document.getElementById('zeitfresser-floating-toc');
var title = document.querySelector(
'.zeitfresser-article-heading .page-title, ' +
'.zeitfresser-article-heading .entry-title, ' +
'.entry-header .entry-title'
);
var progressBar = document.getElementById('zeitfresser-floating-toc-progress');
var nav = toc ? toc.querySelector('.zeitfresser-floating-toc__nav') : null;
if (!toc || !title) {
return;
}
var links = Array.prototype.slice.call(toc.querySelectorAll('a[data-target]'));
var desktopQuery = window.matchMedia('(min-width: 1500px)');
var stickyTop = 100;
var headingOffset = 88;
var ticking = false;
var tocBottomOffset = null;
var cachedSidebar = null;
var headings = getHeadings();
function isDesktop() {
return desktopQuery.matches;
}
function getTarget(link) {
var id = link.getAttribute('data-target');
return id ? document.getElementById(id) : null;
}
function getHeadings() {
return links
.map(function (link) {
return { link: link, target: getTarget(link) };
})
.filter(function (item) {
return !!item.target;
});
}
function getArticleElement() {
return document.querySelector(
'.single-post .post-content article, ' +
'.single-post .post-content, ' +
'article.post, article, ' +
'.entry-content'
);
}
function getTocBottomOffset() {
if (tocBottomOffset !== null) return tocBottomOffset;
var value = getComputedStyle(document.documentElement)
.getPropertyValue('--toc-bottom-offset')
.trim();
tocBottomOffset = parseInt(value, 10) || 12;
return tocBottomOffset;
}
function getRealSidebar() {
if (cachedSidebar) return cachedSidebar;
var candidates = Array.prototype.slice.call(
document.querySelectorAll('aside, .sidebar, #secondary')
);
cachedSidebar = candidates
.filter(function (el) {
var rect = el.getBoundingClientRect();
return rect.width > 200 && rect.height > 200;
})
.sort(function (a, b) {
var rectA = a.getBoundingClientRect();
var rectB = b.getBoundingClientRect();
return rectB.left - rectA.left;
})[0] || null;
return cachedSidebar;
}
function syncPosition() {
if (!isDesktop()) {
document.documentElement.style.setProperty('--zeitfresser-toc-top', stickyTop + 'px');
document.documentElement.style.setProperty('--zeitfresser-toc-left', '24px');
document.documentElement.style.setProperty('--zeitfresser-toc-width', '220px');
return;
}
var scrollTop = window.scrollY || window.pageYOffset || 0;
var titleRect = title.getBoundingClientRect();
// 🔥 bessere Content-Erkennung
var contentColumn =
document.querySelector('.inside-page .main-wrapper > section') ||
document.querySelector('#primary') ||
document.querySelector('.content-area') ||
title;
if (!contentColumn) return;
var sidebar = getRealSidebar();
var contentRect = contentColumn.getBoundingClientRect();
var sidebarRect = sidebar ? sidebar.getBoundingClientRect() : null;
var gap = 48;
if (sidebarRect) {
gap = Math.abs(sidebarRect.left - contentRect.right);
gap = Math.max(32, Math.min(gap, 120));
}
var maxWidth = Math.max(Math.round(contentRect.left - gap - 24), 180);
var tocWidth = Math.max(220, Math.min(260, maxWidth));
var tocLeft = Math.max(
24,
Math.round(contentRect.left - gap - tocWidth)
);
var tocTop = Math.max(
stickyTop,
Math.round(titleRect.top + scrollTop + 14)
);
document.documentElement.style.setProperty('--zeitfresser-toc-top', tocTop + 'px');
document.documentElement.style.setProperty('--zeitfresser-toc-left', tocLeft + 'px');
document.documentElement.style.setProperty('--zeitfresser-toc-width', tocWidth + 'px');
}
function handleFooterCollision() {
if (!isDesktop()) {
toc.style.transform = '';
return;
}
var article = getArticleElement();
if (!article) {
toc.style.transform = '';
return;
}
toc.style.transform = '';
var scrollTop = window.scrollY || window.pageYOffset;
var articleRect = article.getBoundingClientRect();
var articleBottom = articleRect.top + scrollTop + articleRect.height;
var tocRect = toc.getBoundingClientRect();
var tocTop = tocRect.top + scrollTop;
var tocHeight = tocRect.height;
var tocBottom = tocTop + tocHeight;
var offset = getTocBottomOffset();
var maxBottom = articleBottom - offset;
var overflow = Math.ceil(tocBottom - maxBottom);
if (overflow > 0) {
toc.style.transform = 'translateY(-' + overflow + 'px)';
}
}
function setActiveLink(id) {
links.forEach(function (link) {
var active = link.getAttribute('data-target') === id;
link.classList.toggle('is-active', active);
if (active) {
link.setAttribute('aria-current', 'true');
} else {
link.removeAttribute('aria-current');
}
});
}
function updateProgress() {
if (!progressBar) return;
var article = getArticleElement();
if (!article) {
progressBar.style.width = '0%';
return;
}
var rect = article.getBoundingClientRect();
var total = Math.max(
Math.max(article.scrollHeight, article.offsetHeight) - window.innerHeight,
1
);
var progress = Math.min(
Math.max((-rect.top / total) * 100, 0),
100
);
progressBar.style.width = progress + '%';
}
function updateActiveHeading() {
if (!headings.length) return;
var currentId = headings[0].target.id;
var triggerY = headingOffset + 24;
for (var i = 0; i < headings.length; i++) {
var rectTop = headings[i].target.getBoundingClientRect().top;
if (rectTop <= triggerY) {
currentId = headings[i].target.id;
} else {
break;
}
}
setActiveLink(currentId);
}
function onViewportChange() {
if (ticking) return;
ticking = true;
window.requestAnimationFrame(function () {
syncPosition();
handleFooterCollision();
updateProgress();
updateActiveHeading();
ticking = false;
});
}
links.forEach(function (link) {
link.addEventListener('click', function (event) {
var target = getTarget(link);
if (!target) return;
event.preventDefault();
var top =
target.getBoundingClientRect().top +
window.scrollY -
headingOffset;
window.scrollTo({
top: top,
behavior: 'smooth'
});
setActiveLink(target.id);
});
});
if (nav) {
nav.addEventListener(
'wheel',
function (event) {
var canScroll = nav.scrollHeight > nav.clientHeight;
if (!canScroll) return;
var atTop = nav.scrollTop <= 0;
var atBottom =
Math.ceil(nav.scrollTop + nav.clientHeight) >= nav.scrollHeight;
if (
(event.deltaY < 0 && !atTop) ||
(event.deltaY > 0 && !atBottom)
) {
event.preventDefault();
nav.scrollTop += event.deltaY;
}
},
{ passive: false }
);
}
// Initial run
syncPosition();
handleFooterCollision();
updateProgress();
updateActiveHeading();
requestAnimationFrame(function () {
toc.classList.add('is-visible');
});
window.addEventListener('scroll', onViewportChange, { passive: true });
window.addEventListener('resize', onViewportChange, { passive: true });
window.addEventListener('load', function () {
syncPosition();
});
});
+97 -41
View File
@@ -1,3 +1,19 @@
/**
* Floating TOC (IntersectionObserver Version)
*
* This implementation relies on the IntersectionObserver API to detect which
* headings are currently visible in the viewport. It is event-driven and
* more efficient, as updates occur only when visibility changes.
*
* Pros:
* - Lower CPU usage (no continuous polling)
* - Native browser optimization
*
* Cons:
* - Can produce multiple competing active states
* - May require tuning to avoid flickering or reordering
*/
document.addEventListener('DOMContentLoaded', function () {
var toc = document.getElementById('zeitfresser-floating-toc');
var title = document.querySelector('.zeitfresser-article-heading .page-title, .zeitfresser-article-heading .entry-title, .entry-header .entry-title');
@@ -13,7 +29,7 @@ document.addEventListener('DOMContentLoaded', function () {
var stickyTop = 100;
var headingOffset = 88;
var ticking = false;
var cachedSidebar = null;
var tocBottomOffset = null;
function isDesktop() {
@@ -56,6 +72,25 @@ document.addEventListener('DOMContentLoaded', function () {
return tocBottomOffset;
}
function getRealSidebar() {
if (cachedSidebar) return cachedSidebar;
var candidates = Array.prototype.slice.call(
document.querySelectorAll('aside, .sidebar, #secondary')
);
cachedSidebar = candidates
.filter(function (el) {
var rect = el.getBoundingClientRect();
return rect.width > 200 && rect.height > 200;
})
.sort(function (a, b) {
return b.getBoundingClientRect().left - a.getBoundingClientRect().left;
})[0] || null;
return cachedSidebar;
}
function syncPosition() {
if (!isDesktop()) {
document.documentElement.style.setProperty('--zeitfresser-toc-top', stickyTop + 'px');
@@ -64,36 +99,43 @@ document.addEventListener('DOMContentLoaded', function () {
return;
}
var titleRect = title.getBoundingClientRect();
var scrollTop = window.scrollY || window.pageYOffset || 0;
var titleRect = title.getBoundingClientRect();
var contentColumn = document.querySelector(
'.inside-page .main-wrapper > *:first-child, ' +
'.inside-page .main-wrapper .primary-content, ' +
'.inside-page .main-wrapper #primary, ' +
'.inside-page .main-wrapper main'
);
// 🔥 bessere Content-Erkennung
var contentColumn =
document.querySelector('.inside-page .main-wrapper > section') ||
document.querySelector('#primary') ||
document.querySelector('.content-area') ||
title;
var sidebar = document.querySelector(
'.inside-page .main-wrapper > aside, ' +
'.inside-page .main-wrapper .widget-area, ' +
'.inside-page .main-wrapper #secondary, ' +
'.inside-page .main-wrapper .sidebar'
);
if (!contentColumn) return;
var contentRect = contentColumn ? contentColumn.getBoundingClientRect() : titleRect;
var sidebar = getRealSidebar();
var contentRect = contentColumn.getBoundingClientRect();
var sidebarRect = sidebar ? sidebar.getBoundingClientRect() : null;
var mirroredGap = 56;
var gap = 48;
if (sidebarRect) {
mirroredGap = Math.max(Math.round(sidebarRect.left - contentRect.right), 40);
gap = Math.abs(sidebarRect.left - contentRect.right);
gap = Math.max(32, Math.min(gap, 120));
}
var maxWidth = Math.max(Math.round(contentRect.left - mirroredGap - 24), 180);
var tocWidth = Math.max(190, Math.min(250, maxWidth));
var tocLeft = Math.max(24, Math.round(contentRect.left - mirroredGap - tocWidth));
var tocTop = Math.max(stickyTop, Math.round(titleRect.top + scrollTop + 14));
// Toc Content Breite
var maxWidth = Math.max(Math.round(contentRect.left - gap - 24), 180);
var tocWidth = Math.max(220, Math.min(260, maxWidth));
var tocLeft = Math.max(
24,
Math.round(contentRect.left - gap - tocWidth)
);
var tocTop = Math.max(
stickyTop,
Math.round(titleRect.top + scrollTop + 14)
);
document.documentElement.style.setProperty('--zeitfresser-toc-top', tocTop + 'px');
document.documentElement.style.setProperty('--zeitfresser-toc-left', tocLeft + 'px');
@@ -165,22 +207,6 @@ document.addEventListener('DOMContentLoaded', function () {
progressBar.style.width = progress + '%';
}
function updateActiveHeading() {
var headings = getHeadings();
if (!headings.length) return;
var currentId = headings[0].target.id;
var triggerY = headingOffset + 24;
headings.forEach(function (item) {
if (item.target.getBoundingClientRect().top <= triggerY) {
currentId = item.target.id;
}
});
setActiveLink(currentId);
}
function onViewportChange() {
if (ticking) return;
@@ -190,11 +216,43 @@ document.addEventListener('DOMContentLoaded', function () {
syncPosition();
handleFooterCollision();
updateProgress();
updateActiveHeading();
ticking = false;
});
}
// 🔥 NEW: IntersectionObserver for active headings
let currentActiveId = null;
function initIntersectionObserver() {
const headings = getHeadings();
if (!headings.length) return;
const observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
const id = entry.target.id;
if (id !== currentActiveId) {
currentActiveId = id;
setActiveLink(id);
}
}
});
}, {
root: null,
rootMargin: `-${headingOffset}px 0px -70% 0px`,
threshold: 0
});
headings.forEach(function (item) {
if (item.target) {
observer.observe(item.target);
}
});
}
links.forEach(function (link) {
link.addEventListener('click', function (event) {
var target = getTarget(link);
@@ -208,8 +266,6 @@ document.addEventListener('DOMContentLoaded', function () {
top: top,
behavior: 'smooth'
});
setActiveLink(target.id);
});
});
@@ -232,7 +288,7 @@ document.addEventListener('DOMContentLoaded', function () {
syncPosition();
handleFooterCollision();
updateProgress();
updateActiveHeading();
initIntersectionObserver();
requestAnimationFrame(function () {
toc.classList.add('is-visible');
+325
View File
@@ -0,0 +1,325 @@
/**
* Floating TOC (Scroll-Driven Implementation)
*
* This implementation uses a scroll-based approach combined with
* requestAnimationFrame to determine the currently active heading.
* The active section is calculated based on a fixed viewport trigger
* (offset from the top), ensuring predictable and stable behavior.
*
* Design Goals:
* - Deterministic highlighting (no competing states)
* - Visual stability (no flickering or race conditions)
* - Theme compatibility (no reliance on experimental APIs)
* - Maintainable and debuggable logic
*
* Characteristics:
* - Uses a cached list of headings for efficient iteration
* - Throttles scroll handling via requestAnimationFrame
* - Minimizes DOM writes and layout recalculations
* - Separates layout (positioning) from state (active link)
*
* Trade-offs:
* - Runs continuously during scroll (minor CPU overhead)
* - Relies on getBoundingClientRect for visibility detection
* - Less "event-driven" than IntersectionObserver-based approaches
*
* Notes:
* This approach was chosen over IntersectionObserver to guarantee
* consistent ordering, eliminate flickering edge cases, and provide
* fully deterministic behavior across all layouts and browsers.
*/
document.addEventListener('DOMContentLoaded', function () {
var toc = document.getElementById('zeitfresser-floating-toc');
var title = document.querySelector(
'.zeitfresser-article-heading .page-title, ' +
'.zeitfresser-article-heading .entry-title, ' +
'.entry-header .entry-title'
);
var progressBar = document.getElementById('zeitfresser-floating-toc-progress');
var nav = toc ? toc.querySelector('.zeitfresser-floating-toc__nav') : null;
if (!toc || !title) {
return;
}
var links = Array.prototype.slice.call(toc.querySelectorAll('a[data-target]'));
var desktopQuery = window.matchMedia('(min-width: 1500px)');
var stickyTop = 100;
var headingOffset = 88;
var ticking = false;
var tocBottomOffset = null;
var cachedSidebar = null;
var headings = getHeadings();
function isDesktop() {
return desktopQuery.matches;
}
function getTarget(link) {
var id = link.getAttribute('data-target');
return id ? document.getElementById(id) : null;
}
function getHeadings() {
return links
.map(function (link) {
return { link: link, target: getTarget(link) };
})
.filter(function (item) {
return !!item.target;
});
}
function getArticleElement() {
return document.querySelector(
'.single-post .post-content article, ' +
'.single-post .post-content, ' +
'article.post, article, ' +
'.entry-content'
);
}
function getTocBottomOffset() {
if (tocBottomOffset !== null) return tocBottomOffset;
var value = getComputedStyle(document.documentElement)
.getPropertyValue('--toc-bottom-offset')
.trim();
tocBottomOffset = parseInt(value, 10) || 12;
return tocBottomOffset;
}
function getRealSidebar() {
if (cachedSidebar) return cachedSidebar;
var candidates = Array.prototype.slice.call(
document.querySelectorAll('aside, .sidebar, #secondary')
);
cachedSidebar = candidates
.filter(function (el) {
var rect = el.getBoundingClientRect();
return rect.width > 200 && rect.height > 200;
})
.sort(function (a, b) {
var rectA = a.getBoundingClientRect();
var rectB = b.getBoundingClientRect();
return rectB.left - rectA.left;
})[0] || null;
return cachedSidebar;
}
function syncPosition() {
if (!isDesktop()) {
document.documentElement.style.setProperty('--zeitfresser-toc-top', stickyTop + 'px');
document.documentElement.style.setProperty('--zeitfresser-toc-left', '24px');
document.documentElement.style.setProperty('--zeitfresser-toc-width', '220px');
return;
}
var scrollTop = window.scrollY || window.pageYOffset || 0;
var titleRect = title.getBoundingClientRect();
// 🔥 bessere Content-Erkennung
var contentColumn =
document.querySelector('.inside-page .main-wrapper > section') ||
document.querySelector('#primary') ||
document.querySelector('.content-area') ||
title;
if (!contentColumn) return;
var sidebar = getRealSidebar();
var contentRect = contentColumn.getBoundingClientRect();
var sidebarRect = sidebar ? sidebar.getBoundingClientRect() : null;
var gap = 48;
if (sidebarRect) {
gap = Math.abs(sidebarRect.left - contentRect.right);
gap = Math.max(32, Math.min(gap, 120));
}
var maxWidth = Math.max(Math.round(contentRect.left - gap - 24), 180);
var tocWidth = Math.max(220, Math.min(260, maxWidth));
var tocLeft = Math.max(
24,
Math.round(contentRect.left - gap - tocWidth)
);
var tocTop = Math.max(
stickyTop,
Math.round(titleRect.top + scrollTop + 14)
);
document.documentElement.style.setProperty('--zeitfresser-toc-top', tocTop + 'px');
document.documentElement.style.setProperty('--zeitfresser-toc-left', tocLeft + 'px');
document.documentElement.style.setProperty('--zeitfresser-toc-width', tocWidth + 'px');
}
function handleFooterCollision() {
if (!isDesktop()) {
toc.style.transform = '';
return;
}
var article = getArticleElement();
if (!article) {
toc.style.transform = '';
return;
}
toc.style.transform = '';
var scrollTop = window.scrollY || window.pageYOffset;
var articleRect = article.getBoundingClientRect();
var articleBottom = articleRect.top + scrollTop + articleRect.height;
var tocRect = toc.getBoundingClientRect();
var tocTop = tocRect.top + scrollTop;
var tocHeight = tocRect.height;
var tocBottom = tocTop + tocHeight;
var offset = getTocBottomOffset();
var maxBottom = articleBottom - offset;
var overflow = Math.ceil(tocBottom - maxBottom);
if (overflow > 0) {
toc.style.transform = 'translateY(-' + overflow + 'px)';
}
}
function setActiveLink(id) {
links.forEach(function (link) {
var active = link.getAttribute('data-target') === id;
link.classList.toggle('is-active', active);
if (active) {
link.setAttribute('aria-current', 'true');
} else {
link.removeAttribute('aria-current');
}
});
}
function updateProgress() {
if (!progressBar) return;
var article = getArticleElement();
if (!article) {
progressBar.style.width = '0%';
return;
}
var rect = article.getBoundingClientRect();
var total = Math.max(
Math.max(article.scrollHeight, article.offsetHeight) - window.innerHeight,
1
);
var progress = Math.min(
Math.max((-rect.top / total) * 100, 0),
100
);
progressBar.style.width = progress + '%';
}
function updateActiveHeading() {
if (!headings.length) return;
var currentId = headings[0].target.id;
var triggerY = headingOffset + 24;
for (var i = 0; i < headings.length; i++) {
var rectTop = headings[i].target.getBoundingClientRect().top;
if (rectTop <= triggerY) {
currentId = headings[i].target.id;
} else {
break;
}
}
setActiveLink(currentId);
}
function onViewportChange() {
if (ticking) return;
ticking = true;
window.requestAnimationFrame(function () {
syncPosition();
handleFooterCollision();
updateProgress();
updateActiveHeading();
ticking = false;
});
}
links.forEach(function (link) {
link.addEventListener('click', function (event) {
var target = getTarget(link);
if (!target) return;
event.preventDefault();
var top =
target.getBoundingClientRect().top +
window.scrollY -
headingOffset;
window.scrollTo({
top: top,
behavior: 'smooth'
});
setActiveLink(target.id);
});
});
if (nav) {
nav.addEventListener(
'wheel',
function (event) {
var canScroll = nav.scrollHeight > nav.clientHeight;
if (!canScroll) return;
var atTop = nav.scrollTop <= 0;
var atBottom =
Math.ceil(nav.scrollTop + nav.clientHeight) >= nav.scrollHeight;
if (
(event.deltaY < 0 && !atTop) ||
(event.deltaY > 0 && !atBottom)
) {
event.preventDefault();
nav.scrollTop += event.deltaY;
}
},
{ passive: false }
);
}
// Initial run
syncPosition();
handleFooterCollision();
updateProgress();
updateActiveHeading();
requestAnimationFrame(function () {
toc.classList.add('is-visible');
});
window.addEventListener('scroll', onViewportChange, { passive: true });
window.addEventListener('resize', onViewportChange, { passive: true });
window.addEventListener('load', function () {
syncPosition();
});
});
-7
View File
@@ -1,7 +0,0 @@
/* Align lists in the Classic Editor */
ul, ol {
margin-left: 0 !important;
padding-left: 1.0em !important;
list-style-position: inside !important;
}
+4 -1
View File
@@ -5,7 +5,10 @@
* @package zeitfresser
*/
$copyright = get_theme_mod( 'footer_copyright_text', zeitfresser_get_default_footer_copyright() );
$copyright = get_theme_mod(
'footer_copyright_text',
'© ' . date('Y') . ' Zeitfresser'
);
?>
<footer id="colophon" class="site-footer">
+128 -424
View File
@@ -9,33 +9,75 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* ------------------------------------------------------------------------
* Theme Constants
* ------------------------------------------------------------------------
*/
if ( ! defined( 'ZEITFRESSER_VERSION' ) ) {
define( 'ZEITFRESSER_VERSION', '2.3.6' );
}
if ( ! defined( 'DAISY_BLOG_VERSION' ) ) {
define( 'DAISY_BLOG_VERSION', ZEITFRESSER_VERSION );
if ( ! defined( 'ZEITFRESSER_IMAGE_OPTIMIZATION_VERSION' ) ) {
define( 'ZEITFRESSER_IMAGE_OPTIMIZATION_VERSION', '1.0' );
}
require get_template_directory() . '/inc/zeitfresser-helpers.php';
require get_template_directory() . '/inc/legacy-aliases.php';
require get_template_directory() . '/inc/performance-tools.php';
require get_template_directory() . '/inc/zeitfresser-toc.php';
/**
* ------------------------------------------------------------------------
* Customizer
* ------------------------------------------------------------------------
*/
require_once get_template_directory() . '/inc/customizer/core-settings.php';
require_once get_template_directory() . '/inc/customizer/general-settings.php';
require_once get_template_directory() . '/inc/customizer/layout-settings.php';
require_once get_template_directory() . '/inc/customizer/toc-settings.php';
require_once get_template_directory() . '/inc/customizer/social-settings.php';
require_once get_template_directory() . '/inc/customizer/image-optimizer-settings.php';
/**
* Theme setup.
*
* @return void
* ------------------------------------------------------------------------
* Utilities
* ------------------------------------------------------------------------
*/
require_once get_template_directory() . '/inc/utilities/helpers.php';
require_once get_template_directory() . '/inc/utilities/template-tags.php';
require_once get_template_directory() . '/inc/utilities/template-functions.php';
require_once get_template_directory() . '/inc/utilities/pagination.php';
require_once get_template_directory() . '/inc/utilities/toc.php';
/**
* ------------------------------------------------------------------------
* Tools
* ------------------------------------------------------------------------
*/
require_once get_template_directory() . '/inc/tools/image-optimizer.php';
require_once get_template_directory() . '/inc/tools/code-block.php';
/**
* ------------------------------------------------------------------------
* Performance
* ------------------------------------------------------------------------
*/
require_once get_template_directory() . '/inc/performance/performance.php';
/**
* ------------------------------------------------------------------------
* Theme Setup
* ------------------------------------------------------------------------
*/
function zeitfresser_setup() {
load_theme_textdomain( 'zeitfresser', get_template_directory() . '/languages' );
add_theme_support( 'automatic-feed-links' );
add_theme_support( 'title-tag' );
add_theme_support( 'post-thumbnails' );
add_theme_support(
'html5',
array(
// Editor Styles
add_theme_support( 'editor-styles' );
add_editor_style( 'assets/css/editor.css' );
add_theme_support( 'html5', array(
'search-form',
'comment-form',
'comment-list',
@@ -43,46 +85,42 @@ function zeitfresser_setup() {
'caption',
'style',
'script',
)
);
add_theme_support(
'custom-background',
apply_filters(
'zeitfresser_custom_background_args',
array(
'default-image' => '',
'default-color' => zeitfresser_get_default_background_color(),
)
)
);
));
add_theme_support( 'customize-selective-refresh-widgets' );
add_theme_support(
'custom-logo',
array(
add_theme_support( 'custom-logo', array(
'height' => 250,
'width' => 250,
'flex-width' => true,
'flex-height' => true,
)
);
));
add_theme_support( 'align-wide' );
add_theme_support( 'wp-block-styles' );
add_theme_support( 'responsive-embeds' );
register_nav_menus(
array(
register_nav_menus( array(
'menu-1' => esc_html__( 'Primary', 'zeitfresser' ),
)
);
add_editor_style( 'editor-style.css' );
));
}
add_action( 'after_setup_theme', 'zeitfresser_setup' );
/**
* Set the content width in pixels.
*
* @return void
* ------------------------------------------------------------------------
* Image Sizes
* ------------------------------------------------------------------------
*/
function zeitfresser_custom_image_sizes() {
add_image_size( 'zeitfresser-content', 720, 0, false );
add_image_size( 'zeitfresser-card', 480, 0, false );
}
add_action( 'after_setup_theme', 'zeitfresser_custom_image_sizes' );
/**
* ------------------------------------------------------------------------
* Content Width
* ------------------------------------------------------------------------
*/
function zeitfresser_content_width() {
$GLOBALS['content_width'] = apply_filters( 'zeitfresser_content_width', 640 );
@@ -90,13 +128,12 @@ function zeitfresser_content_width() {
add_action( 'after_setup_theme', 'zeitfresser_content_width', 0 );
/**
* Register widget area.
*
* @return void
* ------------------------------------------------------------------------
* Widgets
* ------------------------------------------------------------------------
*/
function zeitfresser_widgets_init() {
register_sidebar(
array(
register_sidebar( array(
'name' => esc_html__( 'Sidebar', 'zeitfresser' ),
'id' => 'sidebar-1',
'description' => esc_html__( 'Add widgets here.', 'zeitfresser' ),
@@ -104,409 +141,76 @@ function zeitfresser_widgets_init() {
'after_widget' => '</section>',
'before_title' => '<h4 class="widget-title">',
'after_title' => '</h4>',
)
);
));
}
add_action( 'widgets_init', 'zeitfresser_widgets_init' );
/**
* Enqueue floating TOC assets on single posts.
*
* @return void
*/
function zeitfresser_enqueue_toc_assets() {
if ( is_singular( 'post' ) && zeitfresser_has_floating_toc() ) {
wp_enqueue_script(
'zeitfresser-toc',
get_template_directory_uri() . '/js/toc.js',
array(),
ZEITFRESSER_VERSION,
true
);
}
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_enqueue_toc_assets', 20 );
/**
* Return file version using filemtime in production-safe form.
*
* @param string $relative_path Relative file path inside the theme.
* @return string
*/
function zeitfresser_asset_version( $relative_path ) {
$path = get_template_directory() . $relative_path;
return file_exists( $path ) ? (string) filemtime( $path ) : ZEITFRESSER_VERSION;
}
/**
* Enqueue scripts and styles.
*
* @return void
* ------------------------------------------------------------------------
* Assets
* ------------------------------------------------------------------------
*/
function zeitfresser_scripts() {
/**
* Base stylesheet
*/
wp_enqueue_style(
'zeitfresser',
get_template_directory_uri() . '/style.css',
array(),
zeitfresser_asset_version( '/style.css' )
[],
file_exists( get_template_directory() . '/style.css' )
? filemtime( get_template_directory() . '/style.css' )
: ZEITFRESSER_VERSION
);
wp_style_add_data( 'zeitfresser', 'rtl', 'replace' );
/**
* Additional styles (versioned helper)
*/
$fonts = zeitfresser_asset_versioned('/css/fonts.css');
$colors = zeitfresser_asset_versioned('/css/colors.css');
wp_enqueue_style(
'zeitfresser-fonts',
$fonts['url'],
['zeitfresser'],
$fonts['version']
);
wp_enqueue_style(
'zeitfresser-colors',
$colors['url'],
['zeitfresser'],
$colors['version']
);
/**
* Scripts
*/
$nav = zeitfresser_asset_versioned('/js/navigation.js');
$scripts = zeitfresser_asset_versioned('/js/scripts.js');
wp_enqueue_script(
'zeitfresser-navigation',
get_template_directory_uri() . '/js/navigation.js',
array(),
zeitfresser_asset_version( '/js/navigation.js' ),
$nav['url'],
[],
$nav['version'],
true
);
if ( is_home() || is_front_page() || is_archive() || is_search() ) {
wp_enqueue_script(
'zeitfresser-masonry',
get_template_directory_uri() . '/js/masonry.pkgd.min.js',
array(),
zeitfresser_asset_version( '/js/masonry.pkgd.min.js' ),
true
);
}
wp_enqueue_script(
'zeitfresser-scripts',
get_template_directory_uri() . '/js/scripts.js',
array(),
zeitfresser_asset_version( '/js/scripts.js' ),
$scripts['url'],
['zeitfresser-navigation'],
$scripts['version'],
true
);
/**
* WordPress native threaded comments
*/
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_scripts' );
/**
* Theme package marker kept for compatibility with the original premium controls.
*
* @return string
*/
function zeitfresser_free_pro() {
return 'pro';
}
require get_template_directory() . '/inc/custom-header.php';
require get_template_directory() . '/inc/template-tags.php';
require get_template_directory() . '/inc/template-functions.php';
require get_template_directory() . '/inc/customizer.php';
if ( defined( 'JETPACK__VERSION' ) ) {
require get_template_directory() . '/inc/jetpack.php';
}
require get_template_directory() . '/inc/blocks/blocks.php';
require get_template_directory() . '/inc/graphthemes-widgets/graphthemes-widgets.php';
require get_template_directory() . '/inc/pagination.php';
/**
* Remove duplicate local Google font generation to avoid unnecessary footer CSS.
*
* @return void
*/
function zeitfresser_disable_duplicate_local_fonts() {
remove_action( 'wp_loaded', 'zeitfresser_google_font_local' );
}
add_action( 'after_setup_theme', 'zeitfresser_disable_duplicate_local_fonts', 20 );
/**
* Add safe front-end performance optimizations.
*
* @return void
*/
function zeitfresser_performance_setup() {
// Disable the legacy embeds script on the front end. Native iframes still work.
if ( ! is_admin() ) {
wp_deregister_script( 'wp-embed' );
}
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_performance_setup', 100 );
/**
* Remove unnecessary head output for a leaner front end.
*
* @return void
*/
function zeitfresser_cleanup_wp_head() {
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
remove_action( 'wp_head', 'rsd_link' );
remove_action( 'wp_head', 'wlwmanifest_link' );
remove_action( 'wp_head', 'wp_generator' );
remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
remove_action( 'wp_head', 'wp_shortlink_wp_head', 10 );
remove_action( 'wp_head', 'wp_oembed_add_discovery_links', 10 );
remove_action( 'wp_head', 'wp_oembed_add_host_js' );
remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 );
}
add_action( 'init', 'zeitfresser_cleanup_wp_head' );
/**
* Remove front-end dashicons for visitors.
*
* @return void
*/
function zeitfresser_maybe_dequeue_dashicons() {
if ( ! is_user_logged_in() ) {
wp_deregister_style( 'dashicons' );
}
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_maybe_dequeue_dashicons', 100 );
/**
* Add resource hints for externally loaded fonts only when needed.
*
* @param array $urls URLs to print for resource hints.
* @param string $relation_type Hint relation type.
* @return array
*/
function zeitfresser_resource_hints( $urls, $relation_type ) {
$uses_external_fonts = false;
if ( function_exists( 'zeitfresser_fonts_url' ) ) {
$uses_external_fonts = ! empty( zeitfresser_fonts_url( zeitfresser_used_google_fonts() ) ) && empty( zeitfresser_get_local_webfonts_css() );
}
if ( $uses_external_fonts && 'preconnect' === $relation_type ) {
$urls[] = 'https://fonts.googleapis.com';
$urls[] = array(
'href' => 'https://fonts.gstatic.com',
'crossorigin' => 'anonymous',
);
}
return $urls;
}
add_filter( 'wp_resource_hints', 'zeitfresser_resource_hints', 10, 2 );
/**
* Preload locally hosted webfont files once they are available.
*
* @return void
*/
function zeitfresser_preload_local_webfonts() {
if ( is_admin() || ! function_exists( 'zeitfresser_get_local_webfonts_css' ) ) {
return;
}
$urls = zeitfresser_get_local_webfont_urls( zeitfresser_get_local_webfonts_css() );
if ( empty( $urls ) ) {
return;
}
$urls = array_slice( $urls, 0, 4 );
foreach ( $urls as $url ) {
$type = ( '.woff2' === substr( $url, -6 ) ) ? 'font/woff2' : 'font/woff';
printf( "<link rel='preload' href='%s' as='font' type='%s' crossorigin>
", esc_url( $url ), esc_attr( $type ) );
}
}
add_action( 'wp_head', 'zeitfresser_preload_local_webfonts', 2 );
/**
* Improve image decoding defaults without changing visual output.
*
* @param array $attr Image markup attributes.
* @param WP_Post $attachment Attachment post object.
* @param string|array $size Requested image size.
* @return array
*/
function zeitfresser_optimize_image_attributes( $attr, $attachment, $size ) {
if ( empty( $attr['decoding'] ) ) {
$attr['decoding'] = 'async';
}
if ( empty( $attr['loading'] ) && ! is_admin() ) {
$attr['loading'] = 'lazy';
}
return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'zeitfresser_optimize_image_attributes', 10, 3 );
/**
* Lower the threshold for WordPress scaled originals.
*
* This prevents very large uploads from shipping oversized source images.
*
* @return int
*/
function zeitfresser_big_image_size_threshold() {
return 1800;
}
add_filter( 'big_image_size_threshold', 'zeitfresser_big_image_size_threshold' );
/**
* Skip generating oversized core intermediate sizes we do not use.
*
* @param array $sizes Registered intermediate sizes.
* @return array
*/
function zeitfresser_filter_intermediate_image_sizes( $sizes ) {
unset( $sizes['1536x1536'], $sizes['2048x2048'] );
return $sizes;
}
add_filter( 'intermediate_image_sizes_advanced', 'zeitfresser_filter_intermediate_image_sizes' );
/**
* Convert generated JPEG and PNG sub-sizes to WebP when supported by the server.
*
* @param array $formats Output format map.
* @return array
*/
function zeitfresser_image_output_format( $formats ) {
if ( function_exists( 'wp_image_editor_supports' ) && wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {
$formats['image/jpeg'] = 'image/webp';
$formats['image/png'] = 'image/webp';
}
return $formats;
}
add_filter( 'image_editor_output_format', 'zeitfresser_image_output_format' );
/**
* Keep generated image quality balanced for file size and visual fidelity.
*
* @param int $quality Proposed image quality.
* @param string $mime_type Image mime type.
* @return int
*/
function zeitfresser_image_quality( $quality, $mime_type = 'image/jpeg' ) {
if ( 'image/png' === $mime_type ) {
return $quality;
}
return 82;
}
add_filter( 'wp_editor_set_quality', 'zeitfresser_image_quality', 10, 2 );
/**
* Improve attachment image attributes for layout stability and fetch priority.
*
* @param array $attr Image markup attributes.
* @param WP_Post $attachment Attachment post object.
* @param string|array $size Requested image size.
* @return array
*/
function zeitfresser_improve_attachment_dimensions( $attr, $attachment, $size ) {
if ( empty( $attr['width'] ) || empty( $attr['height'] ) ) {
$metadata = wp_get_attachment_metadata( $attachment->ID );
if ( is_array( $metadata ) && ! empty( $metadata['width'] ) && ! empty( $metadata['height'] ) ) {
if ( empty( $attr['width'] ) ) {
$attr['width'] = (int) $metadata['width'];
}
if ( empty( $attr['height'] ) ) {
$attr['height'] = (int) $metadata['height'];
}
}
}
if ( empty( $attr['fetchpriority'] ) && ! is_admin() && ! is_feed() ) {
static $did_set_high_priority = false;
if ( ! $did_set_high_priority && ( is_home() || is_front_page() || is_archive() || is_search() || is_singular() ) ) {
$attr['fetchpriority'] = 'high';
$did_set_high_priority = true;
}
}
return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'zeitfresser_improve_attachment_dimensions', 11, 3 );
/**
* Preload the most likely LCP image for archive and singular views.
*
* @param array $resources Existing preload resources.
* @return array
*/
function zeitfresser_preload_resources( $resources ) {
if ( is_admin() || is_feed() || is_embed() ) {
return $resources;
}
$image_url = '';
$image_type = '';
if ( is_singular() ) {
$object_id = get_queried_object_id();
if ( $object_id && has_post_thumbnail( $object_id ) ) {
$image_url = get_the_post_thumbnail_url( $object_id, 'large' );
}
} elseif ( is_home() || is_front_page() || is_archive() || is_search() ) {
global $wp_query;
if ( isset( $wp_query->posts[0]->ID ) && has_post_thumbnail( $wp_query->posts[0]->ID ) ) {
$image_url = get_the_post_thumbnail_url( $wp_query->posts[0]->ID, 'thumbnail' );
}
}
if ( empty( $image_url ) ) {
return $resources;
}
$extension = strtolower( pathinfo( wp_parse_url( $image_url, PHP_URL_PATH ), PATHINFO_EXTENSION ) );
if ( 'jpg' === $extension || 'jpeg' === $extension ) {
$image_type = 'image/jpeg';
} elseif ( 'png' === $extension ) {
$image_type = 'image/png';
} elseif ( 'webp' === $extension ) {
$image_type = 'image/webp';
}
$resources[] = array_filter(
array(
'href' => esc_url( $image_url ),
'as' => 'image',
'type' => $image_type,
'fetchpriority' => 'high',
)
);
return $resources;
}
add_filter( 'wp_preload_resources', 'zeitfresser_preload_resources' );
/**
* Improve script loading strategy for non-critical assets.
*
* @param array $tag Script tag markup.
* @param string $handle Script handle.
* @param string $src Script source URL.
* @return string
*/
function zeitfresser_defer_non_critical_scripts( $tag, $handle, $src ) {
$deferred_handles = array(
'zeitfresser-navigation',
'zeitfresser-masonry',
'zeitfresser-scripts',
);
if ( in_array( $handle, $deferred_handles, true ) && false === strpos( $tag, ' defer' ) ) {
return str_replace( ' src=', ' defer src=', $tag );
}
return $tag;
}
add_filter( 'script_loader_tag', 'zeitfresser_defer_non_critical_scripts', 10, 3 );
add_action( 'wp_enqueue_scripts', 'zeitfresser_scripts', 10 );
+22 -19
View File
@@ -2,13 +2,8 @@
/**
* The header for our theme
*
* This is the template that displays all of the <head> section and everything up until <div id="content">
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package zeitfresser
*/
?>
<!doctype html>
<html <?php language_attributes(); ?>>
@@ -23,46 +18,51 @@
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<a class="skip-link screen-reader-text" href="#primary"><?php esc_html_e( 'Skip to content', 'zeitfresser' ); ?></a>
<a class="skip-link screen-reader-text" href="#primary">
<?php esc_html_e( 'Skip to content', 'zeitfresser' ); ?>
</a>
<header id="masthead" class="site-header">
<div class="header-wrapper">
<div class="container">
<div class="site-header-wrapper">
<div class="site-branding">
<?php the_custom_logo(); ?>
<div class="site-identity">
<?php if( get_theme_mod( 'show_hide_site_title', zeitfresser_get_default_site_title_show_hide() ) ) { ?>
<?php if ( get_theme_mod( 'show_hide_site_title', true ) ) : ?>
<div class="site-title">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"
class="logo"><?php bloginfo( 'name' ); ?></a>
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home" class="logo">
<?php bloginfo( 'name' ); ?>
</a>
</div>
<?php } ?>
<?php endif; ?>
<?php if ( get_theme_mod( 'show_hide_site_tagline', true ) ) : ?>
<div class="site-description">
<?php bloginfo( 'description' ); ?>
</div>
<?php endif; ?>
<?php $daisy_blog_description = get_bloginfo( 'description' ); ?>
<?php if( get_theme_mod( 'show_hide_site_tagline', zeitfresser_get_default_site_tagline_show_hide() ) ) { ?>
<div class="site-description"><?php echo $daisy_blog_description; ?></div>
<?php } ?>
</div>
</div><!-- .site-branding -->
<div class="nav-social-links">
<nav id="site-navigation" class="main-navigation">
<button id="nav-icon3" class="menu-toggle" aria-controls="primary-menu"
aria-expanded="false">
<nav id="site-navigation" class="main-navigation">
<button id="nav-icon3" class="menu-toggle" aria-controls="primary-menu" aria-expanded="false">
<span></span>
<span></span>
<span></span>
<span></span>
</button>
<?php
wp_nav_menu(
array(
@@ -71,11 +71,14 @@
)
);
?>
</nav><!-- #site-navigation -->
</nav>
<?php get_template_part( 'template-parts/social', 'links' ); ?>
</div>
</div>
</div>
</div>
</div>
</header><!-- #masthead -->
-23
View File
@@ -1,23 +0,0 @@
<?php
/**
* Register customizer blocks used by the Zeitfresser theme.
*/
if ( ! defined( 'ZEITFRESSER_BLOCKS_DIR_PATH' ) ) {
define( 'ZEITFRESSER_BLOCKS_DIR_PATH', dirname( __FILE__ ) );
}
if ( ! defined( 'DAISY_BLOG_BLOCKS_DIR_PATH' ) ) {
define( 'DAISY_BLOG_BLOCKS_DIR_PATH', ZEITFRESSER_BLOCKS_DIR_PATH );
}
require dirname( __FILE__ ) . '/includes/sanitize.php';
require dirname( __FILE__ ) . '/includes/register-controls.php';
require dirname( __FILE__ ) . '/site-identity/site-identity.php';
require dirname( __FILE__ ) . '/colors/colors.php';
require dirname( __FILE__ ) . '/font-family/font-family.php';
require dirname( __FILE__ ) . '/font-customization/font-customization.php';
require dirname( __FILE__ ) . '/general/general.php';
require dirname( __FILE__ ) . '/post-detail/post-detail.php';
require dirname( __FILE__ ) . '/footer-copyright/footer-copyright.php';
@@ -1,11 +0,0 @@
<?php
add_action( 'wp_enqueue_scripts', 'zeitfresser_sticky_menu_background_color' );
function zeitfresser_sticky_menu_background_color() {
$bg_color = get_theme_mod( 'background_color', get_theme_support( 'custom-background', 'default-color' ) );
$dynamic_css = "body,.site-header{background:#$bg_color;}";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,25 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_dark_color' );
function zeitfresser_dark_color( $wp_customize ) {
$wp_customize->add_setting( 'dark_color', array(
'default' => zeitfresser_get_default_dark_color(),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color'
) );
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'dark_color', array(
'label' => esc_html__( 'Misc Colors', 'zeitfresser' ),
'section' => 'colors',
'settings' => 'dark_color',
) ) );
}
add_action( 'customize_preview_init', 'zeitfresser_dark_color_enqueue_scripts' );
function zeitfresser_dark_color_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-dark-customizer', get_template_directory_uri() . '/inc/blocks/colors/color-dark/customizer-color-dark.js', array('jquery'), '', true );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('dark_color',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--dark-color', to);
}
);
} );
} );
@@ -1,25 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_grey_color' );
function zeitfresser_grey_color( $wp_customize ) {
$wp_customize->add_setting( 'grey_color', array(
'default' => zeitfresser_get_default_grey_color(),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color'
) );
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'grey_color', array(
'label' => esc_html__( 'Soft Text Color', 'zeitfresser' ),
'section' => 'colors',
'settings' => 'grey_color',
) ) );
}
add_action( 'customize_preview_init', 'zeitfresser_grey_color_enqueue_scripts' );
function zeitfresser_grey_color_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-grey-customizer', get_template_directory_uri() . '/inc/blocks/colors/color-grey/customizer-color-grey.js', array('jquery'), '', true );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('grey_color',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--grey-color', to);
}
);
} );
} );
@@ -1,25 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_light_color' );
function zeitfresser_light_color( $wp_customize ) {
$wp_customize->add_setting( 'light_color', array(
'default' => zeitfresser_get_default_light_color(),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color'
) );
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'light_color', array(
'label' => esc_html__( 'Header Color', 'zeitfresser' ),
'section' => 'colors',
'settings' => 'light_color',
) ) );
}
add_action( 'customize_preview_init', 'zeitfresser_light_color_enqueue_scripts' );
function zeitfresser_light_color_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-light-customizer', get_template_directory_uri() . '/inc/blocks/colors/color-light/customizer-color-light.js', array('jquery'), '', true );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('light_color',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--light-color', to);
}
);
} );
} );
@@ -1,25 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_primary_color' );
function zeitfresser_primary_color( $wp_customize ) {
$wp_customize->add_setting( 'primary_color', array(
'default' => zeitfresser_get_default_primary_color(),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color'
) );
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'primary_color', array(
'label' => esc_html__( 'Menu / Title / Button Color', 'zeitfresser' ),
'section' => 'colors',
'settings' => 'primary_color',
) ) );
}
add_action( 'customize_preview_init', 'zeitfresser_primary_color_enqueue_scripts' );
function zeitfresser_primary_color_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-primary-color-customizer', get_template_directory_uri() . '/inc/blocks/colors/color-primary/customizer-color-primary.js', array('jquery'), '', true );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('primary_color',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--primary-color', to);
}
);
} );
} );
@@ -1,25 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_secondary_color' );
function zeitfresser_secondary_color( $wp_customize ) {
$wp_customize->add_setting( 'secondary_color', array(
'default' => zeitfresser_get_default_secondary_color(),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color'
) );
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'secondary_color', array(
'label' => esc_html__( 'Highlight Color', 'zeitfresser' ),
'section' => 'colors',
'settings' => 'secondary_color',
) ) );
}
add_action( 'customize_preview_init', 'zeitfresser_secondary_color_enqueue_scripts' );
function zeitfresser_secondary_color_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-secondary-customizer', get_template_directory_uri() . '/inc/blocks/colors/color-secondary/customizer-color-secondary.js', array('jquery'), '', true );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('secondary_color',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--secondary-color', to);
}
);
} );
} );
@@ -1,25 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_site_title_color' );
function zeitfresser_site_title_color( $wp_customize ) {
$wp_customize->add_setting( 'site_title_color_option', array(
'default' => zeitfresser_get_default_site_title_color(),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color',
) );
$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'site_title_color_option', array(
'label' => esc_html__( 'Site Identity Color', 'zeitfresser' ),
'section' => 'title_tagline',
'settings' => 'site_title_color_option',
) ) );
}
add_action( 'customize_preview_init', 'zeitfresser_site_title_color_enqueue_scripts' );
function zeitfresser_site_title_color_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-site-title-color-customizer', get_template_directory_uri() . '/inc/blocks/colors/color-site-title/customizer-color-site-title.js', array(), '', true );
}
@@ -1,9 +0,0 @@
jQuery( function( $ ) {
wp.customize( 'site_title_color_option', function( value ) {
value.bind( function( to ) {
$( '.site-title a' ).css( 'color', to );
} );
} );
} );
-35
View File
@@ -1,35 +0,0 @@
<?php
add_action( 'after_setup_theme', function () {
add_theme_support( 'custom-header', array( 'header-text' => false ) );
} );
add_action('customize_register', 'zeitfresser_color_section');
function zeitfresser_color_section($wp_customize)
{
$wp_customize->get_section('colors')->title = esc_html__( "Color Options", 'zeitfresser' );
$wp_customize->get_section('colors')->priority = 21;
}
/* Add Default Colors for Customizer Settings */
require dirname( __FILE__ ) . '/default-colors.php';
if( db_fs()->is__premium_only() ) {
require dirname( __FILE__ ) . '/color-site-title/color-site-title.php';
require dirname( __FILE__ ) . '/color-primary/color-primary.php';
require dirname( __FILE__ ) . '/color-secondary/color-secondary.php';
require dirname( __FILE__ ) . '/color-light/color-light.php';
require dirname( __FILE__ ) . '/color-grey/color-grey.php';
require dirname( __FILE__ ) . '/color-dark/color-dark.php';
}
require dirname( __FILE__ ) . '/color-background/color-background.php';
require dirname( __FILE__ ) . '/dynamic-colors.php';
-37
View File
@@ -1,37 +0,0 @@
<?php
/* Default Site Title Color */
function zeitfresser_get_default_site_title_color() {
return "#f7f7fa";
}
/* Default Primary Color */
function zeitfresser_get_default_primary_color() {
return "#f7f7fa";
}
/* Default Secondary Color */
function zeitfresser_get_default_secondary_color() {
return "#f7f7fa";
}
/* Default Light Color */
function zeitfresser_get_default_light_color() {
return "#1e1f29";
}
/* Default Grey Color */
function zeitfresser_get_default_grey_color() {
return "#f7f7fa";
}
/* Default Dark Color */
function zeitfresser_get_default_dark_color() {
return "#f7f7fa";
}
/* Default Background Color */
function zeitfresser_get_default_background_color() {
return "1e1f29";
}
-62
View File
@@ -1,62 +0,0 @@
<?php
add_action( 'wp_enqueue_scripts', 'zeitfresser_site_title_color_dynamic_css' );
function zeitfresser_site_title_color_dynamic_css() {
$site_title_color = esc_attr( get_theme_mod( 'site_title_color_option', zeitfresser_get_default_site_title_color() ) );
$dynamic_css = ":root { --site-title-color: $site_title_color; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_secondary_color_dynamic_css' );
function zeitfresser_secondary_color_dynamic_css() {
$secondary_color = esc_attr( get_theme_mod( 'secondary_color', zeitfresser_get_default_secondary_color() ) );
$dynamic_css = ":root { --secondary-color: $secondary_color; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_primary_color_dynamic_css' );
function zeitfresser_primary_color_dynamic_css() {
$primary_color = esc_attr( get_theme_mod( 'primary_color', zeitfresser_get_default_primary_color() ) );
$dynamic_css = ":root { --primary-color: $primary_color; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_light_color_dynamic_css' );
function zeitfresser_light_color_dynamic_css() {
$light_color = esc_attr( get_theme_mod( 'light_color', zeitfresser_get_default_light_color() ) );
$dynamic_css = ":root { --light-color: $light_color; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_grey_color_dynamic_css' );
function zeitfresser_grey_color_dynamic_css() {
$grey_color = esc_attr( get_theme_mod( 'grey_color', zeitfresser_get_default_grey_color() ) );
$dynamic_css = ":root { --grey-color: $grey_color; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_dark_color_dynamic_css' );
function zeitfresser_dark_color_dynamic_css() {
$dark_color = esc_attr( get_theme_mod( 'dark_color', zeitfresser_get_default_dark_color() ) );
$dynamic_css = ":root { --dark-color: $dark_color; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,25 +0,0 @@
<?php
/* Default Font Size */
function zeitfresser_get_default_font_size() {
return 16;
}
function zeitfresser_get_default_logo_size() {
return 60;
}
function zeitfresser_get_default_site_identity_font_size() {
return 40;
}
function zeitfresser_get_default_font_weight() {
return "400";
}
function zeitfresser_get_default_line_height() {
return "1.6";
}
@@ -1,29 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_register_font_customization_section' );
function zeitfresser_register_font_customization_section( $wp_customize ) {
$wp_customize->add_section( 'daisy_blog_font_customization_section', array(
'title' => esc_html__( 'Font Options', 'zeitfresser' ),
'priority' => 20
) );
}
/* Add Default Font Customization for Customizer Settings */
require dirname( __FILE__ ) . '/default-font-customization.php';
require dirname( __FILE__ ) . '/logo-size/logo-size.php';
require dirname( __FILE__ ) . '/site-identity-font-size/site-identity-font-size.php';
require dirname( __FILE__ ) . '/font-size/font-size.php';
require dirname( __FILE__ ) . '/font-weight/font-weight.php';
require dirname( __FILE__ ) . '/line-height/line-height.php';
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('font_size',function ( value ) {
value.bind(function ( to ) {
$( 'body,html' ).css( 'font-size', to+'px' );
}
);
} );
} );
@@ -1,40 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_font_size' );
function zeitfresser_font_size( $wp_customize ) {
$wp_customize->add_setting( 'font_size', array(
'default' => zeitfresser_get_default_font_size(),
'transport' => 'postMessage',
'sanitize_callback' => 'absint'
) );
$wp_customize->add_control( 'font_size', array(
'type' => 'number',
'settings' => 'font_size',
'label' => esc_html__( 'Body Font Size', 'zeitfresser' ),
'section' => 'daisy_blog_font_customization_section',
'input_attrs' => array(
'min' => 1,
'max' => 30
)
) );
}
add_action( 'customize_preview_init', 'zeitfresser_font_size_enqueue_scripts' );
function zeitfresser_font_size_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-font-size-customizer', get_template_directory_uri() . '/inc/blocks/font-customization/font-size/customizer-font-size.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_font_size_dynamic_css' );
function zeitfresser_font_size_dynamic_css() {
$font_size = esc_attr( get_theme_mod( 'font_size', zeitfresser_get_default_font_size() ) );
$font_size .= 'px';
$dynamic_css = "html,body{font-size:{$font_size};}";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('font_weight',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--font-weight', to);
}
);
} );
} );
@@ -1,40 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_font_weight' );
function zeitfresser_font_weight( $wp_customize ) {
$wp_customize->add_setting( 'font_weight', array(
'default' => zeitfresser_get_default_font_weight(),
'transport' => 'postMessage',
'sanitize_callback' => 'absint'
) );
$wp_customize->add_control( 'font_weight', array(
'type' => 'number',
'settings' => 'font_weight',
'label' => esc_html__( 'Body Font Weight', 'zeitfresser' ),
'section' => 'daisy_blog_font_customization_section',
'input_attrs' => array(
'min' => 100,
'max' => 900,
'step' => 100
)
) );
}
add_action( 'customize_preview_init', 'zeitfresser_font_weight_enqueue_scripts' );
function zeitfresser_font_weight_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-font-weight-customizer', get_template_directory_uri() . '/inc/blocks/font-customization/font-weight/customizer-font-weight.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_font_weight_dynamic_css' );
function zeitfresser_font_weight_dynamic_css() {
$font_weight = esc_attr( get_theme_mod( 'font_weight', zeitfresser_get_default_font_weight() ) );
$dynamic_css = ":root { --font-weight: $font_weight; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('line_height',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--line-height', to);
}
);
} );
} );
@@ -1,40 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_line_height' );
function zeitfresser_line_height( $wp_customize ) {
$wp_customize->add_setting( 'line_height', array(
'default' => zeitfresser_get_default_line_height(),
'transport' => 'postMessage',
'sanitize_callback' => 'zeitfresser_sanitize_float'
) );
$wp_customize->add_control( 'line_height', array(
'type' => 'number',
'settings' => 'line_height',
'label' => esc_html__( 'Line Height', 'zeitfresser' ),
'section' => 'daisy_blog_font_customization_section',
'input_attrs' => array(
'min' => 1,
'max' => 5,
'step' => 0.1
)
) );
}
add_action( 'customize_preview_init', 'zeitfresser_line_height_enqueue_scripts' );
function zeitfresser_line_height_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-line-height-customizer', get_template_directory_uri() . '/inc/blocks/font-customization/line-height/customizer-line-height.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_line_height_dynamic_css' );
function zeitfresser_line_height_dynamic_css() {
$line_height = esc_attr( get_theme_mod( 'line_height', zeitfresser_get_default_line_height() ) );
$dynamic_css = ":root { --line-height: $line_height; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('logo_size',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--logo-size', to+'px');
}
);
} );
} );
@@ -1,41 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_logo_size' );
function zeitfresser_logo_size( $wp_customize ) {
$wp_customize->add_setting( 'logo_size', array(
'default' => zeitfresser_get_default_logo_size(),
'transport' => 'postMessage',
'sanitize_callback' => 'absint'
) );
$wp_customize->add_control( 'logo_size', array(
'type' => 'number',
'settings' => 'logo_size',
'priority' => 8,
'label' => esc_html__( 'Logo Size', 'zeitfresser' ),
'section' => 'title_tagline',
'input_attrs' => array(
'min' => 10,
'max' => 100
)
) );
}
add_action( 'customize_preview_init', 'zeitfresser_logo_size_enqueue_scripts' );
function zeitfresser_logo_size_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-logo-size-customizer', get_template_directory_uri() . '/inc/blocks/font-customization/logo-size/customizer-logo-size.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_logo_size_dynamic_css' );
function zeitfresser_logo_size_dynamic_css() {
$logo_size = esc_attr( get_theme_mod( 'logo_size', zeitfresser_get_default_logo_size() ) );
$logo_size .= 'px';
$dynamic_css = ":root { --logo-size: $logo_size; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('site_identity_font_size',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--site-identity-font-size', to+'px');
}
);
} );
} );
@@ -1,40 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_site_identity_font_size' );
function zeitfresser_site_identity_font_size( $wp_customize ) {
$wp_customize->add_setting( 'site_identity_font_size', array(
'default' => zeitfresser_get_default_site_identity_font_size(),
'transport' => 'postMessage',
'sanitize_callback' => 'absint'
) );
$wp_customize->add_control( 'site_identity_font_size', array(
'type' => 'number',
'settings' => 'site_identity_font_size',
'label' => esc_html__( 'Site Identity Size', 'zeitfresser' ),
'section' => 'title_tagline',
'input_attrs' => array(
'min' => 10,
'max' => 40
)
) );
}
add_action( 'customize_preview_init', 'zeitfresser_site_identity_font_size_enqueue_scripts' );
function zeitfresser_site_identity_font_size_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-site-identity-font-size-customizer', get_template_directory_uri() . '/inc/blocks/font-customization/site-identity-font-size/customizer-site-identity-font-size.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_site_identity_font_size_dynamic_css' );
function zeitfresser_site_identity_font_size_dynamic_css() {
$site_identity_font_size = esc_attr( get_theme_mod( 'site_identity_font_size', zeitfresser_get_default_site_identity_font_size() ) );
$site_identity_font_size .= 'px';
$dynamic_css = ":root { --site-identity-font-size: $site_identity_font_size; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,14 +0,0 @@
<?php
/* Default Font Family */
function zeitfresser_get_default_site_identity_font_family() {
return esc_html__( "Oswald", 'zeitfresser' );
}
function zeitfresser_get_default_main_font_family() {
return esc_html__( "Oswald", 'zeitfresser' );
}
function zeitfresser_get_default_secondary_font_family() {
return esc_html__( "Roboto", 'zeitfresser' );
}
-40
View File
@@ -1,40 +0,0 @@
<?php
/* Add Google Fonts */
require dirname( __FILE__ ) . '/google-fonts.php';
/* Add Default Font Family for Customizer Settings */
require dirname( __FILE__ ) . '/default-font-family.php';
include_once wp_normalize_path( dirname( __FILE__ ) . '/inc/helper-functions.php' );
include_once wp_normalize_path( dirname( __FILE__ ) . '/inc/class-webfonts-local.php' );
include_once wp_normalize_path( dirname( __FILE__ ) . '/inc/class-fonts-google-local.php' );
require dirname( __FILE__ ) . '/site-identity/site-identity-font-family.php';
require dirname( __FILE__ ) . '/main/main-font-family.php';
require dirname( __FILE__ ) . '/secondary/secondary-font-family.php';
add_action( 'wp_enqueue_scripts', 'zeitfresser_google_fonts_scripts', 5 );
function zeitfresser_google_fonts_scripts() {
$local_css = zeitfresser_get_local_webfonts_css();
wp_register_style( 'zeitfresser-webfonts', false, array(), ZEITFRESSER_VERSION );
wp_enqueue_style( 'zeitfresser-webfonts' );
if ( ! empty( $local_css ) ) {
wp_add_inline_style( 'zeitfresser-webfonts', $local_css );
return;
}
$args = zeitfresser_used_google_fonts();
$fonts_url = zeitfresser_fonts_url( $args );
if ( empty( $fonts_url ) ) {
return;
}
wp_enqueue_style( 'google-fonts', $fonts_url, array(), null );
}
File diff suppressed because it is too large Load Diff
@@ -1,457 +0,0 @@
<?php
/**
* Handles downloading a font from the google-fonts API locally.
* Solves privacy concerns with Google's CDN
* and their sometimes less-than-transparent policies.
*
* @package zeitfresser
*/
// Do not allow directly accessing this file.
if ( ! defined( 'ABSPATH' ) ) {
exit( 'Direct script access denied.' );
}
final class Daisy_Blog_Google_Local {
/**
* The name of the font-family
*
* @access private
* @var string
*/
private $family;
/**
* The system path where font-files are stored.
*
* @access private
* @var string
*/
private $folder_path;
/**
* The URL where files for this font can be found.
*
* @access private
* @var string
*/
private $folder_url;
/**
* An array of instances for this object.
*
* @static
* @access private
* @var array
*/
private static $instances = array();
/**
* Create an instance of this object for a specific font-family.
*
* @static
* @access public
* @param string $family The font-family name.
* @return Daisy_Blog_Google_Local
*/
public static function init( $family ) {
$key = sanitize_key( $family );
if ( ! isset( self::$instances[ $key ] ) ) {
self::$instances[ $key ] = new self( $family );
}
return self::$instances[ $key ];
}
/**
* Constructor.
*
* @access private
* @param string $family The font-family name.
*/
private function __construct( $family ) {
$this->family = $family;
$key = sanitize_key( $this->family );
$this->folder_path = $this->get_root_path() . "/$key";
$this->folder_url = $this->get_root_url() . "/$key";
$this->files = $this->get_font_family();
}
/**
* Gets the @font-face CSS.
*
* @access public
* @param array $variants The variants we want to get.
* @return string
*/
public function get_css( $variants = array() ) {
if ( ! $this->files ) {
return;
}
$key = md5( wp_json_encode( $this->files ) );
$cached = get_transient( $key );
if ( $cached ) {
return $cached;
}
$css = '';
// If $variants is empty then use all variants available.
if ( empty( $variants ) ) {
$variants = array_keys( $this->files );
}
// Download files.
$this->download_font_family( $variants );
// Create the @font-face CSS.
foreach ( $variants as $variant ) {
$css .= $this->get_variant_fontface_css( $variant );
}
set_transient( $key, $css, WEEK_IN_SECONDS );
return $css;
}
/**
* Download font-family files.
*
* @access public
* @param array $variants An array of variants to download. Leave empty to download all.
* @return void
*/
public function download_font_family( $variants = array() ) {
if ( empty( $variants ) ) {
$variants = array_keys( $this->files );
}
foreach ( $this->files as $variant => $file ) {
if ( in_array( $variant, $variants ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
$this->download_font_file( $file );
}
}
}
/**
* Downloads a font-file and saves it locally.
*
* @access private
* @param string $url The URL of the file we want to get.
* @return bool
*/
private function download_font_file( $url ) {
$path = $this->folder_path . '/' . $this->get_filename_from_url( $url );
// If the folder doesn't exist, create it.
if ( ! file_exists( $this->folder_path ) ) {
wp_mkdir_p( $this->folder_path );
}
// If the file exists no reason to do anything.
if ( file_exists( $path ) ) {
return true;
}else{
$contents = $this->get_remote_url_contents( $url );
// Write file.
$filesystem = $this->get_filesystem();
return $filesystem->put_contents( $path, $contents, FS_CHMOD_FILE );
}
}
/**
* Gets the remote URL contents.
*
* @access private
* @param string $url The URL we want to get.
* @return string The contents of the remote URL.
*/
public function get_remote_url_contents( $url ) {
$response = wp_remote_get( $url );
if ( is_wp_error( $response ) ) {
return array();
}
$html = wp_remote_retrieve_body( $response );
if ( is_wp_error( $html ) ) {
return;
}
return $html;
}
/**
* Gets the filename by breaking-down the URL parts.
*
* @access private
* @param string $url The URL.
* @return string The filename.
*/
private function get_filename_from_url( $url ) {
$url_parts = explode( '/', $url );
$parts_count = count( $url_parts );
if ( 1 < $parts_count ) {
return $url_parts[ count( $url_parts ) - 1 ];
}
return $url;
}
/**
* Get the @font-face CSS for a specific variant.
*
* @access public
* @param string $variant The variant.
* @return string
*/
public function get_variant_fontface_css( $variant ) {
$font_face = "@font-face{font-family:'{$this->family}';";
// Get the font-style.
$font_style = ( false !== strpos( $variant, 'italic' ) ) ? 'italic' : 'normal';
$font_face .= "font-style:{$font_style};";
// Get the font-weight.
$font_weight = '400';
$font_weight = str_replace( 'italic', '', $variant );
$font_weight = ( ! $font_weight || 'regular' === $font_weight ) ? '400' : $font_weight;
$font_face .= "font-weight:{$font_weight};";
// Get the font-names.
$font_name_0 = $this->get_local_font_name( $variant, false );
$font_name_1 = $this->get_local_font_name( $variant, true );
$font_face .= "src:local('{$font_name_0}'),";
if ( $font_name_0 !== $font_name_1 ) {
$font_face .= "local('{$font_name_1}'),";
}
// Get the font-url.
$font_url = $this->get_variant_local_url( $variant );
$paths = $this->get_font_files_paths();
if ( ! file_exists( $paths[ $variant ] ) ) {
$font_url = $this->files[ $variant ];
}
// Get the font-format.
$font_format = ( strpos( $font_url, '.woff2' ) ) ? 'woff2' : 'truetype';
$font_format = ( strpos( $font_url, '.woff' ) && ! strpos( $font_url, '.woff2' ) ) ? 'woff' : $font_format;
$font_face .= "url({$font_url}) format('{$font_format}');}";
return $font_face;
}
/**
* Get the name of the font-family.
* This is used by @font-face in case the user already has the font downloaded locally.
*
* @access public
* @param string $variant The variant.
* @param bool $compact Whether we want the compact formatting or not.
* @return string
*/
public function get_local_font_name( $variant, $compact = false ) {
$variant_names = array(
'100' => 'Thin',
'100i' => 'Thin Italic',
'100italic' => 'Thin Italic',
'200' => 'Extra-Light',
'200i' => 'Extra-Light Italic',
'200italic' => 'Extra-Light Italic',
'300' => 'Light',
'300i' => 'Light Italic',
'300italic' => 'Light Italic',
'400' => 'Regular',
'regular' => 'Regular',
'400i' => 'Regular Italic',
'italic' => 'Italic',
'400italic' => 'Regular Italic',
'500' => 'Medium',
'500i' => 'Medium Italic',
'500italic' => 'Medium Italic',
'600' => 'Semi-Bold',
'600i' => 'Semi-Bold Italic',
'600italic' => 'Semi-Bold Italic',
'700' => 'Bold',
'700i' => 'Bold Italic',
'700italic' => 'Bold Italic',
'800' => 'Extra-Bold',
'800i' => 'Extra-Bold Italic',
'800italic' => 'Extra-Bold Italic',
'900' => 'Black',
'900i' => 'Black Italic',
'900italic' => 'Black Italic',
);
$variant = (string) $variant;
if ( $compact ) {
if ( isset( $variant_names[ $variant ] ) ) {
return str_replace( array( ' ', '-' ), '', $this->family ) . '-' . str_replace( array( ' ', '-' ), '', $variant_names[ $variant ] );
}
return str_replace( array( ' ', '-' ), '', $this->family );
}
if ( isset( $variant_names[ $variant ] ) ) {
return $this->family . ' ' . $variant_names[ $variant ];
}
return $this->family;
}
/**
* Gets the local URL for a variant.
*
* @access public
* @param string $variant The variant.
* @return string The URL.
*/
public function get_variant_local_url( $variant ) {
$local_urls = $this->get_font_files_urls_local();
if ( empty( $local_urls ) ) {
return;
}
// Return the specific variant if we can find it.
if ( isset( $local_urls[ $variant ] ) ) {
return $local_urls[ $variant ];
}
// Return regular if the one we want could not be found.
if ( isset( $local_urls['regular'] ) ) {
return $local_urls['regular'];
}
// Return the first available if all else failed.
$vals = array_values( $local_urls );
return $vals[0];
}
/**
* Get an array of local file URLs.
*
* @access public
* @return array
*/
public function get_font_files_urls_local() {
$urls = array();
$files = $this->get_font_files();
foreach ( $files as $key => $file ) {
$urls[ $key ] = $this->folder_url . '/' . $file;
}
return $urls;
}
/**
* Get an array of local file paths.
*
* @access public
* @return array
*/
public function get_font_files_paths() {
$paths = array();
$files = $this->get_font_files();
foreach ( $files as $key => $file ) {
$paths[ $key ] = $this->folder_path . '/' . $file;
}
return $paths;
}
/**
* Get an array of font-files.
* Only contains the filenames.
*
* @access public
* @return array
*/
public function get_font_files() {
$files = array();
foreach ( $this->files as $key => $url ) {
$files[ $key ] = $this->get_filename_from_url( $url );
}
return $files;
}
/**
* Gets the root fonts folder path.
* Other paths are built based on this.
*
* @access public
* @return string
*/
public function get_root_path() {
// Get the upload directory for this site.
$upload_dir = wp_upload_dir();
$path = untrailingslashit( wp_normalize_path( $upload_dir['basedir'] ) ) . '/webfonts';
// If the folder doesn't exist, create it.
if ( ! file_exists( $path ) ) {
wp_mkdir_p( $path );
}
// Return the path.
return apply_filters( 'daisy_blog_googlefonts_root_path', $path );
}
/**
* Gets the root folder url.
* Other urls are built based on this.
*
* @access public
* @return string
*/
public function get_root_url() {
// Get the upload directory for this site.
$upload_dir = wp_upload_dir();
// The URL.
$url = trailingslashit( $upload_dir['baseurl'] );
// Take care of domain mapping.
// When using domain mapping we have to make sure that the URL to the file
// does not include the original domain but instead the mapped domain.
if ( defined( 'DOMAIN_MAPPING' ) && DOMAIN_MAPPING ) {
if ( function_exists( 'domain_mapping_siteurl' ) && function_exists( 'get_original_url' ) ) {
$mapped_domain = domain_mapping_siteurl( false );
$original_domain = get_original_url( 'siteurl' );
$url = str_replace( $original_domain, $mapped_domain, $url );
}
}
$url = str_replace( array( 'https://', 'http://' ), '//', $url );
return apply_filters( 'daisy_blog_googlefonts_root_url', untrailingslashit( esc_url_raw( $url ) ) . '/webfonts' );
}
/**
* Get a font-family from the array of google-fonts.
*
* @access public
* @return array
*/
public function get_font_family() {
// Get the fonts array.
$fonts = $this->get_fonts();
if ( isset( $fonts[ $this->family ] ) ) {
return $fonts[ $this->family ];
}
return array();
}
/**
* Get the font defined in the google-fonts API.
*
* @access private
* @return array
*/
private function get_fonts() {
zeitfresser_get_google_fonts();
}
/**
* Gets the WP_Filesystem object.
*
* @access protected
* @return object
*/
protected function get_filesystem(){
// The WordPress filesystem.
global $wp_filesystem;
if ( empty( $wp_filesystem ) ) {
require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
WP_Filesystem();
}
return $wp_filesystem;
}
}
@@ -1,60 +0,0 @@
<?php
/**
* Handles adding to the footer the @font-face CSS for locally-hosted google-fonts.
* Solves privacy concerns with Google's CDN and their sometimes less-than-transparent policies.
*
* @package zeitfresser
*/
/**
* Manages the way Google Fonts are enqueued.
*/
final class Daisy_Blog_Webfonts_Local{
/**
* @access protected
*/
protected $googlefonts;
/**
* Constructor.
*
* @access public
*/
public function __construct( $googlefonts ) {
$this->googlefonts = $googlefonts;
add_action( 'wp_footer', array( $this, 'add_styles' ) );
add_action( 'admin_footer', array( $this, 'add_styles' ) );
}
/**
* Webfont Loader for Google Fonts.
*
* @access public
*/
public function add_styles() {
$hosted_fonts = $this->googlefonts;
// Early exit if we don't need to add any fonts.
if ( empty( $hosted_fonts ) ) {
return;
}
// Make sure we only do this once per font-family.
$hosted_fonts = array_unique( $hosted_fonts );
// Start CSS.
$css = '';
foreach( $hosted_fonts as $family ){
// Add the @font-face CSS for this font-family.
$css .= Daisy_Blog_Google_Local::init( $family )->get_css();
}
// If we've got CSS, add to the footer.
if ( $css ) {
echo '<style id="daisy-blog-local-webfonts">' . $css . '</style>'; // WPCS: XSS ok.
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,334 +0,0 @@
<?php
/**
* Function to check if it's a google font
*/
function zeitfresser_is_google_font( $font ){
$return = false;
$websafe_fonts = zeitfresser_get_websafe_font();
if( $font ){
if( array_key_exists( $font, $websafe_fonts ) ){
//Web Safe Font
$return = false;
}else{
//Google Font
$return = true;
}
}
return $return;
}
if( ! function_exists( 'zeitfresser_get_websafe_font' ) ) {
/**
* Function listing WebSafe Fonts and its attributes
*/
function zeitfresser_get_websafe_font(){
$standard_fonts = array(
'georgia-serif' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => 'Georgia, serif',
),
'palatino-serif' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => '"Palatino Linotype", "Book Antiqua", Palatino, serif',
),
'times-serif' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => '"Times New Roman", Times, serif',
),
'arial-helvetica' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => 'Arial, Helvetica, sans-serif',
),
'arial-gadget' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => '"Arial Black", Gadget, sans-serif',
),
'comic-cursive' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => '"Comic Sans MS", cursive, sans-serif',
),
'impact-charcoal' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => 'Impact, Charcoal, sans-serif',
),
'lucida' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => '"Lucida Sans Unicode", "Lucida Grande", sans-serif',
),
'tahoma-geneva' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => 'Tahoma, Geneva, sans-serif',
),
'trebuchet-helvetica' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => '"Trebuchet MS", Helvetica, sans-serif',
),
'verdana-geneva' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => 'Verdana, Geneva, sans-serif',
),
'courier' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => '"Courier New", Courier, monospace',
),
'lucida-monaco' => array(
'variants' => array( 'regular', 'italic', '700', '700italic' ),
'fonts' => '"Lucida Console", Monaco, monospace',
)
);
return apply_filters( 'daisy_blog_standard_fonts', $standard_fonts );
}
}
function zeitfresser_used_google_fonts() {
$main_font_family = zeitfresser_get_mod( 'main_font_family', zeitfresser_get_default_main_font_family() );
$secondary_font_family = zeitfresser_get_mod( 'secondary_font_family', zeitfresser_get_default_secondary_font_family() );
$site_identity_font_family = esc_attr( zeitfresser_get_mod( 'site_identity_font_family', zeitfresser_get_default_site_identity_font_family() ) );
$args['main_font_family'] = $main_font_family;
$args['secondary_font_family'] = $secondary_font_family;
$args['site_identity_font_family'] = $site_identity_font_family;
return $args;
}
add_action( 'wp_loaded', 'zeitfresser_google_font_local' );
if( ! function_exists( 'zeitfresser_google_font_local' ) ) {
/**
* Function that load Google Fonts used in our theme from customer locally.
* Solves privacy concerns with Google's CDN and their sometimes less-than-transparent policies.
*/
function zeitfresser_google_font_local() {
$args = array();
$fonts = zeitfresser_used_google_fonts();
foreach( $fonts as $font ) {
$is_google_font = zeitfresser_is_google_font( $font );
if( $is_google_font ) {
array_push( $args, $font );
}
}
new Daisy_Blog_Webfonts_Local( $args );
}
}
if ( ! function_exists( 'zeitfresser_font_weight_variants' ) ) {
/**
* Return the font variants used by the theme as an array.
*
* @return array
*/
function zeitfresser_font_weight_variants() {
$weights = explode( ';', zeitfresser_font_weight_query() );
$weights = array_map( 'trim', $weights );
$weights = array_filter( $weights );
if ( ! in_array( '400', $weights, true ) ) {
$weights[] = '400';
}
$weights = array_values( array_unique( $weights ) );
sort( $weights );
return $weights;
}
}
if ( ! function_exists( 'zeitfresser_get_local_webfonts_css' ) ) {
/**
* Build local @font-face CSS for currently selected Google fonts.
*
* Falls back to remote font file URLs per variant if a local file is not
* available yet, so typography does not break during warmup.
*
* @return string
*/
function zeitfresser_get_local_webfonts_css() {
$fonts = array_values( array_unique( array_filter( zeitfresser_used_google_fonts() ) ) );
$variants = zeitfresser_font_weight_variants();
$css = '';
foreach ( $fonts as $font ) {
if ( ! zeitfresser_is_google_font( $font ) ) {
continue;
}
$css .= Daisy_Blog_Google_Local::init( $font )->get_css( $variants );
}
return $css;
}
}
if ( ! function_exists( 'zeitfresser_get_local_webfont_urls' ) ) {
/**
* Extract local font asset URLs from a generated @font-face stylesheet.
*
* @param string $css Local webfont CSS.
* @return array
*/
function zeitfresser_get_local_webfont_urls( $css ) {
if ( empty( $css ) ) {
return array();
}
preg_match_all( '#url\(([^)]+)\)#', $css, $matches );
if ( empty( $matches[1] ) ) {
return array();
}
$urls = array();
foreach ( $matches[1] as $url ) {
$url = trim( $url, "\"'" );
if ( false !== strpos( $url, content_url() ) ) {
$urls[] = esc_url_raw( $url );
}
}
return array_values( array_unique( array_filter( $urls ) ) );
}
}
if( ! function_exists( 'zeitfresser_font_weight_query' ) ) {
/**
* Return the compact weight list used by the Zeitfresser theme.
*/
function zeitfresser_font_weight_query() {
$weights = array( '400', '500', '700' );
$body_weight = (string) zeitfresser_get_mod( 'font_weight', zeitfresser_get_default_font_weight() );
if ( preg_match( '/^\d{3}$/', $body_weight ) ) {
$weights[] = $body_weight;
}
$weights = array_values( array_unique( array_filter( $weights ) ) );
sort( $weights );
return implode( ';', $weights );
}
}
if( ! function_exists( 'zeitfresser_fonts_url' ) ) {
/**
* Returns a Google Fonts CSS2 URL for the selected theme fonts.
*/
function zeitfresser_fonts_url( $fonts = array() ) {
$font_families = array();
$weights = zeitfresser_font_weight_query();
foreach ( $fonts as $font ) {
if ( ! zeitfresser_is_google_font( $font ) ) {
continue;
}
$family_name = trim( (string) $font );
if ( '' === $family_name ) {
continue;
}
$font_families[] = 'family=' . str_replace( ' ', '+', $family_name ) . ':wght@' . $weights;
}
$font_families = array_values( array_unique( $font_families ) );
if ( empty( $font_families ) ) {
return '';
}
return esc_url( 'https://fonts.googleapis.com/css2?' . implode( '&', $font_families ) . '&display=swap' );
}
}
if( ! function_exists( 'zeitfresser_check_varient' ) ) {
/**
* Checks for matched varients in google fonts for typography fields
*/
function zeitfresser_check_varient( $font_family = 'serif', $font_variants = 'regular', $body = false ){
$variant = '';
$var = array();
$google_fonts = zeitfresser_get_google_fonts(); //Google Fonts
$websafe_fonts = zeitfresser_get_websafe_font(); //Standard Web Safe Fonts
if( array_key_exists( $font_family, $google_fonts ) ){
$variants = $google_fonts[ $font_family ][ 'variants' ];
if( in_array( $font_variants, $variants ) ){
if( $body ){ //LOAD ALL VARIANTS FOR BODY FONT
foreach( $variants as $v ){
$var[] = $v;
}
$variant = implode( ',', $var );
}else{
$variant = $font_variants;
}
}else{
$variant = 'regular';
}
}else{ //Standard Web Safe Fonts
if( array_key_exists( $font_family, $websafe_fonts ) ){
$variants = $websafe_fonts[ $font_family ][ 'variants' ];
if( in_array( $font_variants, $variants ) ){
if( $body ){ //LOAD ALL VARIANTS FOR BODY FONT
foreach( $variants as $v ){
$var[] = $v;
}
$variant = implode( ',', $var );
}else{
$variant = $font_variants;
}
}else{
$variant = 'regular';
}
}
}
return $variant;
}
}
if( ! function_exists( 'zeitfresser_get_google_fonts' ) ) {
/**
* Get Google Fonts
*/
function zeitfresser_get_google_fonts(){
$webfonts_json = @file_get_contents( get_template_directory_uri() . '/inc/blocks/font-family/inc/google-webfonts.json', true );
$fonts = json_decode( $webfonts_json, true );
$google_fonts = array();
if ( is_array( $fonts ) ) {
foreach ( $fonts['items'] as $font ) {
$google_fonts[ $font['family'] ] = array(
'variants' => $font['variants'],
);
}
}
return $google_fonts;
}
}
@@ -1,11 +0,0 @@
jQuery( function( $ ) {
wp.customize('main_font_family',function ( value ) {
value.bind(function ( to ) {
$("head").append("<link href='https://fonts.googleapis.com/css?family=" + to + ":200,300,400,500,600,700,800,900|' rel='stylesheet' type='text/css'>");
document.body.style.setProperty('--primary-font', to);
}
);
} );
} );
@@ -1,40 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_main_font_family' );
function zeitfresser_main_font_family( $wp_customize ) {
$wp_customize->add_setting( 'main_font_family', array(
'default' => zeitfresser_get_default_main_font_family(),
'transport' => 'postMessage',
'sanitize_callback' => 'zeitfresser_sanitize_google_fonts'
) );
$wp_customize->add_control( 'main_font_family', array(
'settings' => 'main_font_family',
'label' => esc_html__( 'Primary Font', 'zeitfresser' ),
'section' => 'daisy_blog_font_customization_section',
'type' => 'select',
'choices' => zeitfresser_google_fonts( zeitfresser_free_pro() ),
) );
}
add_action( 'customize_preview_init', 'zeitfresser_main_font_family_enqueue_scripts' );
function zeitfresser_main_font_family_enqueue_scripts() {
$main_font_family = esc_attr( get_theme_mod( 'main_font_family', zeitfresser_get_default_main_font_family() ) );
wp_enqueue_script( 'graphthemes-main-font-family-customizer', get_template_directory_uri() . '/inc/blocks/font-family/main/customizer-main-font-family.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_main_font_family_dynamic_css' );
function zeitfresser_main_font_family_dynamic_css() {
$main_font_family = esc_attr( get_theme_mod( 'main_font_family', zeitfresser_get_default_main_font_family() ) );
$dynamic_css = ":root { --primary-font: $main_font_family; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,11 +0,0 @@
jQuery( function( $ ) {
wp.customize('secondary_font_family',function ( value ) {
value.bind(function ( to ) {
$("head").append("<link href='https://fonts.googleapis.com/css?family=" + to + ":200,300,400,500,600,700,800,900|' rel='stylesheet' type='text/css'>");
document.body.style.setProperty('--secondary-font', to);
}
);
} );
} );
@@ -1,42 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_secondary_font_family' );
function zeitfresser_secondary_font_family( $wp_customize ) {
$wp_customize->add_setting( 'secondary_font_family', array(
'default' => zeitfresser_get_default_secondary_font_family(),
'transport' => 'postMessage',
'sanitize_callback' => 'zeitfresser_sanitize_google_fonts'
) );
$wp_customize->add_control( 'secondary_font_family', array(
'settings' => 'secondary_font_family',
'label' => esc_html__( 'Secondary Font', 'zeitfresser' ),
'section' => 'daisy_blog_font_customization_section',
'type' => 'select',
'choices' => zeitfresser_google_fonts( zeitfresser_free_pro() ),
) );
}
add_action( 'customize_preview_init', 'zeitfresser_secondary_font_family_enqueue_scripts' );
function zeitfresser_secondary_font_family_enqueue_scripts() {
$secondary_font_family = esc_attr( get_theme_mod( 'secondary_font_family', zeitfresser_get_default_secondary_font_family() ) );
wp_enqueue_script( 'graphthemes-secondary-font-family-customizer', get_template_directory_uri() . '/inc/blocks/font-family/secondary/customizer-secondary-font-family.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_secondary_font_family_dynamic_css' );
function zeitfresser_secondary_font_family_dynamic_css() {
$secondary_font_family = esc_attr( get_theme_mod( 'secondary_font_family', zeitfresser_get_default_secondary_font_family() ) );
$dynamic_css = ":root { --secondary-font: $secondary_font_family; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,11 +0,0 @@
jQuery( function( $ ) {
wp.customize('site_identity_font_family',function ( value ) {
value.bind(function ( to ) {
$("head").append("<link rel='stylesheet' href='https://fonts.googleapis.com/css?family="+to+":200,300,400,500,600,700,800,900|' rel='stylesheet' type='text/css'>");
document.body.style.setProperty('--site-identity-font-family', to);
}
);
} );
} );
@@ -1,41 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_site_identity_font_family' );
function zeitfresser_site_identity_font_family( $wp_customize ) {
$wp_customize->add_setting( 'site_identity_font_family', array(
'default' => zeitfresser_get_default_site_identity_font_family(),
'transport' => 'postMessage',
'sanitize_callback' => 'zeitfresser_sanitize_google_fonts'
) );
$wp_customize->add_control( 'site_identity_font_family', array(
'settings' => 'site_identity_font_family',
'label' => esc_html__( 'Site Title/Tagline Font', 'zeitfresser' ),
'section' => 'title_tagline',
'type' => 'select',
'choices' => zeitfresser_google_fonts( zeitfresser_free_pro() ),
) );
}
add_action( 'customize_preview_init', 'zeitfresser_site_identity_font_family_enqueue_scripts' );
function zeitfresser_site_identity_font_family_enqueue_scripts() {
$site_identity_font_family = esc_attr( get_theme_mod( 'site_identity_font_family', zeitfresser_get_default_site_identity_font_family() ) );
wp_enqueue_script( 'graphthemes-site-identity-font-family-customizer', get_template_directory_uri() . '/inc/blocks/font-family/site-identity/customizer-site-identity-font-family.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_site_identity_font_family_dynamic_css' );
function zeitfresser_site_identity_font_family_dynamic_css() {
$site_identity_font_family = esc_attr( get_theme_mod( 'site_identity_font_family', zeitfresser_get_default_site_identity_font_family() ) );
$dynamic_css = ":root { --site-identity-font-family: $site_identity_font_family; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,5 +0,0 @@
<?php
function zeitfresser_get_default_footer_copyright() {
return "Zeitfresser ©";
}
@@ -1,26 +0,0 @@
<?php
/* Add Default Copyright Text */
require dirname( __FILE__ ) . '/default-footer-copyright.php';
add_action( 'customize_register', 'zeitfresser_customize_register_footer_copyright' );
function zeitfresser_customize_register_footer_copyright( $wp_customize ) {
$wp_customize->add_section( 'daisy_blog_footer_copyright_section', array(
'title' => esc_html__( 'Footer Copyright', 'zeitfresser' ),
'priority' => 24
) );
$wp_customize->add_setting( 'footer_copyright_text', array(
'sanitize_callback' => 'wp_kses_post',
'default' => zeitfresser_get_default_footer_copyright()
) );
$wp_customize->add_control( 'footer_copyright_text', array(
'label' => esc_html__( 'Copyright Text', 'zeitfresser' ),
'section' => 'daisy_blog_footer_copyright_section',
'settings' => 'footer_copyright_text',
'type'=> 'textarea',
) );
}
@@ -1,64 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_container_width' );
function zeitfresser_container_width( $wp_customize ) {
$general_title = '<hr/><h2>' . esc_html__( 'General:', 'zeitfresser' ) . '</h2>';
$wp_customize->add_setting(
'zeitfresser_general_title',
array(
'default' => '',
'sanitize_callback' => 'wp_kses_post',
)
);
$wp_customize->add_control(
new Daisy_Blog_Custom_Text(
$wp_customize,
'zeitfresser_general_title',
array(
'section' => 'daisy_blog_general_customization_section',
'label' => $general_title,
'priority' => 5,
)
)
);
$wp_customize->add_setting('container_width', array(
'default' => zeitfresser_get_default_container_width(),
'sanitize_callback' => 'absint',
'transport' => 'postMessage',
));
$wp_customize->add_control( 'container_width', array(
'label' => esc_html__('Container Width', 'zeitfresser'),
'section' => 'daisy_blog_general_customization_section',
'type' => 'number',
'priority' => 10,
'input_attrs' => array(
'min' => 1000,
'max' => 1600
) )
);
}
add_action( 'customize_preview_init', 'zeitfresser_container_width_enqueue_scripts' );
function zeitfresser_container_width_enqueue_scripts() {
wp_enqueue_script( 'graphthemes-container-width-customizer', get_template_directory_uri() . '/inc/blocks/general/container-width/customizer-container-width.js', array('jquery'), '', true );
}
add_action( 'wp_enqueue_scripts', 'zeitfresser_container_width_dynamic_css' );
function zeitfresser_container_width_dynamic_css() {
$container_width = esc_attr( get_theme_mod( 'container_width', zeitfresser_get_default_container_width() ) );
$container_width .= 'px';
$dynamic_css = ":root { --container-width: $container_width; }";
wp_add_inline_style( 'zeitfresser', $dynamic_css );
}
@@ -1,10 +0,0 @@
jQuery( function( $ ) {
wp.customize('container_width',function ( value ) {
value.bind(function ( to ) {
document.body.style.setProperty('--container-width', to+"px");
}
);
} );
} );
-25
View File
@@ -1,25 +0,0 @@
<?php
/* Default General Customization */
function zeitfresser_get_default_breadcrumbs() {
return false;
}
function zeitfresser_get_default_sticky_menu() {
return false;
}
function zeitfresser_get_default_container_width() {
return 1400;
}
function zeitfresser_get_default_show_article_toc() {
return true;
}
function zeitfresser_get_default_article_toc_min_headlines() {
return 3;
}
-30
View File
@@ -1,30 +0,0 @@
<?php
/**
* General customizer section.
*/
add_action( 'customize_register', 'zeitfresser_register_general_customization_section' );
/**
* Register the general options section.
*
* @param WP_Customize_Manager $wp_customize Customizer manager.
* @return void
*/
function zeitfresser_register_general_customization_section( $wp_customize ) {
$wp_customize->add_section(
'daisy_blog_general_customization_section',
array(
'title' => esc_html__( 'General Options', 'zeitfresser' ),
'priority' => 21,
)
);
}
require dirname( __FILE__ ) . '/default-general.php';
require dirname( __FILE__ ) . '/container-width/container-width.php';
require dirname( __FILE__ ) . '/social-links/social-links.php';
require dirname( __FILE__ ) . '/toc-options.php';
require dirname( __FILE__ ) . '/../post-snippet/default-post-snippet.php';
require dirname( __FILE__ ) . '/../post-snippet/excerpt/excerpt.php';
@@ -1,83 +0,0 @@
<?php
/**
* Social links customizer settings.
*
* @package zeitfresser
*/
if ( ! function_exists( 'zeitfresser_get_social_links' ) ) {
/**
* Return supported social network labels.
*
* @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' );
/**
* Register social link customizer controls.
*
* @param WP_Customize_Manager $wp_customize Customizer manager.
* @return void
*/
function zeitfresser_social_links( $wp_customize ) {
$social_links = zeitfresser_get_social_links();
$social_links_title = '<hr/><h2>' . esc_html__( 'Social Links:', 'zeitfresser' ) . '</h2>';
$wp_customize->add_setting(
'social_links_title',
array(
'default' => '',
'sanitize_callback' => 'wp_kses_post',
)
);
$wp_customize->add_control(
new Daisy_Blog_Custom_Text(
$wp_customize,
'social_links_title',
array(
'section' => 'daisy_blog_general_customization_section',
'label' => $social_links_title,
'priority' => 20,
)
)
);
$social_priority = 21;
foreach ( $social_links as $social_key => $social_label ) {
$wp_customize->add_setting(
'social_links_' . $social_key,
array(
'default' => zeitfresser_get_social_link_default( $social_key ),
'sanitize_callback' => 'esc_url_raw',
)
);
$wp_customize->add_control(
'social_links_' . $social_key,
array(
'label' => $social_label,
'section' => 'daisy_blog_general_customization_section',
'type' => 'url',
'priority' => $social_priority++,
)
);
}
}
-99
View File
@@ -1,99 +0,0 @@
<?php
/**
* TOC related general settings.
*/
add_action( 'customize_register', 'zeitfresser_register_article_toc_options' );
/**
* Sanitize the minimum heading threshold for the article TOC.
*
* @param mixed $value Submitted control value.
* @return int
*/
function zeitfresser_sanitize_article_toc_min_headlines( $value ) {
$value = absint( $value );
if ( $value < 1 ) {
$value = zeitfresser_get_default_article_toc_min_headlines();
}
return min( 50, $value );
}
/**
* Register article TOC options in General Options.
*
* @param WP_Customize_Manager $wp_customize Customizer manager.
* @return void
*/
function zeitfresser_register_article_toc_options( $wp_customize ) {
$article_toc_title = '<hr/><h2>' . esc_html__( 'Article TOC:', 'zeitfresser' ) . '</h2>';
$wp_customize->add_setting(
'article_toc_options_heading',
array(
'sanitize_callback' => 'wp_kses_post',
)
);
$wp_customize->add_control(
new Daisy_Blog_Custom_Text(
$wp_customize,
'article_toc_options_heading',
array(
'section' => 'daisy_blog_general_customization_section',
'label' => $article_toc_title,
'priority' => 12,
)
)
);
$wp_customize->add_setting(
'show_article_toc',
array(
'sanitize_callback' => 'zeitfresser_sanitize_checkbox',
'default' => zeitfresser_get_default_show_article_toc(),
)
);
$wp_customize->add_control(
new Graphthemes_Toggle_Control(
$wp_customize,
'show_article_toc',
array(
'settings' => 'show_article_toc',
'section' => 'daisy_blog_general_customization_section',
'label' => esc_html__( 'Show Article TOC', 'zeitfresser' ),
'description' => esc_html__( 'Enable the floating article TOC on single posts. Default: enabled.', 'zeitfresser' ),
'type' => 'toggle',
'priority' => 13,
)
)
);
$wp_customize->add_setting(
'article_toc_min_headlines',
array(
'sanitize_callback' => 'zeitfresser_sanitize_article_toc_min_headlines',
'default' => zeitfresser_get_default_article_toc_min_headlines(),
)
);
$wp_customize->add_control(
'article_toc_min_headlines',
array(
'settings' => 'article_toc_min_headlines',
'type' => 'number',
'section' => 'daisy_blog_general_customization_section',
'label' => esc_html__( 'Number of Headlines to Start TOC', 'zeitfresser' ),
'description' => esc_html__( 'The article TOC is shown only when this number of headings or more is found. Default: 3.', 'zeitfresser' ),
'priority' => 14,
'input_attrs' => array(
'min' => 1,
'max' => 50,
'step' => 1,
),
)
);
}
-18
View File
@@ -1,18 +0,0 @@
#customize-controls .control-section-button .accordion-section-title:hover,
#customize-controls .control-section-button .accordion-section-title:focus {
background-color: #fff;
}
.control-section-button .accordion-section-title .button {
margin-top: -4px;
font-weight: 400;
margin-left: 8px;
background: #e45157;
border: none;
color: #fff;
}
.rtl .control-section-button .accordion-section-title .button {
margin-left: 0;
margin-right: 8px;
}
-15
View File
@@ -1,15 +0,0 @@
(function (api) {
if (api != null) {
// Extends our custom "upgrade-to-pro" section.
api.sectionConstructor["button"] = api.Section.extend({
// No events for this type of section.
attachEvents: function () {},
// Always make the section active.
isContextuallyActive: function () {
return true;
},
});
} else {
}
})(wp.customize);
@@ -1,74 +0,0 @@
<?php
/**
* Pro customizer section.
*
* @since 1.0.0
* @access public
*/
class Daisy_Blog_Button_Control extends WP_Customize_Section {
/**
* The type of customize section being rendered.
*
* @since 1.0.0
* @access public
* @var string
*/
public $type = 'button';
/**
* Custom button text to output.
*
* @since 1.0.0
* @access public
* @var string
*/
public $pro_text = '';
/**
* Custom pro button URL.
*
* @since 1.0.0
* @access public
* @var string
*/
public $pro_url = '';
/**
* Add custom parameters to pass to the JS via JSON.
*
* @since 1.0.0
* @access public
* @return void
*/
public function json() {
$json = parent::json();
$json['pro_text'] = $this->pro_text;
$json['pro_url'] = esc_url( $this->pro_url );
return $json;
}
/**
* Outputs the Underscore.js template.
*
* @since 1.0.0
* @access public
* @return void
*/
protected function render_template() { ?>
<li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }} cannot-expand">
<h3 class="accordion-section-title">
{{ data.title }}
<# if ( data.pro_text && data.pro_url ) { #>
<a href="{{ data.pro_url }}" class="button button-secondary alignright" target="_blank">{{ data.pro_text }}</a>
<# } #>
</h3>
</li>
<?php }
}
@@ -1,24 +0,0 @@
<?php
if( class_exists( 'WP_Customize_control' ) ){
class Daisy_Blog_Custom_Text extends WP_Customize_Control
{
/**
* Render the content on the theme customizer page
*/
public function render_content()
{
?>
<label>
<strong class="customize-text_editor"><?php echo wp_kses_post( $this->label ); ?></strong>
<br />
<span class="customize-text_editor_desc">
<?php echo wp_kses_post( $this->description ); ?>
</span>
</label>
<?php
}
}//editor close
}//class close
@@ -1,86 +0,0 @@
<?php
/**
* Customizer Control: multi-check
*
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Graphthemes_Multi_Check_Control' ) ) {
/**
* Adds a multicheck control.
*/
class Graphthemes_Multi_Check_Control extends Wp_Customize_Control {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'multi-check';
public $tooltip = '';
public function to_json() {
parent::to_json();
if ( isset( $this->default ) ) {
$this->json['default'] = $this->default;
} else {
$this->json['default'] = $this->setting->default;
}
$this->json['value'] = $this->value();
$this->json['choices'] = $this->choices;
$this->json['link'] = $this->get_link();
$this->json['id'] = $this->id;
$this->json['tooltip'] = $this->tooltip;
$this->json['inputAttrs'] = '';
foreach ( $this->input_attrs as $attr => $value ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
}
}
public function enqueue() {
wp_enqueue_script( 'graphthemes-multi-check', get_template_directory_uri() . '/inc/blocks/includes/multicheck/multi-check.js', array( 'jquery' ), false, true );
}
protected function content_template() {
?>
<# if ( ! data.choices ) { return; } #>
<# if ( data.tooltip ) { #>
<a href="#" class="tooltip hint--left" data-hint="{{ data.tooltip }}"><span class='dashicons dashicons-info'></span></a>
<# } #>
<# if ( data.label ) { #>
<span class="customize-control-title">{{ data.label }}</span>
<# } #>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<ul>
<# for ( key in data.choices ) { #>
<li>
<label>
<input type="checkbox" value="{{ key }}"<# if ( _.contains( data.value, key ) ) { #> checked<# } #> />
{{ data.choices[ key ] }}
</label>
</li>
<# } #>
</ul>
<?php
}
}
}
@@ -1,30 +0,0 @@
wp.customize.controlConstructor['multi-check'] = wp.customize.Control.extend({
// When we're finished loading continue processing.
ready: function() {
'use strict';
var control = this;
// Save the value
control.container.on( 'change', 'input', function() {
var value = [],
i = 0;
// Build the value as an object using the sub-values from individual checkboxes.
jQuery.each( control.params.choices, function( key, subValue ) {
if ( control.container.find( 'input[value="' + key + '"]' ).is( ':checked' ) ) {
value[ i ] = key;
i++;
}
});
// Update the value in the customizer.
control.setting.set( value );
});
}
});
-17
View File
@@ -1,17 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_register_custom_controls' );
function zeitfresser_register_custom_controls( $wp_customize ) {
require_once ZEITFRESSER_BLOCKS_DIR_PATH . '/includes/button/class-button-control.php';
$wp_customize->register_control_type( 'Daisy_Blog_Button_Control' );
require_once ZEITFRESSER_BLOCKS_DIR_PATH . '/includes//custom-html/class-custom-html.php';
require_once ZEITFRESSER_BLOCKS_DIR_PATH . '/includes/toggle/class-toggle-control.php';
$wp_customize->register_control_type( 'Graphthemes_Toggle_Control' );
require_once ZEITFRESSER_BLOCKS_DIR_PATH . '/includes//multicheck/class-multi-check-control.php';
$wp_customize->register_control_type( 'Graphthemes_Multi_Check_Control' );
}
-50
View File
@@ -1,50 +0,0 @@
<?php
/* Sanitize Google Fonts */
function zeitfresser_sanitize_google_fonts( $input, $setting ) {
// Get list of choices from the control associated with the setting.
$choices = $setting->manager->get_control( $setting->id )->choices;
// If the input is a valid key, return it; otherwise, return the default.
return ( array_key_exists( $input, $choices ) ? $input : $setting->default );
}
function zeitfresser_sanitize_float( $input ) {
return filter_var($input, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
}
//checkbox sanitization function
function zeitfresser_sanitize_checkbox( $input ) {
//returns true if checkbox is checked
return ( ( isset( $input ) && true == $input ) ? true : false );
}
function zeitfresser_sanitize_select( $input, $setting ) {
// Ensure input is a slug.
$input = sanitize_key( $input );
// Get list of choices from the control associated with the setting.
$choices = $setting->manager->get_control( $setting->id )->choices;
// If the input is a valid key, return it; otherwise, return the default.
return ( array_key_exists( $input, $choices ) ? $input : $setting->default );
}
function zeitfresser_sanitize_array( $value ){
if ( is_array( $value ) ) {
foreach ( $value as $key => $subvalue ) {
$value[ $key ] = esc_attr( $subvalue );
}
return $value;
}
return esc_attr( $value );
}
@@ -1,56 +0,0 @@
<script type="text/javascript">
var fb = '<?php echo esc_html__( "Facebook", 'zeitfresser' ); ?>';
var twitter = '<?php echo esc_html__( "Twitter", 'zeitfresser' ); ?>';
var pinterest = '<?php echo esc_html__( "Pinterest", 'zeitfresser' ); ?>';
var linkedin = '<?php echo esc_html__( "Linkedin", 'zeitfresser' ); ?>';
</script>
<?php
$url = urlencode(get_the_permalink());
$title = html_entity_decode(get_the_title(), ENT_COMPAT, 'UTF-8');
$media = urlencode(get_the_post_thumbnail_url(get_the_ID(), 'full'));
$twitter_id = get_theme_mod('twitter_id');
$social_share = $args;
?>
<ul class="list-inline">
<li><?php esc_html_e( "Share", 'zeitfresser' ); ?>:</li>
<?php if( in_array( 'facebook', $social_share ) ) { ?>
<li><a href="https://www.facebook.com/sharer/sharer.php?u=<?php echo $url; ?>" onclick="return ! window.open( this.href, fb, 'width=500, height=500' )">
<svg version="1.1" viewBox="0 0 56.693 56.693" width="56.693px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M40.43,21.739h-7.645v-5.014c0-1.883,1.248-2.322,2.127-2.322c0.877,0,5.395,0,5.395,0V6.125l-7.43-0.029 c-8.248,0-10.125,6.174-10.125,10.125v5.518h-4.77v8.53h4.77c0,10.947,0,24.137,0,24.137h10.033c0,0,0-13.32,0-24.137h6.77 L40.43,21.739z"/></svg></a></li>
<?php } ?>
<?php if( in_array( 'twitter', $social_share ) ) { ?>
<li><a href="https://twitter.com/intent/tweet?text=<?php echo $title; ?>&amp;url=<?php echo $url; ?>&amp;via=<?php echo esc_html( $twitter_id ); ?>" onclick="return ! window.open( this.href, twitter, 'width=500, height=500' )">
<svg version="1.1" viewBox="0 0 512 512" width="512px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M492,109.5c-17.4,7.7-36,12.9-55.6,15.3c20-12,35.4-31,42.6-53.6c-18.7,11.1-39.4,19.2-61.5,23.5 C399.8,75.8,374.6,64,346.8,64c-53.5,0-96.8,43.4-96.8,96.9c0,7.6,0.8,15,2.5,22.1C172,179,100.6,140.4,52.9,81.7 c-8.3,14.3-13.1,31-13.1,48.7c0,33.6,17.1,63.3,43.1,80.7C67,210.7,52,206.3,39,199c0,0.4,0,0.8,0,1.2c0,47,33.4,86.1,77.7,95 c-8.1,2.2-16.7,3.4-25.5,3.4c-6.2,0-12.3-0.6-18.2-1.8c12.3,38.5,48.1,66.5,90.5,67.3c-33.1,26-74.9,41.5-120.3,41.5 c-7.8,0-15.5-0.5-23.1-1.4C62.9,432,113.8,448,168.4,448C346.6,448,444,300.3,444,172.2c0-4.2-0.1-8.4-0.3-12.5 C462.6,146,479,128.9,492,109.5z"/></svg>
</a>
</li>
<?php } ?>
<?php if( in_array( 'pinterest', $social_share ) ) { ?>
<li><a href="http://pinterest.com/pin/create/button/?url=<?php echo $url; ?>&amp;media=<?php echo $media; ?>&amp;description=<?php echo esc_html( $title ); ?>" onclick="return ! window.open( this.href, pinterest, 'width=500, height=500' )">
<svg viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><path d="M12.486,4.771c-4.23,0-6.363,3.033-6.363,5.562c0,1.533,0.581,2.894,1.823,3.401c0.205,0.084,0.387,0.004,0.446-0.221 c0.041-0.157,0.138-0.553,0.182-0.717c0.061-0.221,0.037-0.3-0.127-0.495c-0.359-0.422-0.588-0.972-0.588-1.747 c0-2.25,1.683-4.264,4.384-4.264c2.392,0,3.706,1.463,3.706,3.412c0,2.568-1.137,4.734-2.824,4.734 c-0.932,0-1.629-0.77-1.405-1.715c0.268-1.13,0.786-2.347,0.786-3.16c0-0.729-0.392-1.336-1.2-1.336 c-0.952,0-1.718,0.984-1.718,2.304c0,0.841,0.286,1.409,0.286,1.409s-0.976,4.129-1.146,4.852c-0.34,1.44-0.051,3.206-0.025,3.385 c0.013,0.104,0.149,0.131,0.21,0.051c0.088-0.115,1.223-1.517,1.607-2.915c0.111-0.396,0.627-2.445,0.627-2.445 c0.311,0.589,1.213,1.108,2.175,1.108c2.863,0,4.804-2.608,4.804-6.103C18.123,7.231,15.886,4.771,12.486,4.771z"/></g></svg>
</a>
</li>
<?php } ?>
<?php if( in_array( 'linkedin', $social_share ) ) { ?>
<li><a href="https://www.linkedin.com/shareArticle?mini=true&url=<?php echo $url; ?>&title=<?php echo esc_html( $title ); ?>" onclick="return ! window.open( this.href, linkedin, 'width=500, height=500' )">
<svg baseProfile="tiny" version="1.2" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><path d="M8,19H5V9h3V19z M19,19h-3v-5.342c0-1.392-0.496-2.085-1.479-2.085c-0.779,0-1.273,0.388-1.521,1.165C13,14,13,19,13,19h-3 c0,0,0.04-9,0-10h2.368l0.183,2h0.062c0.615-1,1.598-1.678,2.946-1.678c1.025,0,1.854,0.285,2.487,1.001 C18.683,11.04,19,12.002,19,13.353V19z"/></g><g><ellipse cx="6.5" cy="6.5" rx="1.55" ry="1.5"/></g></svg>
</a>
</li>
<?php } ?>
<?php if( in_array( 'email', $social_share ) ) { ?>
<li><a href="mailto:?subject=<?php echo esc_attr( $title ); ?>&body=<?php echo $title . " " . $url; ?>" target="_blank">
<svg version="1.1" viewBox="0 0 100.354 100.352" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M93.09,76.224c0.047-0.145,0.079-0.298,0.079-0.459V22.638c0-0.162-0.032-0.316-0.08-0.462 c-0.007-0.02-0.011-0.04-0.019-0.06c-0.064-0.171-0.158-0.325-0.276-0.46c-0.008-0.009-0.009-0.02-0.017-0.029 c-0.005-0.005-0.011-0.007-0.016-0.012c-0.126-0.134-0.275-0.242-0.442-0.323c-0.013-0.006-0.023-0.014-0.036-0.02 c-0.158-0.071-0.33-0.111-0.511-0.123c-0.018-0.001-0.035-0.005-0.053-0.005c-0.017-0.001-0.032-0.005-0.049-0.005H8.465 c-0.017,0-0.033,0.004-0.05,0.005c-0.016,0.001-0.032,0.004-0.048,0.005c-0.183,0.012-0.358,0.053-0.518,0.125 c-0.01,0.004-0.018,0.011-0.028,0.015c-0.17,0.081-0.321,0.191-0.448,0.327c-0.005,0.005-0.011,0.006-0.016,0.011 c-0.008,0.008-0.009,0.019-0.017,0.028c-0.118,0.135-0.213,0.29-0.277,0.461c-0.008,0.02-0.012,0.04-0.019,0.061 c-0.048,0.146-0.08,0.3-0.08,0.462v53.128c0,0.164,0.033,0.32,0.082,0.468c0.007,0.02,0.011,0.039,0.018,0.059 c0.065,0.172,0.161,0.327,0.28,0.462c0.007,0.008,0.009,0.018,0.016,0.026c0.006,0.007,0.014,0.011,0.021,0.018 c0.049,0.051,0.103,0.096,0.159,0.14c0.025,0.019,0.047,0.042,0.073,0.06c0.066,0.046,0.137,0.083,0.21,0.117 c0.018,0.008,0.034,0.021,0.052,0.028c0.181,0.077,0.38,0.121,0.589,0.121h83.204c0.209,0,0.408-0.043,0.589-0.121 c0.028-0.012,0.054-0.03,0.081-0.044c0.062-0.031,0.124-0.063,0.181-0.102c0.03-0.021,0.057-0.048,0.086-0.071 c0.051-0.041,0.101-0.082,0.145-0.129c0.008-0.008,0.017-0.014,0.025-0.022c0.008-0.009,0.01-0.021,0.018-0.03 c0.117-0.134,0.211-0.288,0.275-0.458C93.078,76.267,93.083,76.246,93.09,76.224z M9.965,26.04l25.247,23.061L9.965,72.346V26.04z M61.711,47.971c-0.104,0.068-0.214,0.125-0.301,0.221c-0.033,0.036-0.044,0.083-0.073,0.121l-11.27,10.294L12.331,24.138h75.472 L61.711,47.971z M37.436,51.132l11.619,10.613c0.287,0.262,0.649,0.393,1.012,0.393s0.725-0.131,1.011-0.393l11.475-10.481 l25.243,23.002H12.309L37.436,51.132z M64.778,49.232L90.169,26.04v46.33L64.778,49.232z"/></svg></a>
</li>
<?php } ?>
</ul>
@@ -1,65 +0,0 @@
<?php
/**
* Customizer Control: toggle.
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Graphthemes_Toggle_Control' ) ) {
/**
* Toggle control (modified checkbox).
*/
class Graphthemes_Toggle_Control extends Wp_Customize_Control {
public $type = 'toggle';
public $tooltip = '';
public function to_json() {
parent::to_json();
if ( isset( $this->default ) ) {
$this->json['default'] = $this->default;
} else {
$this->json['default'] = $this->setting->default;
}
$this->json['value'] = $this->value();
$this->json['link'] = $this->get_link();
$this->json['id'] = $this->id;
$this->json['tooltip'] = $this->tooltip;
$this->json['inputAttrs'] = '';
foreach ( $this->input_attrs as $attr => $value ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
}
}
public function enqueue() {
wp_enqueue_style( 'graphthemes-toggle', get_template_directory_uri() . '/inc/blocks/includes/toggle/toggle.css', null );
wp_enqueue_script( 'graphthemes-toggle', get_template_directory_uri() . '/inc/blocks/includes/toggle/toggle.js', array( 'jquery' ), false, true ); //for toggle
}
protected function content_template() {
?>
<# if ( data.tooltip ) { #>
<a href="#" class="tooltip hint--left" data-hint="{{ data.tooltip }}"><span class='dashicons dashicons-info'></span></a>
<# } #>
<label for="toggle_{{ data.id }}">
<span class="customize-control-title">
{{{ data.label }}}
</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<input {{{ data.inputAttrs }}} name="toggle_{{ data.id }}" id="toggle_{{ data.id }}" type="checkbox" value="{{ data.value }}" {{{ data.link }}}<# if ( '1' == data.value ) { #> checked<# } #> hidden />
<span class="switch"></span>
</label>
<?php
}
}
}
-64
View File
@@ -1,64 +0,0 @@
.customize-control-toggle label {
display: flex;
flex-wrap: wrap;
}
.customize-control-toggle label .customize-control-title {
width: calc(100% - 55px);
}
.customize-control-toggle label .description {
order: 99;
}
.customize-control-toggle input[type="checkbox"] {
display: none;
}
.customize-control-toggle .switch {
border: 1px solid rgba(0, 0, 0, 0.1);
display: inline-block;
width: 35px;
height: 12px;
border-radius: 8px;
background: #ccc;
vertical-align: middle;
position: relative;
cursor: pointer;
user-select: none;
transition: background 350ms ease;
}
.customize-control-toggle .switch:before, .customize-control-toggle .switch:after {
content: "";
display: block;
width: 20px;
height: 20px;
border-radius: 50%;
position: absolute;
top: 50%;
left: -3px;
transition: all 350ms cubic-bezier(0, 0.95, 0.38, 0.98), background 150ms ease;
}
.customize-control-toggle .switch:before {
background: rgba(0, 0, 0, 0.2);
transform: translate3d(0, -50%, 0) scale(0);
}
.customize-control-toggle .switch:after {
background: #999;
border: 1px solid rgba(0, 0, 0, 0.1);
transform: translate3d(0, -50%, 0);
}
.customize-control-toggle .switch:active:before {
transform: translate3d(0, -50%, 0) scale(3);
}
.customize-control-toggle input:checked + .switch {
background: rgba(52, 152, 222, 0.3);
}
.customize-control-toggle input:checked + .switch:before {
background: rgba(52, 152, 222, 0.075);
transform: translate3d(100%, -50%, 0) scale(1);
}
.customize-control-toggle input:checked + .switch:after {
background: #3498DE;
transform: translate3d(100%, -50%, 0);
}
.customize-control-toggle input:checked + .switch:active:before {
background: rgba(52, 152, 222, 0.075);
transform: translate3d(100%, -50%, 0) scale(3);
}
-18
View File
@@ -1,18 +0,0 @@
wp.customize.controlConstructor['toggle'] = wp.customize.Control.extend({
ready: function() {
'use strict';
var control = this,
checkboxValue = control.setting._value;
// Save the value
this.container.on( 'change', 'input', function() {
checkboxValue = ( jQuery( this ).is( ':checked' ) ) ? true : false;
control.setting.set( checkboxValue );
});
}
});
@@ -1,61 +0,0 @@
<?php
/* Default Post Detail Author*/
function zeitfresser_get_default_post_detail_author() {
return false;
}
/* Default Post Detail Category*/
function zeitfresser_get_default_post_detail_category() {
return false;
}
/* Default Post Detail Comment*/
function zeitfresser_get_default_post_detail_comment() {
return true;
}
/* Default Post Detail Date*/
function zeitfresser_get_default_post_detail_date() {
return true;
}
/* Default Post Detail Featured Image*/
function zeitfresser_get_default_post_detail_featured_image() {
return false;
}
/* Default Post Detail Tag*/
function zeitfresser_get_default_post_detail_featured_image_size() {
return esc_html__( 'large', 'zeitfresser' );
}
/* Default Post Detail Tag*/
function zeitfresser_get_default_post_detail_tag() {
return false;
}
/* Default Post Detail Social Share */
function zeitfresser_get_default_post_detail_social_share() {
return false;
}
/* Default Post Detail Social Share Options*/
function zeitfresser_get_default_post_detail_social_share_options() {
return array();
}
/* Default Post Detail Author Block Options */
function zeitfresser_get_default_post_detail_author_block() {
return false;
}
/* Default Post Detail Related Articles Options*/
function zeitfresser_get_default_post_detail_related_articles() {
return true;
}
/* Default Post Detail Related Articles Title */
function zeitfresser_get_default_post_detail_related_articles_title() {
return esc_html__( "Related Articles", 'zeitfresser' );
}
-9
View File
@@ -1,9 +0,0 @@
<?php
/**
* Post detail defaults only.
*
* The frontend still uses these defaults, but the related controls are intentionally
* hidden to keep the customizer lean for the Zeitfresser setup.
*/
require dirname( __FILE__ ) . '/default-post-detail.php';
@@ -1,61 +0,0 @@
<?php
/* Default Post Snippet Author*/
function zeitfresser_get_default_post_snippet_author() {
return false;
}
/* Default Post Snippet Category*/
function zeitfresser_get_default_post_snippet_category() {
return false;
}
/* Default Post Snippet Comment*/
function zeitfresser_get_default_post_snippet_comment() {
return false;
}
/* Default Post Snippet Date*/
function zeitfresser_get_default_post_snippet_date() {
return false;
}
/* Default Post Snippet Featured Image*/
function zeitfresser_get_default_post_snippet_featured_image() {
return true;
}
/* Default Post Snippet Tag*/
function zeitfresser_get_default_post_snippet_featured_image_size() {
return esc_html__( 'thumbnail', 'zeitfresser' );
}
/* Default Post Snippet Tag*/
function zeitfresser_get_default_post_snippet_tag() {
return false;
}
/* Default Post Snippet Excerpt Szie */
function zeitfresser_get_default_post_snippet_excerpt_size() {
return 20;
}
/* Default Post Snippet Read More */
function zeitfresser_get_default_post_snippet_show_hide_read_more() {
return false;
}
/* Default Post Snippet Read More Text */
function zeitfresser_get_default_post_snippet_read_more_text() {
return esc_html__( "Read More", 'zeitfresser' );
}
/* Default Post Snippet Social Share */
function zeitfresser_get_default_post_snippet_social_share() {
return false;
}
/* Default Post Snippet Social Share Options*/
function zeitfresser_get_default_post_snippet_social_share_options() {
return array();
}
@@ -1,23 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_post_snippet_excerpt_size' );
function zeitfresser_post_snippet_excerpt_size( $wp_customize ) {
$wp_customize->add_setting( 'post_snippet_excerpt_size', array(
'sanitize_callback' => 'absint',
'default' => zeitfresser_get_default_post_snippet_excerpt_size()
) );
$wp_customize->add_control( 'post_snippet_excerpt_size', array(
'settings' => 'post_snippet_excerpt_size',
'type' => 'number',
'section' => 'daisy_blog_general_customization_section',
'label' => esc_html__( 'Excerpt Size', 'zeitfresser' ),
'priority' => 11,
'input_attrs' => array(
'min' => 5,
'max' => 80,
),
) );
}
-25
View File
@@ -1,25 +0,0 @@
<?php
/**
* Post snippet customizer section.
*/
add_action( 'customize_register', 'zeitfresser_register_post_snippet_customization_section' );
/**
* Register the post snippet section.
*
* @param WP_Customize_Manager $wp_customize Customizer manager.
* @return void
*/
function zeitfresser_register_post_snippet_customization_section( $wp_customize ) {
$wp_customize->add_section(
'daisy_blog_post_snippet_customization_section',
array(
'title' => esc_html__( 'Post Snippet', 'zeitfresser' ),
'priority' => 22,
)
);
}
require dirname( __FILE__ ) . '/default-post-snippet.php';
require dirname( __FILE__ ) . '/excerpt/excerpt.php';
@@ -1,11 +0,0 @@
<?php
/* Default Site Title Show Hide Option */
function zeitfresser_get_default_site_title_show_hide() {
return true;
}
/* Default Site Tagline Show Hide Option */
function zeitfresser_get_default_site_tagline_show_hide() {
return true;
}
@@ -1,9 +0,0 @@
<?php
/* Default Site Identity Settings */
require dirname( __FILE__ ) . '/default-site-identity.php';
require dirname( __FILE__ ) . '/site-title/site-title.php';
require dirname( __FILE__ ) . '/site-tagline/site-tagline.php';
@@ -1,18 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_show_hide_site_tagline' );
function zeitfresser_show_hide_site_tagline( $wp_customize ) {
$wp_customize->add_setting( 'show_hide_site_tagline', array(
'sanitize_callback' => 'zeitfresser_sanitize_checkbox',
'default' => zeitfresser_get_default_site_tagline_show_hide()
) );
$wp_customize->add_control( new Graphthemes_Toggle_Control( $wp_customize, 'show_hide_site_tagline', array(
'label' => esc_html__( 'Show/Hide Site Tagline','zeitfresser' ),
'section' => 'title_tagline',
'settings' => 'show_hide_site_tagline',
'type'=> 'toggle',
) ) );
}
@@ -1,18 +0,0 @@
<?php
add_action( 'customize_register', 'zeitfresser_show_hide_site_title' );
function zeitfresser_show_hide_site_title( $wp_customize ) {
$wp_customize->add_setting( 'show_hide_site_title', array(
'sanitize_callback' => 'zeitfresser_sanitize_checkbox',
'default' => zeitfresser_get_default_site_title_show_hide(),
) );
$wp_customize->add_control( new Graphthemes_Toggle_Control( $wp_customize, 'show_hide_site_title', array(
'label' => esc_html__( 'Show/Hide Site Title','zeitfresser' ),
'section' => 'title_tagline',
'settings' => 'show_hide_site_title',
'type'=> 'toggle',
) ) );
}
-78
View File
@@ -1,78 +0,0 @@
<?php
/**
* Sample implementation of the Custom Header feature
*
* You can add an optional custom header image to header.php like so ...
*
<?php the_header_image_tag(); ?>
*
* @link https://developer.wordpress.org/themes/functionality/custom-headers/
*
* @package zeitfresser
*/
/**
* Set up the WordPress core custom header feature.
*
* @uses zeitfresser_header_style()
*/
function zeitfresser_custom_header_setup() {
add_theme_support(
'custom-header',
apply_filters(
'daisy_blog_custom_header_args',
array(
'default-image' => '',
'default-text-color' => '444444',
'width' => 1000,
'height' => 250,
'flex-height' => true,
'wp-head-callback' => 'zeitfresser_header_style',
)
)
);
}
add_action( 'after_setup_theme', 'zeitfresser_custom_header_setup' );
if ( ! function_exists( 'zeitfresser_header_style' ) ) :
/**
* Styles the header image and text displayed on the blog.
*
* @see zeitfresser_custom_header_setup().
*/
function zeitfresser_header_style() {
$header_text_color = get_header_textcolor();
/*
* If no custom options for text are set, let's bail.
* get_header_textcolor() options: Any hex value, 'blank' to hide text. Default: add_theme_support( 'custom-header' ).
*/
if ( get_theme_support( 'custom-header', 'default-text-color' ) === $header_text_color ) {
return;
}
// If we get this far, we have custom styles. Let's do this.
?>
<style type="text/css">
<?php
// Has the text been hidden?
if ( ! display_header_text() ) :
?>
.site-title,
.site-description {
position: absolute;
clip: rect(1px, 1px, 1px, 1px);
}
<?php
// If the user has set a custom color for the text use that.
else :
?>
.site-title a,
.site-description {
color: #<?php echo esc_attr( $header_text_color ); ?>;
}
<?php endif; ?>
</style>
<?php
}
endif;

Some files were not shown because too many files have changed in this diff Show More