first commit

This commit is contained in:
Sophia Atkinson 2023-09-08 01:45:46 -07:00
commit 8cbf53172b
108 changed files with 29005 additions and 0 deletions

78
comments.php Normal file
View File

@ -0,0 +1,78 @@
<?php
/**
* The template for displaying comments.
*
* This is the template that displays the area of the page that contains both the current comments
* and the comment form.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package PressBook
*/
/*
* If the current post is protected by a password and
* the visitor has not yet entered the password we will
* return early without loading the comments.
*/
if ( post_password_required() ) {
return;
}
?>
<div id="comments" class="comments-area">
<?php
if ( have_comments() ) {
?>
<h2 class="comments-title">
<?php
$pressbook_comment_count = get_comments_number();
printf(
wp_kses(
/* translators: 1: number of comments, 2: post title */
_nx(
'Comment <span class="comments-title-count">(%1$s)</span><span class="screen-reader-text"> on &ldquo;%2$s&rdquo;</span>',
'Comments <span class="comments-title-count">(%1$s)</span><span class="screen-reader-text"> on &ldquo;%2$s&rdquo;</span>',
$pressbook_comment_count,
'comments title',
'pressbook'
),
array( 'span' => array( 'class' => array() ) )
),
esc_html( number_format_i18n( $pressbook_comment_count ) ),
wp_kses_post( get_the_title() )
);
?>
</h2><!-- .comments-title -->
<?php the_comments_navigation(); ?>
<ol class="comment-list">
<?php
wp_list_comments(
array(
'style' => 'ol',
'short_ping' => true,
'avatar_size' => 32,
)
);
?>
</ol><!-- .comment-list -->
<?php
the_comments_navigation();
// If comments are closed and there are comments, let's leave a little note, shall we?
if ( ! comments_open() ) {
?>
<p class="no-comments"><?php esc_html_e( 'Comments are closed.', 'pressbook' ); ?></p>
<?php
}
} // Check for have_comments().
comment_form();
?>
</div><!-- #comments -->

278
editor-style-rtl.css Normal file
View File

@ -0,0 +1,278 @@
body {
color: #404040;
font-size: 16px;
font-size: 1rem;
line-height: 1.75;
}
@media screen and (min-width: 768px) {
body {
font-size: 17px;
font-size: 1.0625rem;
}
}
.editor-post-title__input,
.editor-post-title .editor-post-title__input,
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.5;
}
.editor-post-title__input,
.editor-post-title .editor-post-title__input {
margin-top: 0;
margin-bottom: .45em;
padding: 19px 0;
font-size: 1.46em;
}
h1 {
font-size: 1.94em;
margin: .67em 0;
}
h2 {
font-size: 1.78em;
margin: .73em 0;
}
h3 {
font-size: 1.62em;
margin: .8em 0;
}
h4 {
font-size: 1.46em;
margin: .89em 0;
}
h5 {
font-size: 1.3em;
margin: 1em 0;
}
h6 {
font-size: 1.14em;
margin: 1.14em 0;
}
p {
margin-bottom: 1.5em;
}
a {
text-decoration: underline;
transition: color .2s;
}
a {
color: #166dd6;
}
a:hover,
a:focus,
a:active {
color: #f69275;
}
a:focus {
outline: thin dotted;
}
a:focus:not(:focus-visible),
a:hover,
a:active {
outline: 0;
}
p.has-text-color a,
p.has-text-color a:hover,
p.has-text-color a:focus,
p.has-text-color a:active {
color: inherit;
}
ul,
ol {
margin: 1.5em 0 1.5em 0;
padding-right: 1em;
}
ul {
list-style-type: disc;
}
ol {
list-style-type: decimal;
}
li>ul,
li>ol {
margin-top: 0;
margin-bottom: 0;
margin-right: 1.5em;
}
li:not(:first-child) {
padding-top: .2em;
}
li:not(:last-child) {
padding-bottom: .2em;
}
li>ul>li:first-child,
li>ol>li:first-child {
padding-top: .4em;
}
blockquote {
margin: 0 1.5em;
}
.wp-block-quote p {
margin-bottom: .75em;
}
.wp-block-quote.is-large p,
.wp-block-quote.is-style-large p {
font-size: 1.3em;
}
.wp-block-quote__citation,
.wp-block-quote cite,
.wp-block-quote footer {
font-size: .85em;
}
.wp-block-quote.is-large cite,
.wp-block-quote.is-large footer,
.wp-block-quote.is-style-large cite,
.wp-block-quote.is-style-large footer {
font-size: .95em;
}
.wp-block-quote,
.wp-block-quote.is-large,
.wp-block-quote.is-style-large {
margin-bottom: 1.75em;
}
.wp-block-pullquote {
padding: 2.4em 0;
}
.wp-block-pullquote p {
font-size: 1.75em;
margin-bottom: 0;
}
.wp-block-pullquote__citation,
.wp-block-pullquote cite,
.wp-block-pullquote footer {
display: block;
margin-top: 1.5em;
}
.wp-block-pullquote.is-style-solid-color blockquote p {
font-size: 1.9em;
}
.wp-block-pullquote.is-style-solid-color blockquote {
max-width: 70%;
}
.wp-block-table,
.wp-block-video,
.wp-block-audio,
.wp-block-embed,
.wp-block-image,
.wp-block-gallery,
.wp-block-media-text,
.wp-block-calendar {
margin-bottom: 1.5em;
}
.wp-block-calendar table:where(:not(.has-text-color)) {
color: inherit;
}
.wp-block-table table,
.wp-block-calendar .wp-calendar-table {
margin-bottom: 0;
}
.wp-block-calendar .wp-calendar-nav {
margin-top: .5em;
}
.wp-block-image img {
display: block;
}
.wp-block-table figcaption,
.wp-block-video figcaption,
.wp-block-embed figcaption,
.wp-block-image figcaption,
.wp-block-gallery figcaption {
font-size: .85em;
}
.wp-block-table figcaption,
.wp-block-video figcaption,
.wp-block-embed figcaption {
margin-top: 1em;
margin-bottom: 0;
}
.wp-block-audio figcaption {
margin-top: .75em;
margin-bottom: 0;
font-size: .8em;
}
.wp-block-table.is-style-stripes {
border-bottom: 0;
}
.wp-block-code>code {
color: inherit;
}
pre.wp-block-verse {
font-family: 'Courier 10 Pitch', courier, monospace;
}
.wp-block-search .wp-block-search__button {
margin-right: 0;
}
.wp-block-rss {
padding: 0;
list-style-type: none;
}
.wp-block-rss .wp-block-rss__item:not(:last-child) {
margin-bottom: 1em;
}
.wp-block-rss .wp-block-rss__item:not(:first-child) {
padding-top: 0;
}
.wp-block-latest-comments__comment {
line-height: inherit;
}
.wp-block-button__link {
text-decoration: none;
}
.wp-block-social-links .wp-block-social-link {
padding: 0;
}

278
editor-style.css Normal file
View File

@ -0,0 +1,278 @@
body {
color: #404040;
font-size: 16px;
font-size: 1rem;
line-height: 1.75;
}
@media screen and (min-width: 768px) {
body {
font-size: 17px;
font-size: 1.0625rem;
}
}
.editor-post-title__input,
.editor-post-title .editor-post-title__input,
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.5;
}
.editor-post-title__input,
.editor-post-title .editor-post-title__input {
margin-top: 0;
margin-bottom: .45em;
padding: 19px 0;
font-size: 1.46em;
}
h1 {
font-size: 1.94em;
margin: .67em 0;
}
h2 {
font-size: 1.78em;
margin: .73em 0;
}
h3 {
font-size: 1.62em;
margin: .8em 0;
}
h4 {
font-size: 1.46em;
margin: .89em 0;
}
h5 {
font-size: 1.3em;
margin: 1em 0;
}
h6 {
font-size: 1.14em;
margin: 1.14em 0;
}
p {
margin-bottom: 1.5em;
}
a {
text-decoration: underline;
transition: color .2s;
}
a {
color: #166dd6;
}
a:hover,
a:focus,
a:active {
color: #f69275;
}
a:focus {
outline: thin dotted;
}
a:focus:not(:focus-visible),
a:hover,
a:active {
outline: 0;
}
p.has-text-color a,
p.has-text-color a:hover,
p.has-text-color a:focus,
p.has-text-color a:active {
color: inherit;
}
ul,
ol {
margin: 1.5em 0 1.5em 0;
padding-left: 1em;
}
ul {
list-style-type: disc;
}
ol {
list-style-type: decimal;
}
li>ul,
li>ol {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
li:not(:first-child) {
padding-top: .2em;
}
li:not(:last-child) {
padding-bottom: .2em;
}
li>ul>li:first-child,
li>ol>li:first-child {
padding-top: .4em;
}
blockquote {
margin: 0 1.5em;
}
.wp-block-quote p {
margin-bottom: .75em;
}
.wp-block-quote.is-large p,
.wp-block-quote.is-style-large p {
font-size: 1.3em;
}
.wp-block-quote__citation,
.wp-block-quote cite,
.wp-block-quote footer {
font-size: .85em;
}
.wp-block-quote.is-large cite,
.wp-block-quote.is-large footer,
.wp-block-quote.is-style-large cite,
.wp-block-quote.is-style-large footer {
font-size: .95em;
}
.wp-block-quote,
.wp-block-quote.is-large,
.wp-block-quote.is-style-large {
margin-bottom: 1.75em;
}
.wp-block-pullquote {
padding: 2.4em 0;
}
.wp-block-pullquote p {
font-size: 1.75em;
margin-bottom: 0;
}
.wp-block-pullquote__citation,
.wp-block-pullquote cite,
.wp-block-pullquote footer {
display: block;
margin-top: 1.5em;
}
.wp-block-pullquote.is-style-solid-color blockquote p {
font-size: 1.9em;
}
.wp-block-pullquote.is-style-solid-color blockquote {
max-width: 70%;
}
.wp-block-table,
.wp-block-video,
.wp-block-audio,
.wp-block-embed,
.wp-block-image,
.wp-block-gallery,
.wp-block-media-text,
.wp-block-calendar {
margin-bottom: 1.5em;
}
.wp-block-calendar table:where(:not(.has-text-color)) {
color: inherit;
}
.wp-block-table table,
.wp-block-calendar .wp-calendar-table {
margin-bottom: 0;
}
.wp-block-calendar .wp-calendar-nav {
margin-top: .5em;
}
.wp-block-image img {
display: block;
}
.wp-block-table figcaption,
.wp-block-video figcaption,
.wp-block-embed figcaption,
.wp-block-image figcaption,
.wp-block-gallery figcaption {
font-size: .85em;
}
.wp-block-table figcaption,
.wp-block-video figcaption,
.wp-block-embed figcaption {
margin-top: 1em;
margin-bottom: 0;
}
.wp-block-audio figcaption {
margin-top: .75em;
margin-bottom: 0;
font-size: .8em;
}
.wp-block-table.is-style-stripes {
border-bottom: 0;
}
.wp-block-code>code {
color: inherit;
}
pre.wp-block-verse {
font-family: 'Courier 10 Pitch', courier, monospace;
}
.wp-block-search .wp-block-search__button {
margin-left: 0;
}
.wp-block-rss {
padding: 0;
list-style-type: none;
}
.wp-block-rss .wp-block-rss__item:not(:last-child) {
margin-bottom: 1em;
}
.wp-block-rss .wp-block-rss__item:not(:first-child) {
padding-top: 0;
}
.wp-block-latest-comments__comment {
line-height: inherit;
}
.wp-block-button__link {
text-decoration: none;
}
.wp-block-social-links .wp-block-social-link {
padding: 0;
}

36
footer.php Normal file
View File

@ -0,0 +1,36 @@
<?php
/**
* The template for displaying the footer.
*
* Contains the closing of the #content div and all content after.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package PressBook
*/
?>
</div><!-- #content -->
<footer id="colophon" class="site-footer">
<?php
do_action( 'pressbook_after_footer_start' );
get_template_part( 'template-parts/footer/block-section' );
get_template_part( 'template-parts/footer/widgets' );
get_template_part( 'template-parts/footer/copyright-text' );
do_action( 'pressbook_before_footer_end' );
?>
</footer><!-- #colophon -->
<?php if ( ! PressBook\Options\Footer::get_hide_go_to_top() ) { ?>
<a href="#" class="go-to-top" aria-label="<?php esc_attr_e( 'Go to top', 'pressbook' ); ?>"></a>
<?php } ?>
</div><!-- #page -->
<?php wp_footer(); ?>
</body>
</html>

27
functions.php Normal file
View File

@ -0,0 +1,27 @@
<?php
/**
* PressBook functions and definitions.
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package PressBook
*/
defined( 'ABSPATH' ) || die();
define( 'PRESSBOOK_VERSION', '1.9.1' );
// This theme requires WordPress 5.3 or later.
if ( version_compare( $GLOBALS['wp_version'], '5.3', '<' ) ) {
require get_template_directory() . '/inc/back-compat.php';
}
require get_template_directory() . '/inc/libs/class-tgm-plugin-activation.php';
require get_template_directory() . '/inc/libs/class-wptt-webfont-loader.php';
require get_template_directory() . '/inc/libs/class-pressbook-upsell-section.php';
require get_template_directory() . '/inc/libs/class-pressbook-upsell-control.php';
require get_template_directory() . '/inc/vendor/autoload.php';
require get_template_directory() . '/inc/recommended-plugins.php';
require get_template_directory() . '/inc/welcome-page.php';
PressBook\Theme::init();

42
header.php Normal file
View File

@ -0,0 +1,42 @@
<?php
/**
* 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 PressBook
*/
?><!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="profile" href="https://gmpg.org/xfn/11">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<div id="page" class="site">
<a class="skip-link screen-reader-text" href="#content"><?php esc_html_e( 'Skip to content', 'pressbook' ); ?></a>
<header id="masthead" class="site-header">
<?php
do_action( 'pressbook_after_header_start' );
get_template_part( 'template-parts/header/top-navbar' );
get_template_part( 'template-parts/header/site-branding' );
get_template_part( 'template-parts/header/primary-navbar' );
get_template_part( 'template-parts/header/block-section' );
do_action( 'pressbook_before_header_end' );
?>
</header><!-- #masthead -->
<div id="content" class="site-content">

136
inc/alpha-color-picker.css Normal file
View File

@ -0,0 +1,136 @@
/**
* Alpha Color Picker CSS
*/
.customize-control-alpha-color .wp-picker-container .iris-picker {
border-bottom: none;
}
.customize-control-alpha-color .wp-picker-container {
max-width: 257px;
}
.customize-control-alpha-color .wp-picker-open+.wp-picker-input-wrap {
width: 100%;
}
.customize-control-alpha-color .wp-picker-input-wrap input[type="text"].wp-color-picker.alpha-color-control {
float: left;
width: 195px;
}
.customize-control-alpha-color .wp-picker-input-wrap label {
display: unset;
}
.customize-control-alpha-color .iris-palette {
height: 22.79px;
width: 22.79px;
}
.customize-control-alpha-color .wp-picker-input-wrap .button {
margin-left: 0;
float: right;
}
.wp-picker-container .wp-picker-open~.wp-picker-holder .alpha-color-picker-container {
display: block;
}
.alpha-color-picker-container {
border: 1px solid #dfdfdf;
border-top: none;
display: none;
background: #FFF;
padding: 0 11px 10px;
position: relative;
}
.alpha-color-picker-container .ui-widget-content,
.alpha-color-picker-container .ui-widget-header,
.alpha-color-picker-wrap .ui-state-focus {
background: transparent;
border: none;
}
.alpha-color-picker-wrap a.iris-square-value:focus {
-webkit-box-shadow: none;
box-shadow: none;
}
.alpha-color-picker-container .ui-slider {
position: relative;
z-index: 1;
height: 24px;
text-align: center;
margin: 0 auto;
width: 88%;
width: calc(100% - 28px);
}
.alpha-color-picker-container .ui-slider-handle,
.alpha-color-picker-container .ui-widget-content .ui-state-default {
color: #777;
background-color: #FFF;
text-shadow: 0 1px 0 #FFF;
text-decoration: none;
position: absolute;
z-index: 2;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
border: 1px solid #aaa;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
margin-top: -2px;
top: 0;
height: 26px;
width: 26px;
cursor: ew-resize;
font-size: 0;
padding: 0;
line-height: 27px;
margin-left: -14px;
}
.alpha-color-picker-container .ui-slider-handle.show-opacity {
font-size: 12px;
}
.alpha-color-picker-container .click-zone {
width: 14px;
height: 24px;
display: block;
position: absolute;
left: 10px;
}
.alpha-color-picker-container .max-click-zone {
right: 10px;
left: auto;
}
.alpha-color-picker-container .transparency {
height: 24px;
width: 100%;
background-color: #FFF;
background-image: url(transparency-grid.png);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.4) inset;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
padding: 0;
margin-top: -24px;
}
@media only screen and (max-width: 782px) {
.customize-control-alpha-color .wp-picker-input-wrap input[type="text"].wp-color-picker.alpha-color-control {
width: 184px;
}
}
@media only screen and (max-width: 640px) {
.customize-control-alpha-color .wp-picker-input-wrap input[type="text"].wp-color-picker.alpha-color-control {
width: 172px;
height: 33px;
}
}

70
inc/back-compat.php Normal file
View File

@ -0,0 +1,70 @@
<?php
/**
* Back compat functionality.
*
* @package PressBook
*/
/**
* Display upgrade notice on theme switch.
*/
function pressbook_switch_theme() {
add_action( 'admin_notices', 'pressbook_upgrade_notice' );
}
add_action( 'after_switch_theme', 'pressbook_switch_theme' );
/**
* Adds a message for unsuccessful theme switch.
*
* Prints an update nag after an unsuccessful attempt to switch to
* the theme on WordPress versions prior to 5.3.
*
* @global string $wp_version WordPress version.
*/
function pressbook_upgrade_notice() {
echo '<div class="error"><p>';
printf(
/* translators: %s: WordPress Version. */
esc_html__( 'This theme requires WordPress 5.3 or newer. You are running version %s. Please upgrade.', 'pressbook' ),
esc_html( $GLOBALS['wp_version'] )
);
echo '</p></div>';
}
/**
* Prevents the Customizer from being loaded on WordPress versions prior to 5.3.
*
* @global string $wp_version WordPress version.
*/
function pressbook_customize() {
wp_die(
sprintf(
/* translators: %s: WordPress Version. */
esc_html__( 'This theme requires WordPress 5.3 or newer. You are running version %s. Please upgrade.', 'pressbook' ),
esc_html( $GLOBALS['wp_version'] )
),
'',
array(
'back_link' => true,
)
);
}
add_action( 'load-customize.php', 'pressbook_customize' );
/**
* Prevents the Theme Preview from being loaded on WordPress versions prior to 5.3.
*
* @global string $wp_version WordPress version.
*/
function pressbook_preview() {
if ( isset( $_GET['preview'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
wp_die(
sprintf(
/* translators: %s: WordPress Version. */
esc_html__( 'This theme requires WordPress 5.3 or newer. You are running version %s. Please upgrade.', 'pressbook' ),
esc_html( $GLOBALS['wp_version'] )
)
);
}
}
add_action( 'template_redirect', 'pressbook_preview' );

575
inc/core/CSSRules.php Normal file
View File

@ -0,0 +1,575 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* CSS Rules.
*
* @package PressBook
*/
namespace PressBook;
use PressBook\Options\Sanitizer;
/**
* Generate dynamic CSS rules for theme.
*/
class CSSRules {
/**
* CSS rules for the final output.
*
* @return string.
*/
public static function output() {
$saved_styles = self::saved_styles();
$styles_keys = array_keys( $saved_styles );
$output = '';
foreach ( $styles_keys as $styles_key ) {
if ( method_exists( static::class, $styles_key ) ) {
$rules = static::$styles_key( $saved_styles[ $styles_key ] );
foreach ( $rules as $selector => $props ) {
$output_selector = ( $selector . '{' );
$append_selector = false;
foreach ( $props as $prop => $value ) {
if ( ! array_key_exists( 'skip', $value ) ) {
$output_selector .= ( $prop . ':' . $value['value'] . ';' );
$append_selector = true;
}
}
$output_selector .= '}';
if ( $append_selector ) {
$output .= $output_selector;
}
}
}
}
return $output;
}
/**
* CSS rules for the final output in array format.
*
* @return array.
*/
public static function output_array() {
$saved_styles = self::saved_styles();
$styles_keys = array_keys( $saved_styles );
$output = array();
foreach ( $styles_keys as $styles_key ) {
$output[ $styles_key ] = array();
if ( method_exists( static::class, $styles_key ) ) {
$rules = static::$styles_key( $saved_styles[ $styles_key ] );
foreach ( $rules as $selector => $props ) {
$output[ $styles_key ][ $selector ] = $props;
}
}
}
return $output;
}
/**
* CSS rules for the final output in the editor.
*/
public static function output_editor() {
$saved_styles = self::saved_styles();
$styles_keys = Editor::styles_keys();
$output = '';
foreach ( $styles_keys as $styles_key ) {
if ( method_exists( Editor::class, $styles_key ) ) {
$rules = Editor::$styles_key( $saved_styles[ $styles_key ] );
foreach ( $rules as $selector => $props ) {
$output_selector = ( '.editor-styles-wrapper' . str_replace( ',', ',.editor-styles-wrapper', $selector ) . '{' );
$append_selector = false;
foreach ( $props as $prop => $value ) {
if ( ! array_key_exists( 'skip', $value ) ) {
$output_selector .= ( $prop . ':' . $value['value'] . ';' );
$append_selector = true;
}
}
$output_selector .= '}';
if ( $append_selector ) {
$output .= $output_selector;
}
}
}
}
return $output;
}
/**
* CSS rules for the final output in the widgets editor legacy.
*/
public static function output_widgets_editor_legacy() {
$saved_styles = self::saved_styles();
$styles_keys = Widget::legacy_styles_keys();
$output = '';
foreach ( $styles_keys as $styles_key ) {
if ( method_exists( static::class, $styles_key ) ) {
$rules = static::$styles_key( $saved_styles[ $styles_key ] );
foreach ( $rules as $selector => $props ) {
$output_selector = ( $selector . '{' );
$append_selector = false;
foreach ( $props as $prop => $value ) {
if ( ! array_key_exists( 'skip', $value ) ) {
$output_selector .= ( $prop . ':' . $value['value'] . ';' );
$append_selector = true;
}
}
$output_selector .= '}';
if ( $append_selector ) {
$output .= $output_selector;
}
}
}
}
return $output;
}
/**
* Get saved styles.
*
* @return array.
*/
public static function saved_styles() {
return wp_parse_args(
get_theme_mod( 'set_styles', array() ),
self::default_styles()
);
}
/**
* Get default styles.
*
* @param string $key Color setting key.
* @return string|array.
*/
public static function default_styles( $key = '' ) {
$styles = apply_filters(
'pressbook_default_styles',
array(
'header_bg_position' => 'center-center',
'header_bg_repeat' => 'repeat',
'header_bg_size' => 'contain',
'top_banner_max_height' => '150',
'top_navbar_bg_color_1' => '#166dd6',
'top_navbar_bg_color_2' => '#1257ab',
'primary_navbar_bg_color' => '#166dd6',
'header_bg_color' => '#ffffff',
'site_title_color' => '#404040',
'tagline_color' => '#979797',
'button_bg_color_1' => '#f3c841',
'button_bg_color_2' => '#f69275',
'button_font_wgt' => '600',
'heading_font_wgt' => '700',
'site_title_font_wgt' => '700',
'side_widget_border_color' => '#fafafa',
'footer_bg_color' => '#232323',
'footer_credit_link_color' => '#f69275',
)
);
if ( array_key_exists( $key, $styles ) ) {
return $styles[ $key ];
}
return $styles;
}
/**
* Header Background Position.
*
* @param string $value Position value.
* @return array
*/
public static function header_bg_position( $value ) {
return array(
'.site-branding' => array(
'background-position' => array(
'value' => esc_attr( str_replace( '-', ' ', $value ) ),
'place' => '_PLACE',
),
),
);
}
/**
* Header Background Repeat.
*
* @param string $value Repeat value.
* @return array
*/
public static function header_bg_repeat( $value ) {
return array(
'.site-branding' => array(
'background-repeat' => array(
'value' => esc_attr( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Header Background Size.
*
* @param string $value Size value.
* @return array
*/
public static function header_bg_size( $value ) {
return array(
'.site-branding' => array(
'background-size' => array(
'value' => esc_attr( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Top Banner Max Height.
*
* @param string $value Max Height value.
* @return array
*/
public static function top_banner_max_height( $value ) {
return array(
'.top-banner-image' => array(
'max-height' => array(
'value' => ( absint( $value ) . 'px' ),
'place' => '_PLACEpx',
),
),
);
}
/**
* Top Navbar Background Color 1.
*
* @param string $value Color value.
* @return array
*/
public static function top_navbar_bg_color_1( $value ) {
$color_2 = self::saved_styles()['top_navbar_bg_color_2'];
return array(
'.top-navbar' => array(
'background' => array(
'value' => ( 'linear-gradient(0deg, ' . Sanitizer::sanitize_alpha_color( $value ) . ' 0%, ' . Sanitizer::sanitize_alpha_color( $color_2 ) . ' 100%)' ),
'place' => 'linear-gradient(0deg, _PLACE 0%, _EXTRA_COLOR_2 100%)',
'extra' => array(
'top_navbar_bg_color_2' => '_EXTRA_COLOR_2',
),
'remove' => array(
'top_navbar_bg_color_2',
),
),
),
'.social-navigation a:active .svg-icon,.social-navigation a:focus .svg-icon,.social-navigation a:hover .svg-icon' => array(
'color' => array(
'value' => Sanitizer::sanitize_alpha_color( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Top Navbar Background Color 2.
*
* @param string $value Color value.
* @return array
*/
public static function top_navbar_bg_color_2( $value ) {
$color_1 = self::saved_styles()['top_navbar_bg_color_1'];
$rules = array(
'.top-navbar' => array(
'background' => array(
'skip' => true,
'value' => ( 'linear-gradient(0deg, ' . Sanitizer::sanitize_alpha_color( $color_1 ) . ' 0%, ' . Sanitizer::sanitize_alpha_color( $value ) . ' 100%)' ),
'place' => 'linear-gradient(0deg, _EXTRA_COLOR_1 0%, _PLACE 100%)',
'extra' => array(
'top_navbar_bg_color_1' => '_EXTRA_COLOR_1',
),
'remove' => array(
'top_navbar_bg_color_1',
),
),
),
);
if ( is_customize_preview() ) {
$rules['.social-navigation a:active .svg-icon,.social-navigation a:focus .svg-icon,.social-navigation a:hover .svg-icon'] = array(
'color' => array(
'value' => Sanitizer::sanitize_alpha_color( $color_1 ),
'place' => '_EXTRA_COLOR_1',
'extra' => array(
'top_navbar_bg_color_1' => '_EXTRA_COLOR_1',
),
'remove' => array(
'top_navbar_bg_color_1',
),
),
);
}
return $rules;
}
/**
* Primary Navbar Background Color.
*
* @param string $value Color value.
* @return array
*/
public static function primary_navbar_bg_color( $value ) {
return array(
'.primary-navbar,.main-navigation ul ul' => array(
'background' => array(
'value' => Sanitizer::sanitize_alpha_color( $value ),
'place' => '_PLACE',
),
),
'.main-navigation .main-navigation-arrow-btn:active,.main-navigation .main-navigation-arrow-btn:hover,.main-navigation li.focus>.main-navigation-arrow-btn,.main-navigation:not(.toggled) li:hover>.main-navigation-arrow-btn,.main-navigation a:active,.main-navigation a:focus,.main-navigation a:hover' => array(
'color' => array(
'value' => Sanitizer::sanitize_alpha_color( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Header Background Color.
*
* @param string $value Color value.
* @return array
*/
public static function header_bg_color( $value ) {
return array(
'.site-branding' => array(
'background-color' => array(
'value' => Sanitizer::sanitize_alpha_color( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Site Title Color.
*
* @param string $value Color value.
* @return array
*/
public static function site_title_color( $value ) {
return array(
'.site-title,.site-title a,.site-title a:active,.site-title a:focus,.site-title a:hover' => array(
'color' => array(
'value' => sanitize_hex_color( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Tagline Color.
*
* @param string $value Color value.
* @return array
*/
public static function tagline_color( $value ) {
return array(
'.site-tagline' => array(
'color' => array(
'value' => sanitize_hex_color( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Button Background Color 1.
*
* @param string $value Color value.
* @return array
*/
public static function button_bg_color_1( $value ) {
$color_2 = self::saved_styles()['button_bg_color_2'];
return array(
'.more-link,.wp-block-search .wp-block-search__button,button,input[type=button],input[type=reset],input[type=submit]' => array(
'background-image' => array(
'value' => ( 'linear-gradient(to right, ' . Sanitizer::sanitize_alpha_color( $value ) . ' 0%, ' . Sanitizer::sanitize_alpha_color( $color_2 ) . ' 51%, ' . Sanitizer::sanitize_alpha_color( $value ) . ' 100%)' ),
'place' => 'linear-gradient(to right, _PLACE 0%, _EXTRA_COLOR_2 51%, _PLACE 100%)',
'extra' => array(
'button_bg_color_2' => '_EXTRA_COLOR_2',
),
'remove' => array(
'button_bg_color_2',
),
),
),
);
}
/**
* Button Background Color 2.
*
* @param string $value Color value.
* @return array
*/
public static function button_bg_color_2( $value ) {
$color_1 = self::saved_styles()['button_bg_color_1'];
return array(
'.more-link,.wp-block-search .wp-block-search__button,button,input[type=button],input[type=reset],input[type=submit]' => array(
'background-image' => array(
'skip' => true,
'value' => ( 'linear-gradient(to right, ' . Sanitizer::sanitize_alpha_color( $color_1 ) . ' 0%, ' . Sanitizer::sanitize_alpha_color( $value ) . ' 51%, ' . Sanitizer::sanitize_alpha_color( $color_1 ) . ' 100%)' ),
'place' => 'linear-gradient(to right, _EXTRA_COLOR_1 0%, _PLACE 51%, _EXTRA_COLOR_1 100%)',
'extra' => array(
'button_bg_color_1' => '_EXTRA_COLOR_1',
),
'remove' => array(
'button_bg_color_1',
),
),
),
);
}
/**
* Button Font Weight.
*
* @param string $value Font weight value.
* @return array
*/
public static function button_font_wgt( $value ) {
return array(
'.more-link,.wp-block-search .wp-block-search__button,button,input[type=button],input[type=reset],input[type=submit]' => array(
'font-weight' => array(
'value' => absint( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Heading Font Weight.
*
* @param string $value Font weight value.
* @return array
*/
public static function heading_font_wgt( $value ) {
return array(
'h1,h2,h3,h4,h5,h6' => array(
'font-weight' => array(
'value' => absint( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Site Title Font Weight.
*
* @param string $value Font weight value.
* @return array
*/
public static function site_title_font_wgt( $value ) {
return array(
'.site-title' => array(
'font-weight' => array(
'value' => absint( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Side Widget Border Color.
*
* @param string $value Color value.
* @return array
*/
public static function side_widget_border_color( $value ) {
return array(
'.c-sidebar .widget' => array(
'border-color' => array(
'value' => Sanitizer::sanitize_alpha_color( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Footer Background Color.
*
* @param string $value Color value.
* @return array
*/
public static function footer_bg_color( $value ) {
return array(
'.footer-widgets,.copyright-text' => array(
'background' => array(
'value' => Sanitizer::sanitize_alpha_color( $value ),
'place' => '_PLACE',
),
),
);
}
/**
* Footer Credit Link Color.
*
* @param string $value Color value.
* @return array
*/
public static function footer_credit_link_color( $value ) {
return array(
'.copyright-text a' => array(
'color' => array(
'value' => sanitize_hex_color( $value ),
'place' => '_PLACE',
),
),
);
}
}

150
inc/core/Editor.php Normal file
View File

@ -0,0 +1,150 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Editor service.
*
* @package PressBook
*/
namespace PressBook;
use PressBook\Options\Content;
use PressBook\Options\Sanitizer;
/**
* Editor setup.
*/
class Editor implements Serviceable {
/**
* Register service features.
*/
public function register() {
add_action( 'after_setup_theme', array( $this, 'support_editor_styles' ) );
if ( version_compare( $GLOBALS['wp_version'], '6.2.99', '<=' ) ) {
add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_editor_assets' ) );
} else {
add_action( 'enqueue_block_assets', array( $this, 'enqueue_block_assets' ) );
}
}
/**
* Support editor styles.
*/
public function support_editor_styles() {
// Add support for editor styles.
add_theme_support( 'editor-styles' );
// Enqueue editor styles.
add_editor_style( 'editor-style.css' );
}
/**
* Enqueue editor assets.
*/
public function enqueue_editor_assets() {
if ( function_exists( '\get_current_screen' ) ) {
$current_screen = get_current_screen();
if ( $current_screen && in_array( $current_screen->id, array( 'widgets', 'nav-menus' ), true ) ) {
return;
}
$this->enqueue_assets();
}
}
/**
* Enqueue block assets.
*/
public function enqueue_block_assets() {
if ( $this->is_block_screen() ) {
$this->enqueue_assets();
}
}
/**
* Enqueue assets.
*/
public function enqueue_assets() {
// Enqueue fonts.
wp_enqueue_style( 'pressbook-editor-fonts', Scripts::fonts_url(), array(), null ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
// Add inline style for fonts in the block editor.
$this->load_editor_fonts_css();
// Add output of customizer settings as inline style.
wp_add_inline_style( 'pressbook-editor-fonts', CSSRules::output_editor() );
}
/**
* Check if block editor screen, but not widgets or nav-menus screen.
*
* @return bool
*/
public function is_block_screen() {
if ( function_exists( '\get_current_screen' ) ) {
$current_screen = get_current_screen();
if ( $current_screen ) {
if ( \in_array( $current_screen->id, array( 'widgets', 'nav-menus' ), true ) ) {
return false;
}
if ( \method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
return true;
}
}
}
return false;
}
/**
* Add inline style for fonts in the block editor.
*/
public function load_editor_fonts_css() {
$fonts_css = '';
/* translators: If there are characters in your language that are not supported by Inter, translate this to 'off'. Do not translate into your own language. */
$inter = _x( 'on', 'Inter font (in the editor): on or off', 'pressbook' );
if ( 'off' !== $inter ) {
$fonts_css .= ( '.editor-styles-wrapper.editor-styles-wrapper{font-family:\'Inter\', Arial, Helvetica, sans-serif;}' );
}
/* translators: If there are characters in your language that are not supported by Lato, translate this to 'off'. Do not translate into your own language. */
$lato = _x( 'on', 'Lato font (in the editor): on or off', 'pressbook' );
if ( 'off' !== $lato ) {
$fonts_css .= ( '.editor-styles-wrapper .editor-post-title__input,.editor-styles-wrapper .editor-post-title .editor-post-title__input,.editor-styles-wrapper h1,.editor-styles-wrapper h2,.editor-styles-wrapper h3,.editor-styles-wrapper h4,.editor-styles-wrapper h5,.editor-styles-wrapper h6{font-family:\'Lato\', Helvetica, Arial, sans-serif;}' );
}
if ( '' !== $fonts_css ) {
wp_add_inline_style( 'pressbook-editor-fonts', $fonts_css );
}
}
/**
* Styles keys for the editor CSS output.
*
* @return array
*/
public static function styles_keys() {
return apply_filters(
'pressbook_default_editor_styles_keys',
array( 'heading_font_wgt' )
);
}
/**
* Heading Font Weight.
*
* @param string $value Color value.
* @return array
*/
public static function heading_font_wgt( $value ) {
return array(
'.editor-styles-wrapper .editor-post-title__input,.editor-styles-wrapper .editor-post-title .editor-post-title__input,.editor-styles-wrapper h1,.editor-styles-wrapper h2,.editor-styles-wrapper h3,.editor-styles-wrapper h4,.editor-styles-wrapper h5,.editor-styles-wrapper h6' => array(
'font-weight' => array(
'value' => absint( $value ),
),
),
);
}
}

175
inc/core/Enhance.php Normal file
View File

@ -0,0 +1,175 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Enhance service.
*
* @package PressBook
*/
namespace PressBook;
use PressBook\Options\Blog;
use PressBook\Options\Content;
use PressBook\Options\General;
use PressBook\Options\Sidebar;
/**
* Enhance the theme by hooking into WordPress.
*/
class Enhance implements Serviceable {
/**
* Register service features.
*/
public function register() {
add_filter( 'body_class', array( $this, 'body_classes' ) );
add_action( 'wp_head', array( $this, 'pingback_header' ) );
add_filter( 'excerpt_more', array( $this, 'excerpt_more' ) );
add_filter( 'the_content_more_link', array( $this, 'content_more' ) );
add_filter( 'get_search_form', array( $this, 'search_form' ) );
}
/**
* Adds custom classes to the array of body classes.
*
* @param array $classes Classes for the body element.
* @return array
*/
public function body_classes( $classes ) {
// Adds a class of hfeed to non-singular pages.
if ( ! is_singular() ) {
$classes[] = 'hfeed';
}
if ( is_active_sidebar( 'sidebar-1' ) ) {
if ( is_active_sidebar( 'sidebar-2' ) ) {
$classes[] = 'double-sidebar left-right-sidebar';
} else {
$classes[] = 'single-sidebar right-sidebar';
}
} elseif ( is_active_sidebar( 'sidebar-2' ) ) {
$classes[] = 'single-sidebar left-sidebar';
} else {
$classes[] = 'no-sidebar';
}
// Adds a class of pb-content-columns where there is a layout set for the blog archive post.
$archive_post_layout_lg = Blog::get_archive_post_layout_lg();
if ( 'cover' === $archive_post_layout_lg ) {
$classes[] = 'pb-content-columns pb-content-cover';
} elseif ( 'columns' === $archive_post_layout_lg ) {
$classes[] = 'pb-content-columns';
}
$content_layout_class = Content::get_content_layout_body_class();
if ( '' !== $content_layout_class ) {
$classes[] = $content_layout_class;
}
$side_widget_class = Sidebar::get_side_widget_body_class();
if ( '' !== $side_widget_class ) {
$classes[] = $side_widget_class;
}
return $classes;
}
/**
* Add a pingback url auto-discovery header for single posts, pages, or attachments.
*/
public function pingback_header() {
if ( is_singular() && pings_open() ) {
printf( '<link rel="pingback" href="%s">', esc_url( get_bloginfo( 'pingback_url' ) ) );
}
}
/**
* Change the excerpt more string.
*
* @param string $more The string shown within the more link.
* @return string
*/
public function excerpt_more( $more ) {
if ( is_admin() ) {
return $more;
}
$more_text = General::get_read_more_text();
if ( '' === $more_text ) {
$more_text = esc_html__( 'Read More', 'pressbook' );
}
$more = ( '...<p class="more-link-wrap"><a href="' . esc_url( get_permalink() ) . '" class="more-link">' . sprintf(
wp_kses(
/* translators: 1: "Read More" text, 2: Name of current post. Only visible to screen readers */
_x( '%1$s<span class="screen-reader-text"> &ldquo;%2$s&rdquo;</span> &raquo;', 'excerpt more', 'pressbook' ),
array(
'span' => array(
'class' => array(),
),
)
),
esc_html( $more_text ),
wp_kses_post( get_the_title() )
) . '</a></p>' );
return apply_filters( 'pressbook_excerpt_more', $more );
}
/**
* Change the content more string.
*
* @param string $more The string shown within the more link.
* @return string
*/
public function content_more( $more ) {
if ( is_admin() ) {
return $more;
}
$more_text = General::get_read_more_text();
if ( '' === $more_text ) {
$more_text = esc_html__( 'Read More', 'pressbook' );
}
$more = ( '<p class="more-link-wrap"><a href="' . esc_url( get_permalink() . apply_filters( 'pressbook_more_jump', '#more-' . get_the_ID() ) ) . '" class="more-link">' . sprintf(
wp_kses(
/* translators: 1: "Read More" text, 2: Name of current post. Only visible to screen readers */
_x( '%1$s<span class="screen-reader-text"> &ldquo;%2$s&rdquo;</span> &raquo;', 'content more', 'pressbook' ),
array(
'span' => array(
'class' => array(),
),
)
),
esc_html( $more_text ),
wp_kses_post( get_the_title() )
) . '</a></p>' );
return apply_filters( 'pressbook_content_more', $more );
}
/**
* Change the search form button text.
*
* @param string $form The search form HTML output.
* @return string
*/
public function search_form( $form ) {
if ( is_admin() ) {
return $form;
}
$button_text = General::get_search_form_button_text();
if ( '' !== $button_text ) {
$form = str_replace( 'value="Search"', ( 'value="' . esc_attr( $button_text ) . '"' ), $form );
}
return $form;
}
}

42
inc/core/Header.php Normal file
View File

@ -0,0 +1,42 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Header service.
*
* @package PressBook
*/
namespace PressBook;
/**
* Add support for the custom header.
*/
class Header implements Serviceable {
/**
* Register service features.
*/
public function register() {
add_action( 'after_setup_theme', array( $this, 'custom_header_setup' ) );
}
/**
* Set up the WordPress core custom header feature.
*
* @uses pressbook_header_style()
*/
public function custom_header_setup() {
add_theme_support(
'custom-header',
apply_filters(
'pressbook_custom_header_args',
array(
'default-image' => '',
'width' => 1600,
'height' => 250,
'flex-width' => true,
'flex-height' => true,
'header-text' => false,
)
)
);
}
}

95
inc/core/Helpers.php Normal file
View File

@ -0,0 +1,95 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Helpers.
*
* @package PressBook
*/
namespace PressBook;
use PressBook\Options\Blog;
/**
* Theme helpers.
*/
class Helpers {
/**
* Find out if we should show the excerpt or the content.
*
* @return bool Whether to show the excerpt.
*/
public static function show_excerpt() {
global $post;
// Check if the more tag is being used.
$more_tag = apply_filters( 'pressbook_more_tag', strpos( $post->post_content, '<!--more-->' ) );
$format = ( false !== get_post_format() ) ? get_post_format() : 'standard';
$show_excerpt = ( 'excerpt' === Blog::get_archive_content() );
$show_excerpt = ( 'standard' !== $format ) ? false : $show_excerpt;
$show_excerpt = ( $more_tag ) ? false : $show_excerpt;
$show_excerpt = ( is_search() ) ? true : $show_excerpt;
return apply_filters( 'pressbook_show_excerpt', $show_excerpt );
}
/**
* Get theme name.
*
* @return string
*/
public static function get_theme_name() {
return wp_get_theme()->get( 'Name' );
}
/**
* Get theme URL.
* Used in footer credit link.
*
* @return string
*/
public static function get_theme_url() {
return wp_get_theme()->get( 'ThemeURI' );
}
/**
* Get theme author URL.
*
* @return string
*/
public static function get_theme_author_url() {
return wp_get_theme()->get( 'AuthorURI' );
}
/**
* Get upsell detail URL.
*
* @return string
*/
public static function get_upsell_detail_url() {
return 'https://scriptstown.com/wordpress-themes/pressbook-premium/';
}
/**
* Get upsell buy URL.
* Used one time in the theme page and customizer.
*
* @return string
*/
public static function get_upsell_buy_url() {
return 'https://scriptstown.com/account/signup/pressbook-premium-wordpress-theme';
}
/**
* Get FAQ page URL.
*
* @return string
*/
public static function get_faq_url() {
return 'https://scriptstown.com/wordpress-themes/pressbook/#faq';
}
}

279
inc/core/Icons.php Normal file
View File

@ -0,0 +1,279 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* SVG Icons class.
*
* @package PressBook
*/
namespace PressBook;
/**
* This class is in charge of displaying SVG icons across the site.
*
* Place each <svg> source on its own array key, without adding the
* both `width` and `height` attributes, since these are added dynamically,
* before rendering the SVG code.
*
* All icons are assumed to have equal width and height, hence the option
* to only specify a `$size` parameter in the svg methods.
*/
class Icons {
/**
* Gets the SVG code for a given icon.
*
* @param string $group Icon group.
* @param string $icon Icon key.
* @param int $size Icon size.
* @return string
*/
public static function get_svg( $group, $icon, $size ) {
if ( 'ui' === $group ) {
$arr = self::$ui_icons;
} elseif ( 'social' === $group ) {
$arr = self::$social_icons;
} else {
$arr = array();
}
if ( array_key_exists( $icon, $arr ) ) {
$repl = sprintf( '<svg class="svg-icon" width="%d" height="%d" aria-hidden="true" role="img" focusable="false" ', $size, $size );
$svg = preg_replace( '/^<svg /', $repl, trim( $arr[ $icon ] ) ); // Add extra attributes to SVG code.
$svg = preg_replace( "/([\n\t]+)/", ' ', $svg ); // Remove newlines & tabs.
$svg = preg_replace( '/>\s*</', '><', $svg ); // Remove white space between SVG tags.
return $svg;
}
return null;
}
/**
* Detects the social network from a URL and returns the SVG code for its icon.
*
* @param string $uri Social link uri.
* @param int $size Icon size.
* @return string
*/
public static function get_social_link_svg( $uri, $size ) {
static $regex_map; // Only compute regex map once, for performance.
if ( ! isset( $regex_map ) ) {
$regex_map = array();
$map = &self::$social_icons_map; // Use reference instead of copy, to save memory.
foreach ( array_keys( self::$social_icons ) as $icon ) {
$domains = array_key_exists( $icon, $map ) ? $map[ $icon ] : array( sprintf( '%s.com', $icon ) );
$domains = array_map( 'trim', $domains ); // Remove leading/trailing spaces, to prevent regex from failing to match.
$domains = array_map( 'preg_quote', $domains );
$regex_map[ $icon ] = sprintf( '/(%s)/i', implode( '|', $domains ) );
}
}
foreach ( $regex_map as $icon => $regex ) {
if ( preg_match( $regex, $uri ) ) {
return self::get_svg( 'social', $icon, $size );
}
}
return null;
}
/**
* User Interface icons svg sources.
*
* @var array
*/
public static $ui_icons = array(
'menu' => '<svg enable-background="new 0 0 2048 2048" preserveAspectRatio="xMidYMid meet" viewBox="0.0 0 1536.0 2048" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify"><path d="M1536,1472v128c0,17.333-6.333,32.333-19,45s-27.667,19-45,19H64c-17.333,0-32.333-6.333-45-19s-19-27.667-19-45v-128 c0-17.333,6.333-32.333,19-45s27.667-19,45-19h1408c17.333,0,32.333,6.333,45,19S1536,1454.667,1536,1472z M1536,960v128 c0,17.333-6.333,32.333-19,45s-27.667,19-45,19H64c-17.333,0-32.333-6.333-45-19s-19-27.667-19-45V960c0-17.333,6.333-32.333,19-45 s27.667-19,45-19h1408c17.333,0,32.333,6.333,45,19S1536,942.667,1536,960z M1536,448v128c0,17.333-6.333,32.333-19,45 s-27.667,19-45,19H64c-17.333,0-32.333-6.333-45-19S0,593.333,0,576V448c0-17.333,6.333-32.333,19-45s27.667-19,45-19h1408 c17.333,0,32.333,6.333,45,19S1536,430.667,1536,448z"></path></svg>',
'close' => '<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1490 1322q0 40-28 68l-136 136q-28 28-68 28t-68-28l-294-294-294 294q-28 28-68 28t-68-28l-136-136q-28-28-28-68t28-68l294-294-294-294q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 294 294-294q28-28 68-28t68 28l136 136q28 28 28 68t-28 68l-294 294 294 294q28 28 28 68z"/></svg>',
'chevron_down' => '<svg enable-background="new 0 0 2048 2048" preserveAspectRatio="xMidYMid meet" viewBox="53.0 0 1558.0 2048" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify"><path d="M1611,832c0,35.333-12.333,65.333-37,90l-651,651c-25.333,25.333-55.667,38-91,38c-36,0-66-12.667-90-38L91,922 c-25.333-24-38-54-38-90c0-35.333,12.667-65.667,38-91l74-75c26-24.667,56.333-37,91-37c35.333,0,65.333,12.333,90,37l486,486 l486-486c24.667-24.667,54.667-37,90-37c34.667,0,65,12.333,91,37l75,75C1598.667,767,1611,797.333,1611,832z"/></svg>',
'search' => '<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1216 832q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 52-38 90t-90 38q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg>',
'calendar' => '<svg enable-background="new 0 0 2048 2048" preserveAspectRatio="xMidYMid meet" viewBox="0.0 0 1664.0 2048" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify"><path d="M128,1792h1408V768H128V1792z M512,576V288c0-9.333-3-17-9-23s-13.667-9-23-9h-64c-9.333,0-17,3-23,9s-9,13.667-9,23v288 c0,9.333,3,17,9,23s13.667,9,23,9h64c9.333,0,17-3,23-9S512,585.333,512,576z M1280,576V288c0-9.333-3-17-9-23s-13.667-9-23-9h-64 c-9.333,0-17,3-23,9s-9,13.667-9,23v288c0,9.333,3,17,9,23s13.667,9,23,9h64c9.333,0,17-3,23-9S1280,585.333,1280,576z M1664,512 v1280c0,34.667-12.667,64.667-38,90s-55.333,38-90,38H128c-34.667,0-64.667-12.667-90-38s-38-55.333-38-90V512 c0-34.667,12.667-64.667,38-90s55.333-38,90-38h128v-96c0-44,15.667-81.667,47-113s69-47,113-47h64c44,0,81.667,15.667,113,47 s47,69,47,113v96h384v-96c0-44,15.667-81.667,47-113s69-47,113-47h64c44,0,81.667,15.667,113,47s47,69,47,113v96h128 c34.667,0,64.667,12.667,90,38S1664,477.333,1664,512z"/></svg>',
'user' => '<svg enable-background="new 0 0 2048 2048" preserveAspectRatio="xMidYMid meet" viewBox="0.0 0 1408.0 2048" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify"><path d="M1408,1533c0,80-24.333,143.167-73,189.5s-113.333,69.5-194,69.5H267c-80.667,0-145.333-23.167-194-69.5S0,1613,0,1533 c0-35.333,1.167-69.833,3.5-103.5s7-70,14-109S33.333,1245.333,44,1212s25-65.833,43-97.5s38.667-58.667,62-81 c23.333-22.333,51.833-40.167,85.5-53.5s70.833-20,111.5-20c6,0,20,7.167,42,21.5s46.833,30.333,74.5,48 c27.667,17.667,63.667,33.667,108,48S659.333,1099,704,1099s89.167-7.167,133.5-21.5s80.333-30.333,108-48 c27.667-17.667,52.5-33.667,74.5-48s36-21.5,42-21.5c40.667,0,77.833,6.667,111.5,20s62.167,31.167,85.5,53.5 c23.333,22.333,44,49.333,62,81s32.333,64.167,43,97.5s19.5,69.5,26.5,108.5s11.667,75.333,14,109S1408,1497.667,1408,1533z M1088,640c0,106-37.5,196.5-112.5,271.5S810,1024,704,1024s-196.5-37.5-271.5-112.5S320,746,320,640s37.5-196.5,112.5-271.5 S598,256,704,256s196.5,37.5,271.5,112.5S1088,534,1088,640z"></path></svg>',
'category' => '<svg enable-background="new 0 0 2048 2048" preserveAspectRatio="xMidYMid meet" viewBox="0.0 0 1879.0 2048" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify"><path d="M1879,1080c0,20.667-10.333,42.667-31,66l-336,396c-28.667,34-68.833,62.833-120.5,86.5S1292,1664,1248,1664H160 c-22.667,0-42.833-4.333-60.5-13S73,1628,73,1608c0-20.667,10.333-42.667,31-66l336-396c28.667-34,68.833-62.833,120.5-86.5 S660,1024,704,1024h1088c22.667,0,42.833,4.333,60.5,13S1879,1060,1879,1080z M1536,736v160H704c-62.667,0-128.333,15.833-197,47.5 S383.667,1015,343,1063L6,1459l-5,6c0-2.667-0.167-6.833-0.5-12.5S0,1442.667,0,1440V480c0-61.333,22-114,66-158s96.667-66,158-66 h320c61.333,0,114,22,158,66s66,96.667,66,158v32h544c61.333,0,114,22,158,66S1536,674.667,1536,736z"/></svg>',
'tag' => '<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
<path d="M384 448q0-53-37.5-90.5t-90.5-37.5-90.5 37.5-37.5 90.5 37.5 90.5 90.5 37.5 90.5-37.5 37.5-90.5zm1067 576q0 53-37 90l-491 492q-39 37-91 37-53 0-90-37l-715-716q-38-37-64.5-101t-26.5-117v-416q0-52 38-90t90-38h416q53 0 117 26.5t102 64.5l715 714q37 39 37 91zm384 0q0 53-37 90l-491 492q-39 37-91 37-36 0-59-14t-53-45l470-470q37-37 37-90 0-52-37-91l-715-714q-38-38-102-64.5t-117-26.5h224q53 0 117 26.5t102 64.5l715 714q37 39 37 91z"></path>
</svg>',
'bookmark' => '<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1420 128q23 0 44 9 33 13 52.5 41t19.5 62v1289q0 34-19.5 62t-52.5 41q-19 8-44 8-48 0-83-32l-441-424-441 424q-36 33-83 33-23 0-44-9-33-13-52.5-41t-19.5-62v-1289q0-34 19.5-62t52.5-41q21-9 44-9h1048z"/></svg>',
'comment' => '<svg viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M704 384q-153 0-286 52t-211.5 141-78.5 191q0 82 53 158t149 132l97 56-35 84q34-20 62-39l44-31 53 10q78 14 153 14 153 0 286-52t211.5-141 78.5-191-78.5-191-211.5-141-286-52zm0-128q191 0 353.5 68.5t256.5 186.5 94 257-94 257-256.5 186.5-353.5 68.5q-86 0-176-16-124 88-278 128-36 9-86 16h-3q-11 0-20.5-8t-11.5-21q-1-3-1-6.5t.5-6.5 2-6l2.5-5 3.5-5.5 4-5 4.5-5 4-4.5q5-6 23-25t26-29.5 22.5-29 25-38.5 20.5-44q-124-72-195-177t-71-224q0-139 94-257t256.5-186.5 353.5-68.5zm822 1169q10 24 20.5 44t25 38.5 22.5 29 26 29.5 23 25q1 1 4 4.5t4.5 5 4 5 3.5 5.5l2.5 5 2 6 .5 6.5-1 6.5q-3 14-13 22t-22 7q-50-7-86-16-154-40-278-128-90 16-176 16-271 0-472-132 58 4 88 4 161 0 309-45t264-129q125-92 192-212t67-254q0-77-23-152 129 71 204 178t75 230q0 120-71 224.5t-195 176.5z"/></svg>',
);
/**
* Social Icons domain mappings.
*
* By default, each Icon ID is matched against a .com TLD. To override this behavior,
* specify all the domains it covers (including the .com TLD too, if applicable).
*
* @var array
*/
public static $social_icons_map = array(
'amazon' => array(
'amazon.com',
'amazon.cn',
'amazon.in',
'amazon.fr',
'amazon.de',
'amazon.it',
'amazon.nl',
'amazon.es',
'amazon.co',
'amazon.ca',
),
'behance' => array(
'behance.net',
),
'codepen' => array(
'codepen.io',
),
'discord' => array(
'discord.com',
'discord.gg',
),
'facebook' => array(
'facebook.com',
'fb.me',
),
'feed' => array(
'feed',
),
'google' => array(
'g.page',
),
'kbin' => array(
'kbin.social',
),
'lastfm' => array(
'last.fm',
),
'lemmy' => array(
'lemmy.world',
'join-lemmy.org',
),
'mail' => array(
'mailto:',
),
'mastodon' => array(
'mastodon.world',
'mastodon.social',
),
'pocket' => array(
'getpocket.com',
),
'threads' => array(
'threads.net',
),
'tiktok' => array(
'tiktok.com',
),
'twitch' => array(
'twitch.tv',
),
'wordpress' => array(
'wordpress.com',
'wordpress.org',
),
'x' => array(
'x.com',
),
);
/**
* Social Icons svg sources.
*
* @var array
*/
public static $social_icons = array(
'500px' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M6.94026,15.1412c.00437.01213.108.29862.168.44064a6.55008,6.55008,0,1,0,6.03191-9.09557,6.68654,6.68654,0,0,0-2.58357.51467A8.53914,8.53914,0,0,0,8.21268,8.61344L8.209,8.61725V3.22948l9.0504-.00008c.32934-.0036.32934-.46353.32934-.61466s0-.61091-.33035-.61467L7.47248,2a.43.43,0,0,0-.43131.42692v7.58355c0,.24466.30476.42131.58793.4819.553.11812.68074-.05864.81617-.2457l.018-.02481A10.52673,10.52673,0,0,1,9.32258,9.258a5.35268,5.35268,0,1,1,7.58985,7.54976,5.417,5.417,0,0,1-3.80867,1.56365,5.17483,5.17483,0,0,1-2.69822-.74478l.00342-4.61111a2.79372,2.79372,0,0,1,.71372-1.78792,2.61611,2.61611,0,0,1,1.98282-.89477,2.75683,2.75683,0,0,1,1.95525.79477,2.66867,2.66867,0,0,1,.79656,1.909,2.724,2.724,0,0,1-2.75849,2.748,4.94651,4.94651,0,0,1-.86254-.13719c-.31234-.093-.44519.34058-.48892.48349-.16811.54966.08453.65862.13687.67489a3.75751,3.75751,0,0,0,1.25234.18375,3.94634,3.94634,0,1,0-2.82444-6.742,3.67478,3.67478,0,0,0-1.13028,2.584l-.00041.02323c-.0035.11667-.00579,2.881-.00644,3.78811l-.00407-.00451a6.18521,6.18521,0,0,1-1.0851-1.86092c-.10544-.27856-.34358-.22925-.66857-.12917-.14192.04372-.57386.17677-.47833.489Zm4.65165-1.08338a.51346.51346,0,0,0,.19513.31818l.02276.022a.52945.52945,0,0,0,.3517.18416.24242.24242,0,0,0,.16577-.0611c.05473-.05082.67382-.67812.73287-.738l.69041.68819a.28978.28978,0,0,0,.21437.11032.53239.53239,0,0,0,.35708-.19486c.29792-.30419.14885-.46821.07676-.54751l-.69954-.69975.72952-.73469c.16-.17311.01874-.35708-.12218-.498-.20461-.20461-.402-.25742-.52855-.14083l-.7254.72665-.73354-.73375a.20128.20128,0,0,0-.14179-.05695.54135.54135,0,0,0-.34379.19648c-.22561.22555-.274.38149-.15656.5059l.73374.7315-.72942.73072A.26589.26589,0,0,0,11.59191,14.05782Zm1.59866-9.915A8.86081,8.86081,0,0,0,9.854,4.776a.26169.26169,0,0,0-.16938.22759.92978.92978,0,0,0,.08619.42094c.05682.14524.20779.531.50006.41955a8.40969,8.40969,0,0,1,2.91968-.55484,7.87875,7.87875,0,0,1,3.086.62286,8.61817,8.61817,0,0,1,2.30562,1.49315.2781.2781,0,0,0,.18318.07586c.15529,0,.30425-.15253.43167-.29551.21268-.23861.35873-.4369.1492-.63538a8.50425,8.50425,0,0,0-2.62312-1.694A9.0177,9.0177,0,0,0,13.19058,4.14283ZM19.50945,18.6236h0a.93171.93171,0,0,0-.36642-.25406.26589.26589,0,0,0-.27613.06613l-.06943.06929A7.90606,7.90606,0,0,1,7.60639,18.505a7.57284,7.57284,0,0,1-1.696-2.51537,8.58715,8.58715,0,0,1-.5147-1.77754l-.00871-.04864c-.04939-.25873-.28755-.27684-.62981-.22448-.14234.02178-.5755.088-.53426.39969l.001.00712a9.08807,9.08807,0,0,0,15.406,4.99094c.00193-.00192.04753-.04718.0725-.07436C19.79425,19.16234,19.87422,18.98728,19.50945,18.6236Z"></path></svg>',
'amazon' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M13.582,8.182C11.934,8.367,9.78,8.49,8.238,9.166c-1.781,0.769-3.03,2.337-3.03,4.644 c0,2.953,1.86,4.429,4.253,4.429c2.02,0,3.125-0.477,4.685-2.065c0.516,0.747,0.685,1.109,1.629,1.894 c0.212,0.114,0.483,0.103,0.672-0.066l0.006,0.006c0.567-0.505,1.599-1.401,2.18-1.888c0.231-0.188,0.19-0.496,0.009-0.754 c-0.52-0.718-1.072-1.303-1.072-2.634V8.305c0-1.876,0.133-3.599-1.249-4.891C15.23,2.369,13.422,2,12.04,2 C9.336,2,6.318,3.01,5.686,6.351C5.618,6.706,5.877,6.893,6.109,6.945l2.754,0.298C9.121,7.23,9.308,6.977,9.357,6.72 c0.236-1.151,1.2-1.706,2.284-1.706c0.584,0,1.249,0.215,1.595,0.738c0.398,0.584,0.346,1.384,0.346,2.061V8.182z M13.049,14.088 c-0.451,0.8-1.169,1.291-1.967,1.291c-1.09,0-1.728-0.83-1.728-2.061c0-2.42,2.171-2.86,4.227-2.86v0.615 C13.582,12.181,13.608,13.104,13.049,14.088z M20.683,19.339C18.329,21.076,14.917,22,11.979,22c-4.118,0-7.826-1.522-10.632-4.057 c-0.22-0.199-0.024-0.471,0.241-0.317c3.027,1.762,6.771,2.823,10.639,2.823c2.608,0,5.476-0.541,8.115-1.66 C20.739,18.62,21.072,19.051,20.683,19.339z M21.336,21.043c-0.194,0.163-0.379,0.076-0.293-0.139 c0.284-0.71,0.92-2.298,0.619-2.684c-0.301-0.386-1.99-0.183-2.749-0.092c-0.23,0.027-0.266-0.173-0.059-0.319 c1.348-0.946,3.555-0.673,3.811-0.356C22.925,17.773,22.599,19.986,21.336,21.043z"></path></svg>',
'bandcamp' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M15.27 17.289 3 17.289 8.73 6.711 21 6.711 15.27 17.289"></path></svg>',
'behance' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M7.799,5.698c0.589,0,1.12,0.051,1.606,0.156c0.482,0.102,0.894,0.273,1.241,0.507c0.344,0.235,0.612,0.546,0.804,0.938 c0.188,0.387,0.281,0.871,0.281,1.443c0,0.619-0.141,1.137-0.421,1.551c-0.284,0.413-0.7,0.751-1.255,1.014 c0.756,0.218,1.317,0.601,1.689,1.146c0.374,0.549,0.557,1.205,0.557,1.975c0,0.623-0.12,1.161-0.359,1.612 c-0.241,0.457-0.569,0.828-0.973,1.114c-0.408,0.288-0.876,0.5-1.399,0.637C9.052,17.931,8.514,18,7.963,18H2V5.698H7.799 M7.449,10.668c0.481,0,0.878-0.114,1.192-0.345c0.311-0.228,0.463-0.603,0.463-1.119c0-0.286-0.051-0.523-0.152-0.707 C8.848,8.315,8.711,8.171,8.536,8.07C8.362,7.966,8.166,7.894,7.94,7.854c-0.224-0.044-0.457-0.06-0.697-0.06H4.709v2.874H7.449z M7.6,15.905c0.267,0,0.521-0.024,0.759-0.077c0.243-0.053,0.457-0.137,0.637-0.261c0.182-0.12,0.332-0.283,0.441-0.491 C9.547,14.87,9.6,14.602,9.6,14.278c0-0.633-0.18-1.084-0.533-1.357c-0.356-0.27-0.83-0.404-1.413-0.404H4.709v3.388L7.6,15.905z M16.162,15.864c0.367,0.358,0.897,0.538,1.583,0.538c0.493,0,0.92-0.125,1.277-0.374c0.354-0.248,0.571-0.514,0.654-0.79h2.155 c-0.347,1.072-0.872,1.838-1.589,2.299C19.534,18,18.67,18.23,17.662,18.23c-0.701,0-1.332-0.113-1.899-0.337 c-0.567-0.227-1.041-0.544-1.439-0.958c-0.389-0.415-0.689-0.907-0.904-1.484c-0.213-0.574-0.32-1.21-0.32-1.899 c0-0.666,0.11-1.288,0.329-1.863c0.222-0.577,0.529-1.075,0.933-1.492c0.406-0.42,0.885-0.751,1.444-0.994 c0.558-0.241,1.175-0.363,1.857-0.363c0.754,0,1.414,0.145,1.98,0.44c0.563,0.291,1.026,0.686,1.389,1.181 c0.363,0.493,0.622,1.057,0.783,1.69c0.16,0.632,0.217,1.292,0.171,1.983h-6.428C15.557,14.84,15.795,15.506,16.162,15.864 M18.973,11.184c-0.291-0.321-0.783-0.496-1.384-0.496c-0.39,0-0.714,0.066-0.973,0.2c-0.254,0.132-0.461,0.297-0.621,0.491 c-0.157,0.197-0.265,0.405-0.328,0.628c-0.063,0.217-0.101,0.413-0.111,0.587h3.98C19.478,11.969,19.265,11.509,18.973,11.184z M15.057,7.738h4.985V6.524h-4.985L15.057,7.738z"></path></svg>',
'codepen' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.016,8.84c-0.002-0.013-0.005-0.025-0.007-0.037c-0.005-0.025-0.008-0.048-0.015-0.072 c-0.003-0.015-0.01-0.028-0.013-0.042c-0.008-0.02-0.015-0.04-0.023-0.062c-0.007-0.015-0.013-0.028-0.02-0.042 c-0.008-0.02-0.018-0.037-0.03-0.057c-0.007-0.013-0.017-0.027-0.025-0.038c-0.012-0.018-0.023-0.035-0.035-0.052 c-0.01-0.013-0.02-0.025-0.03-0.037c-0.015-0.017-0.028-0.032-0.043-0.045c-0.01-0.012-0.022-0.023-0.035-0.035 c-0.015-0.015-0.032-0.028-0.048-0.04c-0.012-0.01-0.025-0.02-0.037-0.03c-0.005-0.003-0.01-0.008-0.015-0.012l-9.161-6.096 c-0.289-0.192-0.666-0.192-0.955,0L2.359,8.237C2.354,8.24,2.349,8.245,2.344,8.249L2.306,8.277 c-0.017,0.013-0.033,0.027-0.048,0.04C2.246,8.331,2.234,8.342,2.222,8.352c-0.015,0.015-0.028,0.03-0.042,0.047 c-0.012,0.013-0.022,0.023-0.03,0.037C2.139,8.453,2.125,8.471,2.115,8.488C2.107,8.501,2.099,8.514,2.09,8.526 C2.079,8.548,2.069,8.565,2.06,8.585C2.054,8.6,2.047,8.613,2.04,8.626C2.032,8.648,2.025,8.67,2.019,8.69 c-0.005,0.013-0.01,0.027-0.013,0.042C1.999,8.755,1.995,8.778,1.99,8.803C1.989,8.817,1.985,8.828,1.984,8.84 C1.978,8.879,1.975,8.915,1.975,8.954v6.093c0,0.037,0.003,0.075,0.008,0.112c0.002,0.012,0.005,0.025,0.007,0.038 c0.005,0.023,0.008,0.047,0.015,0.072c0.003,0.015,0.008,0.028,0.013,0.04c0.007,0.022,0.013,0.042,0.022,0.063 c0.007,0.015,0.013,0.028,0.02,0.04c0.008,0.02,0.018,0.038,0.03,0.058c0.007,0.013,0.015,0.027,0.025,0.038 c0.012,0.018,0.023,0.035,0.035,0.052c0.01,0.013,0.02,0.025,0.03,0.037c0.013,0.015,0.028,0.032,0.042,0.045 c0.012,0.012,0.023,0.023,0.035,0.035c0.015,0.013,0.032,0.028,0.048,0.04l0.038,0.03c0.005,0.003,0.01,0.007,0.013,0.01 l9.163,6.095C11.668,21.953,11.833,22,12,22c0.167,0,0.332-0.047,0.478-0.144l9.163-6.095l0.015-0.01 c0.013-0.01,0.027-0.02,0.037-0.03c0.018-0.013,0.035-0.028,0.048-0.04c0.013-0.012,0.025-0.023,0.035-0.035 c0.017-0.015,0.03-0.032,0.043-0.045c0.01-0.013,0.02-0.025,0.03-0.037c0.013-0.018,0.025-0.035,0.035-0.052 c0.008-0.013,0.018-0.027,0.025-0.038c0.012-0.02,0.022-0.038,0.03-0.058c0.007-0.013,0.013-0.027,0.02-0.04 c0.008-0.022,0.015-0.042,0.023-0.063c0.003-0.013,0.01-0.027,0.013-0.04c0.007-0.025,0.01-0.048,0.015-0.072 c0.002-0.013,0.005-0.027,0.007-0.037c0.003-0.042,0.007-0.079,0.007-0.117V8.954C22.025,8.915,22.022,8.879,22.016,8.84z M12.862,4.464l6.751,4.49l-3.016,2.013l-3.735-2.492V4.464z M11.138,4.464v4.009l-3.735,2.494L4.389,8.954L11.138,4.464z M3.699,10.562L5.853,12l-2.155,1.438V10.562z M11.138,19.536l-6.749-4.491l3.015-2.011l3.735,2.492V19.536z M12,14.035L8.953,12 L12,9.966L15.047,12L12,14.035z M12.862,19.536v-4.009l3.735-2.492l3.016,2.011L12.862,19.536z M20.303,13.438L18.147,12 l2.156-1.438L20.303,13.438z"></path></svg>',
'deviantart' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M 18.19 5.636 18.19 2 18.188 2 14.553 2 14.19 2.366 12.474 5.636 11.935 6 5.81 6 5.81 10.994 9.177 10.994 9.477 11.357 5.81 18.363 5.81 22 5.811 22 9.447 22 9.81 21.634 11.526 18.364 12.065 18 18.19 18 18.19 13.006 14.823 13.006 14.523 12.641 18.19 5.636z"></path></svg>',
'discord' => '<svg viewBox="0 0 71 55" xmlns="http://www.w3.org/2000/svg"><path d="M60.1045 4.8978C55.5792 2.8214 50.7265 1.2916 45.6527 0.41542C45.5603 0.39851 45.468 0.440769 45.4204 0.525289C44.7963 1.6353 44.105 3.0834 43.6209 4.2216C38.1637 3.4046 32.7345 3.4046 27.3892 4.2216C26.905 3.0581 26.1886 1.6353 25.5617 0.525289C25.5141 0.443589 25.4218 0.40133 25.3294 0.41542C20.2584 1.2888 15.4057 2.8186 10.8776 4.8978C10.8384 4.9147 10.8048 4.9429 10.7825 4.9795C1.57795 18.7309 -0.943561 32.1443 0.293408 45.3914C0.299005 45.4562 0.335386 45.5182 0.385761 45.5576C6.45866 50.0174 12.3413 52.7249 18.1147 54.5195C18.2071 54.5477 18.305 54.5139 18.3638 54.4378C19.7295 52.5728 20.9469 50.6063 21.9907 48.5383C22.0523 48.4172 21.9935 48.2735 21.8676 48.2256C19.9366 47.4931 18.0979 46.6 16.3292 45.5858C16.1893 45.5041 16.1781 45.304 16.3068 45.2082C16.679 44.9293 17.0513 44.6391 17.4067 44.3461C17.471 44.2926 17.5606 44.2813 17.6362 44.3151C29.2558 49.6202 41.8354 49.6202 53.3179 44.3151C53.3935 44.2785 53.4831 44.2898 53.5502 44.3433C53.9057 44.6363 54.2779 44.9293 54.6529 45.2082C54.7816 45.304 54.7732 45.5041 54.6333 45.5858C52.8646 46.6197 51.0259 47.4931 49.0921 48.2228C48.9662 48.2707 48.9102 48.4172 48.9718 48.5383C50.038 50.6034 51.2554 52.5699 52.5959 54.435C52.6519 54.5139 52.7526 54.5477 52.845 54.5195C58.6464 52.7249 64.529 50.0174 70.6019 45.5576C70.6551 45.5182 70.6887 45.459 70.6943 45.3942C72.1747 30.0791 68.2147 16.7757 60.1968 4.9823C60.1772 4.9429 60.1437 4.9147 60.1045 4.8978ZM23.7259 37.3253C20.2276 37.3253 17.3451 34.1136 17.3451 30.1693C17.3451 26.225 20.1717 23.0133 23.7259 23.0133C27.308 23.0133 30.1626 26.2532 30.1066 30.1693C30.1066 34.1136 27.28 37.3253 23.7259 37.3253ZM47.3178 37.3253C43.8196 37.3253 40.9371 34.1136 40.9371 30.1693C40.9371 26.225 43.7636 23.0133 47.3178 23.0133C50.9 23.0133 53.7545 26.2532 53.6986 30.1693C53.6986 34.1136 50.9 37.3253 47.3178 37.3253Z"></path></svg>',
'dribbble' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,22C6.486,22,2,17.514,2,12S6.486,2,12,2c5.514,0,10,4.486,10,10S17.514,22,12,22z M20.434,13.369 c-0.292-0.092-2.644-0.794-5.32-0.365c1.117,3.07,1.572,5.57,1.659,6.09C18.689,17.798,20.053,15.745,20.434,13.369z M15.336,19.876c-0.127-0.749-0.623-3.361-1.822-6.477c-0.019,0.006-0.038,0.013-0.056,0.019c-4.818,1.679-6.547,5.02-6.701,5.334 c1.448,1.129,3.268,1.803,5.243,1.803C13.183,20.555,14.311,20.313,15.336,19.876z M5.654,17.724 c0.193-0.331,2.538-4.213,6.943-5.637c0.111-0.036,0.224-0.07,0.337-0.102c-0.214-0.485-0.448-0.971-0.692-1.45 c-4.266,1.277-8.405,1.223-8.778,1.216c-0.003,0.087-0.004,0.174-0.004,0.261C3.458,14.207,4.29,16.21,5.654,17.724z M3.639,10.264 c0.382,0.005,3.901,0.02,7.897-1.041c-1.415-2.516-2.942-4.631-3.167-4.94C5.979,5.41,4.193,7.613,3.639,10.264z M9.998,3.709 c0.236,0.316,1.787,2.429,3.187,5c3.037-1.138,4.323-2.867,4.477-3.085C16.154,4.286,14.17,3.471,12,3.471 C11.311,3.471,10.641,3.554,9.998,3.709z M18.612,6.612C18.432,6.855,17,8.69,13.842,9.979c0.199,0.407,0.389,0.821,0.567,1.237 c0.063,0.148,0.124,0.295,0.184,0.441c2.842-0.357,5.666,0.215,5.948,0.275C20.522,9.916,19.801,8.065,18.612,6.612z"></path></svg>',
'dropbox' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,6.134L6.069,9.797L2,6.54l5.883-3.843L12,6.134z M2,13.054l5.883,3.843L12,13.459L6.069,9.797L2,13.054z M12,13.459 l4.116,3.439L22,13.054l-4.069-3.257L12,13.459z M22,6.54l-5.884-3.843L12,6.134l5.931,3.663L22,6.54z M12.011,14.2l-4.129,3.426 l-1.767-1.153v1.291l5.896,3.539l5.897-3.539v-1.291l-1.769,1.153L12.011,14.2z"></path></svg>',
'etsy' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M9.16033,4.038c0-.27174.02717-.43478.48913-.43478h6.22283c1.087,0,1.68478.92391,2.11957,2.663l.35326,1.38587h1.05978C19.59511,3.712,19.75815,2,19.75815,2s-2.663.29891-4.23913.29891h-7.962L3.29076,2.163v1.1413L4.731,3.57609c1.00543.19022,1.25.40761,1.33152,1.33152,0,0,.08152,2.71739.08152,7.20109s-.08152,7.17391-.08152,7.17391c0,.81522-.32609,1.11413-1.33152,1.30435l-1.44022.27174V22l4.2663-.13587h7.11957c1.60326,0,5.32609.13587,5.32609.13587.08152-.97826.625-5.40761.70652-5.89674H19.7038L18.644,18.52174c-.84239,1.90217-2.06522,2.038-3.42391,2.038H11.1712c-1.3587,0-2.01087-.54348-2.01087-1.712V12.65217s3.0163,0,3.99457.08152c.76087.05435,1.22283.27174,1.46739,1.33152l.32609,1.413h1.16848l-.08152-3.55978.163-3.587H15.02989l-.38043,1.57609c-.24457,1.03261-.40761,1.22283-1.46739,1.33152-1.38587.13587-4.02174.1087-4.02174.1087Z"></path></svg>',
'facebook' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg>',
'feed' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M2,8.667V12c5.515,0,10,4.485,10,10h3.333C15.333,14.637,9.363,8.667,2,8.667z M2,2v3.333 c9.19,0,16.667,7.477,16.667,16.667H22C22,10.955,13.045,2,2,2z M4.5,17C3.118,17,2,18.12,2,19.5S3.118,22,4.5,22S7,20.88,7,19.5 S5.882,17,4.5,17z"></path></svg>',
'flickr' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M6.5,7c-2.75,0-5,2.25-5,5s2.25,5,5,5s5-2.25,5-5S9.25,7,6.5,7z M17.5,7c-2.75,0-5,2.25-5,5s2.25,5,5,5s5-2.25,5-5 S20.25,7,17.5,7z"></path></svg>',
'foursquare' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M17.573,2c0,0-9.197,0-10.668,0S5,3.107,5,3.805s0,16.948,0,16.948c0,0.785,0.422,1.077,0.66,1.172 c0.238,0.097,0.892,0.177,1.285-0.275c0,0,5.035-5.843,5.122-5.93c0.132-0.132,0.132-0.132,0.262-0.132h3.26 c1.368,0,1.588-0.977,1.732-1.552c0.078-0.318,0.692-3.428,1.225-6.122l0.675-3.368C19.56,2.893,19.14,2,17.573,2z M16.495,7.22 c-0.053,0.252-0.372,0.518-0.665,0.518c-0.293,0-4.157,0-4.157,0c-0.467,0-0.802,0.318-0.802,0.787v0.508 c0,0.467,0.337,0.798,0.805,0.798c0,0,3.197,0,3.528,0s0.655,0.362,0.583,0.715c-0.072,0.353-0.407,2.102-0.448,2.295 c-0.04,0.193-0.262,0.523-0.655,0.523c-0.33,0-2.88,0-2.88,0c-0.523,0-0.683,0.068-1.033,0.503 c-0.35,0.437-3.505,4.223-3.505,4.223c-0.032,0.035-0.063,0.027-0.063-0.015V4.852c0-0.298,0.26-0.648,0.648-0.648 c0,0,8.228,0,8.562,0c0.315,0,0.61,0.297,0.528,0.683L16.495,7.22z"></path></svg>',
'goodreads' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M17.3,17.5c-0.2,0.8-0.5,1.4-1,1.9c-0.4,0.5-1,0.9-1.7,1.2C13.9,20.9,13.1,21,12,21c-0.6,0-1.3-0.1-1.9-0.2 c-0.6-0.1-1.1-0.4-1.6-0.7c-0.5-0.3-0.9-0.7-1.2-1.2c-0.3-0.5-0.5-1.1-0.5-1.7h1.5c0.1,0.5,0.2,0.9,0.5,1.2 c0.2,0.3,0.5,0.6,0.9,0.8c0.3,0.2,0.7,0.3,1.1,0.4c0.4,0.1,0.8,0.1,1.2,0.1c1.4,0,2.5-0.4,3.1-1.2c0.6-0.8,1-2,1-3.5v-1.7h0 c-0.4,0.8-0.9,1.4-1.6,1.9c-0.7,0.5-1.5,0.7-2.4,0.7c-1,0-1.9-0.2-2.6-0.5C8.7,15,8.1,14.5,7.7,14c-0.5-0.6-0.8-1.3-1-2.1 c-0.2-0.8-0.3-1.6-0.3-2.5c0-0.9,0.1-1.7,0.4-2.5c0.3-0.8,0.6-1.5,1.1-2c0.5-0.6,1.1-1,1.8-1.4C10.3,3.2,11.1,3,12,3 c0.5,0,0.9,0.1,1.3,0.2c0.4,0.1,0.8,0.3,1.1,0.5c0.3,0.2,0.6,0.5,0.9,0.8c0.3,0.3,0.5,0.6,0.6,1h0V3.4h1.5V15 C17.6,15.9,17.5,16.7,17.3,17.5z M13.8,14.1c0.5-0.3,0.9-0.7,1.3-1.1c0.3-0.5,0.6-1,0.8-1.6c0.2-0.6,0.3-1.2,0.3-1.9 c0-0.6-0.1-1.2-0.2-1.9c-0.1-0.6-0.4-1.2-0.7-1.7c-0.3-0.5-0.7-0.9-1.3-1.2c-0.5-0.3-1.1-0.5-1.9-0.5s-1.4,0.2-1.9,0.5 c-0.5,0.3-1,0.7-1.3,1.2C8.5,6.4,8.3,7,8.1,7.6C8,8.2,7.9,8.9,7.9,9.5c0,0.6,0.1,1.3,0.2,1.9C8.3,12,8.6,12.5,8.9,13 c0.3,0.5,0.8,0.8,1.3,1.1c0.5,0.3,1.1,0.4,1.9,0.4C12.7,14.5,13.3,14.4,13.8,14.1z"></path></svg>',
'google' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.02,10.18v3.72v0.01h5.51c-0.26,1.57-1.67,4.22-5.5,4.22c-3.31,0-6.01-2.75-6.01-6.12s2.7-6.12,6.01-6.12 c1.87,0,3.13,0.8,3.85,1.48l2.84-2.76C16.99,2.99,14.73,2,12.03,2c-5.52,0-10,4.48-10,10s4.48,10,10,10c5.77,0,9.6-4.06,9.6-9.77 c0-0.83-0.11-1.42-0.25-2.05H12.02z"></path></svg>',
'github' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg>',
'instagram' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,4.622c2.403,0,2.688,0.009,3.637,0.052c0.877,0.04,1.354,0.187,1.671,0.31c0.42,0.163,0.72,0.358,1.035,0.673 c0.315,0.315,0.51,0.615,0.673,1.035c0.123,0.317,0.27,0.794,0.31,1.671c0.043,0.949,0.052,1.234,0.052,3.637 s-0.009,2.688-0.052,3.637c-0.04,0.877-0.187,1.354-0.31,1.671c-0.163,0.42-0.358,0.72-0.673,1.035 c-0.315,0.315-0.615,0.51-1.035,0.673c-0.317,0.123-0.794,0.27-1.671,0.31c-0.949,0.043-1.233,0.052-3.637,0.052 s-2.688-0.009-3.637-0.052c-0.877-0.04-1.354-0.187-1.671-0.31c-0.42-0.163-0.72-0.358-1.035-0.673 c-0.315-0.315-0.51-0.615-0.673-1.035c-0.123-0.317-0.27-0.794-0.31-1.671C4.631,14.688,4.622,14.403,4.622,12 s0.009-2.688,0.052-3.637c0.04-0.877,0.187-1.354,0.31-1.671c0.163-0.42,0.358-0.72,0.673-1.035 c0.315-0.315,0.615-0.51,1.035-0.673c0.317-0.123,0.794-0.27,1.671-0.31C9.312,4.631,9.597,4.622,12,4.622 M12,3 C9.556,3,9.249,3.01,8.289,3.054C7.331,3.098,6.677,3.25,6.105,3.472C5.513,3.702,5.011,4.01,4.511,4.511 c-0.5,0.5-0.808,1.002-1.038,1.594C3.25,6.677,3.098,7.331,3.054,8.289C3.01,9.249,3,9.556,3,12c0,2.444,0.01,2.751,0.054,3.711 c0.044,0.958,0.196,1.612,0.418,2.185c0.23,0.592,0.538,1.094,1.038,1.594c0.5,0.5,1.002,0.808,1.594,1.038 c0.572,0.222,1.227,0.375,2.185,0.418C9.249,20.99,9.556,21,12,21s2.751-0.01,3.711-0.054c0.958-0.044,1.612-0.196,2.185-0.418 c0.592-0.23,1.094-0.538,1.594-1.038c0.5-0.5,0.808-1.002,1.038-1.594c0.222-0.572,0.375-1.227,0.418-2.185 C20.99,14.751,21,14.444,21,12s-0.01-2.751-0.054-3.711c-0.044-0.958-0.196-1.612-0.418-2.185c-0.23-0.592-0.538-1.094-1.038-1.594 c-0.5-0.5-1.002-0.808-1.594-1.038c-0.572-0.222-1.227-0.375-2.185-0.418C14.751,3.01,14.444,3,12,3L12,3z M12,7.378 c-2.552,0-4.622,2.069-4.622,4.622S9.448,16.622,12,16.622s4.622-2.069,4.622-4.622S14.552,7.378,12,7.378z M12,15 c-1.657,0-3-1.343-3-3s1.343-3,3-3s3,1.343,3,3S13.657,15,12,15z M16.804,6.116c-0.596,0-1.08,0.484-1.08,1.08 s0.484,1.08,1.08,1.08c0.596,0,1.08-0.484,1.08-1.08S17.401,6.116,16.804,6.116z"></path></svg>',
'kbin' => '<svg viewBox="-4 0 41 32" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M6.347 8.835l-4.261 0.035c-1.796 0-2.391 1.087-1.956 2.653l3.924 16.809c0.871 3.108 1.447 3.663 2.035 3.663h1.14c2.244 0 3.041-1.3 3.917-3.663l6.204-16.809h-8.172c-0.582-1.258-0.785-2.682-2.832-2.682z"></path><path d="M20.031-0.004h9.999c0.803 0 2.471 0.437 1.815 2.287l-8.313 26.866c-0.858 2.322-1.643 2.848-4.169 2.848h-13.273c0.693 0 1.422-1.3 2.299-3.663l7.902-25.761c0.576-1.477 1.349-2.576 3.74-2.576z"></path></svg>',
'lastfm' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M10.5002,0 C4.7006,0 0,4.70109753 0,10.4998496 C0,16.2989526 4.7006,21 10.5002,21 C16.299,21 21,16.2989526 21,10.4998496 C21,4.70109753 16.299,0 10.5002,0 Z M14.69735,14.7204413 C13.3164,14.7151781 12.4346,14.0870017 11.83445,12.6859357 L11.6816001,12.3451305 L10.35405,9.31011397 C9.92709997,8.26875064 8.85260001,7.57120012 7.68010001,7.57120012 C6.06945001,7.57120012 4.75925001,8.88509738 4.75925001,10.5009524 C4.75925001,12.1164565 6.06945001,13.4303036 7.68010001,13.4303036 C8.77200001,13.4303036 9.76514999,12.827541 10.2719501,11.8567047 C10.2893,11.8235214 10.3239,11.8019673 10.36305,11.8038219 C10.4007,11.8053759 10.43535,11.8287847 10.4504,11.8631709 L10.98655,13.1045863 C11.0016,13.1389726 10.9956,13.17782 10.97225,13.2068931 C10.1605001,14.1995341 8.96020001,14.7683115 7.68010001,14.7683115 C5.33305,14.7683115 3.42340001,12.8535563 3.42340001,10.5009524 C3.42340001,8.14679459 5.33300001,6.23203946 7.68010001,6.23203946 C9.45720002,6.23203946 10.8909,7.19074535 11.6138,8.86359341 C11.6205501,8.88018505 12.3412,10.5707777 12.97445,12.0190621 C13.34865,12.8739575 13.64615,13.3959676 14.6288,13.4291508 C15.5663001,13.4612814 16.25375,12.9121534 16.25375,12.1484869 C16.25375,11.4691321 15.8320501,11.3003585 14.8803,10.98216 C13.2365,10.4397989 12.34495,9.88605929 12.34495,8.51817658 C12.34495,7.1809207 13.26665,6.31615054 14.692,6.31615054 C15.62875,6.31615054 16.3155,6.7286858 16.79215,7.5768142 C16.80495,7.60062396 16.8079001,7.62814302 16.8004001,7.65420843 C16.7929,7.68027384 16.7748,7.70212868 16.7507001,7.713808 L15.86145,8.16900031 C15.8178001,8.19200805 15.7643,8.17807308 15.73565,8.13847371 C15.43295,7.71345711 15.0956,7.52513451 14.6423,7.52513451 C14.05125,7.52513451 13.6220001,7.92899802 13.6220001,8.48649708 C13.6220001,9.17382194 14.1529001,9.34144259 15.0339,9.61923972 C15.14915,9.65578139 15.26955,9.69397731 15.39385,9.73432853 C16.7763,10.1865133 17.57675,10.7311301 17.57675,12.1836251 C17.57685,13.629654 16.3389,14.7204413 14.69735,14.7204413 Z"></path></svg>',
'lemmy' => '<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.875" d="M5.22 7.648c-0.030-0-0.059 0-0.089 0.001-0.135 0.002-0.268 0.011-0.4 0.026-1.056 0.122-2.007 0.683-2.59 1.665-0.571 0.962-0.712 2.021-0.421 3.002s0.996 1.873 2.041 2.579c0.006 0.004 0.013 0.008 0.019 0.012 0.895 0.54 1.787 0.904 2.742 1.092-0.023 0.394-0.023 0.799 0.003 1.214 0.076 1.253 0.519 2.407 1.191 3.427l-2.407 0.982c-0.26 0.102-0.386 0.396-0.28 0.654s0.402 0.38 0.658 0.271l2.647-1.081c0.491 0.585 1.055 1.115 1.66 1.58 0.023 0.018 0.047 0.035 0.070 0.053l-1.55 2.053c-0.17 0.22-0.128 0.537 0.094 0.705s0.539 0.122 0.704-0.102l1.575-2.085c0.865 0.548 1.784 0.975 2.69 1.258 0.465 0.852 1.374 1.395 2.425 1.395 1.061 0 1.97-0.584 2.431-1.42 0.897-0.288 1.805-0.717 2.661-1.263l1.597 2.114c0.165 0.224 0.482 0.27 0.704 0.102s0.265-0.485 0.094-0.705l-1.574-2.084c0.010-0.008 0.021-0.016 0.031-0.024 0.598-0.458 1.157-0.978 1.647-1.551l2.58 1.053c0.257 0.109 0.553-0.013 0.658-0.271s-0.021-0.553-0.28-0.654l-2.329-0.951c0.693-1.026 1.157-2.189 1.254-3.452 0.032-0.417 0.038-0.826 0.020-1.224 0.949-0.189 1.835-0.552 2.725-1.089 0.006-0.004 0.013-0.008 0.019-0.012 1.044-0.706 1.749-1.598 2.041-2.579s0.151-2.040-0.421-3.002c-0.583-0.982-1.534-1.543-2.59-1.665-0.132-0.015-0.266-0.024-0.4-0.026-0.944-0.017-1.951 0.276-2.92 0.835-0.712 0.411-1.355 1.041-1.857 1.728-1.406-0.805-3.236-1.258-5.484-1.295-0.202-0.003-0.407-0.003-0.615 0-2.506 0.041-4.512 0.516-6.027 1.375-0.004-0.006-0.008-0.012-0.012-0.018-0.509-0.711-1.169-1.367-1.903-1.79-0.938-0.542-1.913-0.833-2.831-0.835z"></path><path stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.875" d="M22.402 10.528c0.478-0.668 1.105-1.285 1.766-1.666 2.083-1.203 4.282-1.038 5.315 0.701 1.034 1.741 0.468 3.672-1.489 4.995-0.999 0.602-1.967 0.966-3.038 1.111M9.598 10.528c-0.478-0.668-1.105-1.285-1.766-1.666-2.083-1.203-4.282-1.038-5.315 0.701-1.034 1.741-0.468 3.672 1.489 4.995 0.999 0.602 1.967 0.966 3.038 1.111"></path><path stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.875" d="M25.038 17.213c0.359-4.681-2.52-7.965-9.039-7.859s-9.321 3.208-9.039 7.859c0.27 4.44 5.525 7.7 9.004 7.7s8.733-3.267 9.073-7.7z"></path><path d="M19.078 19.319c0 0.722 0.585 1.308 1.306 1.308s1.306-0.585 1.306-1.308c0-0.722-0.585-1.308-1.306-1.308s-1.306 0.585-1.306 1.308zM10.311 19.319c0 0.729 0.59 1.32 1.318 1.32s1.318-0.591 1.318-1.32c0-0.729-0.59-1.32-1.318-1.32s-1.318 0.591-1.318 1.32z"></path><path stroke-linejoin="miter" stroke-linecap="round" stroke-miterlimit="4" stroke-width="1" d="M10.617 23.224l-1.704 2.257M21.383 23.224l1.704 2.257M8.24 20.992l-2.742 1.119M23.618 20.992l2.742 1.119"></path><path stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="4" stroke-width="0.875" d="M16 21.469c-1.433 0-2.348 0.995-2.317 2.222 0.033 1.329 1.015 2.222 2.317 2.222s2.314-1.031 2.317-2.222c0.003-1.227-0.884-2.222-2.317-2.222z"></path></svg>',
'linkedin' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg>',
'mail' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M20,4H4C2.895,4,2,4.895,2,6v12c0,1.105,0.895,2,2,2h16c1.105,0,2-0.895,2-2V6C22,4.895,21.105,4,20,4z M20,8.236l-8,4.882 L4,8.236V6h16V8.236z"></path></svg>',
'mastodon' => '<svg viewBox="-1 -1 26 26" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M23.193 7.879c0-5.206-3.411-6.732-3.411-6.732C18.062.357 15.108.025 12.041 0h-.076c-3.068.025-6.02.357-7.74 1.147 0 0-3.411 1.526-3.411 6.732 0 1.192-.023 2.618.015 4.129.124 5.092.934 10.109 5.641 11.355 2.17.574 4.034.695 5.535.612 2.722-.15 4.25-.972 4.25-.972l-.09-1.975s-1.945.613-4.129.539c-2.165-.074-4.449-.233-4.799-2.891a5.499 5.499 0 0 1-.048-.745s2.125.52 4.817.643c1.646.075 3.19-.097 4.758-.283 3.007-.359 5.625-2.212 5.954-3.905.517-2.665.475-6.507.475-6.507zm-4.024 6.709h-2.497V8.469c0-1.29-.543-1.944-1.628-1.944-1.2 0-1.802.776-1.802 2.312v3.349h-2.483v-3.35c0-1.536-.602-2.312-1.802-2.312-1.085 0-1.628.655-1.628 1.944v6.119H4.832V8.284c0-1.289.328-2.313.987-3.07.68-.758 1.569-1.146 2.674-1.146 1.278 0 2.246.491 2.886 1.474L12 6.585l.622-1.043c.64-.983 1.608-1.474 2.886-1.474 1.104 0 1.994.388 2.674 1.146.658.757.986 1.781.986 3.07v6.304z"/></svg>',
'medium' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M20.962,7.257l-5.457,8.867l-3.923-6.375l3.126-5.08c0.112-0.182,0.319-0.286,0.527-0.286c0.05,0,0.1,0.008,0.149,0.02 c0.039,0.01,0.078,0.023,0.114,0.041l5.43,2.715l0.006,0.003c0.004,0.002,0.007,0.006,0.011,0.008 C20.971,7.191,20.98,7.227,20.962,7.257z M9.86,8.592v5.783l5.14,2.57L9.86,8.592z M15.772,17.331l4.231,2.115 C20.554,19.721,21,19.529,21,19.016V8.835L15.772,17.331z M8.968,7.178L3.665,4.527C3.569,4.479,3.478,4.456,3.395,4.456 C3.163,4.456,3,4.636,3,4.938v11.45c0,0.306,0.224,0.669,0.498,0.806l4.671,2.335c0.12,0.06,0.234,0.088,0.337,0.088 c0.29,0,0.494-0.225,0.494-0.602V7.231C9,7.208,8.988,7.188,8.968,7.178z"></path></svg>',
'meetup' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M19.24775,14.722a3.57032,3.57032,0,0,1-2.94457,3.52073,3.61886,3.61886,0,0,1-.64652.05634c-.07314-.0008-.10187.02846-.12507.09547A2.38881,2.38881,0,0,1,13.49453,20.094a2.33092,2.33092,0,0,1-1.827-.50716.13635.13635,0,0,0-.19878-.00408,3.191,3.191,0,0,1-2.104.60248,3.26309,3.26309,0,0,1-3.00324-2.71993,2.19076,2.19076,0,0,1-.03512-.30865c-.00156-.08579-.03413-.1189-.11608-.13493a2.86421,2.86421,0,0,1-1.23189-.56111,2.945,2.945,0,0,1-1.166-2.05749,2.97484,2.97484,0,0,1,.87524-2.50774.112.112,0,0,0,.02091-.16107,2.7213,2.7213,0,0,1-.36648-1.48A2.81256,2.81256,0,0,1,6.57673,7.58838a.35764.35764,0,0,0,.28869-.22819,4.2208,4.2208,0,0,1,6.02892-1.90111.25161.25161,0,0,0,.22023.0243,3.65608,3.65608,0,0,1,3.76031.90678A3.57244,3.57244,0,0,1,17.95918,8.626a2.97339,2.97339,0,0,1,.01829.57356.10637.10637,0,0,0,.0853.12792,1.97669,1.97669,0,0,1,1.27939,1.33733,2.00266,2.00266,0,0,1-.57112,2.12652c-.05284.05166-.04168.08328-.01173.13489A3.51189,3.51189,0,0,1,19.24775,14.722Zm-6.35959-.27836a1.6984,1.6984,0,0,0,1.14556,1.61113,3.82039,3.82039,0,0,0,1.036.17935,1.46888,1.46888,0,0,0,.73509-.12255.44082.44082,0,0,0,.26057-.44274.45312.45312,0,0,0-.29211-.43375.97191.97191,0,0,0-.20678-.063c-.21326-.03806-.42754-.0701-.63973-.11215a.54787.54787,0,0,1-.50172-.60926,2.75864,2.75864,0,0,1,.1773-.901c.1763-.535.414-1.045.64183-1.55913A12.686,12.686,0,0,0,15.85,10.47863a1.58461,1.58461,0,0,0,.04861-.87208,1.04531,1.04531,0,0,0-.85432-.83981,1.60658,1.60658,0,0,0-1.23654.16594.27593.27593,0,0,1-.36286-.03413c-.085-.0747-.16594-.15379-.24918-.23055a.98682.98682,0,0,0-1.33577-.04933,6.1468,6.1468,0,0,1-.4989.41615.47762.47762,0,0,1-.51535.03566c-.17448-.09307-.35512-.175-.53531-.25665a1.74949,1.74949,0,0,0-.56476-.2016,1.69943,1.69943,0,0,0-1.61654.91787,8.05815,8.05815,0,0,0-.32952.80126c-.45471,1.2557-.82507,2.53825-1.20838,3.81639a1.24151,1.24151,0,0,0,.51532,1.44389,1.42659,1.42659,0,0,0,1.22008.17166,1.09728,1.09728,0,0,0,.66994-.69764c.44145-1.04111.839-2.09989,1.25981-3.14926.11581-.28876.22792-.57874.35078-.86438a.44548.44548,0,0,1,.69189-.19539.50521.50521,0,0,1,.15044.43836,1.75625,1.75625,0,0,1-.14731.50453c-.27379.69219-.55265,1.38236-.82766,2.074a2.0836,2.0836,0,0,0-.14038.42876.50719.50719,0,0,0,.27082.57722.87236.87236,0,0,0,.66145.02739.99137.99137,0,0,0,.53406-.532q.61571-1.20914,1.228-2.42031.28423-.55863.57585-1.1133a.87189.87189,0,0,1,.29055-.35253.34987.34987,0,0,1,.37634-.01265.30291.30291,0,0,1,.12434.31459.56716.56716,0,0,1-.04655.1915c-.05318.12739-.10286.25669-.16183.38156-.34118.71775-.68754,1.43273-1.02568,2.152A2.00213,2.00213,0,0,0,12.88816,14.44366Zm4.78568,5.28972a.88573.88573,0,0,0-1.77139.00465.8857.8857,0,0,0,1.77139-.00465Zm-14.83838-7.296a.84329.84329,0,1,0,.00827-1.68655.8433.8433,0,0,0-.00827,1.68655Zm10.366-9.43673a.83506.83506,0,1,0-.0091,1.67.83505.83505,0,0,0,.0091-1.67Zm6.85014,5.22a.71651.71651,0,0,0-1.433.0093.71656.71656,0,0,0,1.433-.0093ZM5.37528,6.17908A.63823.63823,0,1,0,6.015,5.54483.62292.62292,0,0,0,5.37528,6.17908Zm6.68214,14.80843a.54949.54949,0,1,0-.55052.541A.54556.54556,0,0,0,12.05742,20.98752Zm8.53235-8.49689a.54777.54777,0,0,0-.54027.54023.53327.53327,0,0,0,.532.52293.51548.51548,0,0,0,.53272-.5237A.53187.53187,0,0,0,20.58977,12.49063ZM7.82846,2.4715a.44927.44927,0,1,0,.44484.44766A.43821.43821,0,0,0,7.82846,2.4715Zm13.775,7.60492a.41186.41186,0,0,0-.40065.39623.40178.40178,0,0,0,.40168.40168A.38994.38994,0,0,0,22,10.48172.39946.39946,0,0,0,21.60349,10.07642ZM5.79193,17.96207a.40469.40469,0,0,0-.397-.39646.399.399,0,0,0-.396.405.39234.39234,0,0,0,.39939.389A.39857.39857,0,0,0,5.79193,17.96207Z"></path></svg>',
'pinterest' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.289,2C6.617,2,3.606,5.648,3.606,9.622c0,1.846,1.025,4.146,2.666,4.878c0.25,0.111,0.381,0.063,0.439-0.169 c0.044-0.175,0.267-1.029,0.365-1.428c0.032-0.128,0.017-0.237-0.091-0.362C6.445,11.911,6.01,10.75,6.01,9.668 c0-2.777,2.194-5.464,5.933-5.464c3.23,0,5.49,2.108,5.49,5.122c0,3.407-1.794,5.768-4.13,5.768c-1.291,0-2.257-1.021-1.948-2.277 c0.372-1.495,1.089-3.112,1.089-4.191c0-0.967-0.542-1.775-1.663-1.775c-1.319,0-2.379,1.309-2.379,3.059 c0,1.115,0.394,1.869,0.394,1.869s-1.302,5.279-1.54,6.261c-0.405,1.666,0.053,4.368,0.094,4.604 c0.021,0.126,0.167,0.169,0.25,0.063c0.129-0.165,1.699-2.419,2.142-4.051c0.158-0.59,0.817-2.995,0.817-2.995 c0.43,0.784,1.681,1.446,3.013,1.446c3.963,0,6.822-3.494,6.822-7.833C20.394,5.112,16.849,2,12.289,2"></path></svg>',
'pocket' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M21.927,4.194C21.667,3.48,20.982,3,20.222,3h-0.01h-1.721H3.839C3.092,3,2.411,3.47,2.145,4.17 C2.066,4.378,2.026,4.594,2.026,4.814v6.035l0.069,1.2c0.29,2.73,1.707,5.115,3.899,6.778c0.039,0.03,0.079,0.059,0.119,0.089 l0.025,0.018c1.175,0.859,2.491,1.441,3.91,1.727c0.655,0.132,1.325,0.2,1.991,0.2c0.615,0,1.232-0.057,1.839-0.17 c0.073-0.014,0.145-0.028,0.219-0.044c0.02-0.004,0.042-0.012,0.064-0.023c1.359-0.297,2.621-0.864,3.753-1.691l0.025-0.018 c0.04-0.029,0.08-0.058,0.119-0.089c2.192-1.664,3.609-4.049,3.898-6.778l0.069-1.2V4.814C22.026,4.605,22,4.398,21.927,4.194z M17.692,10.481l-4.704,4.512c-0.266,0.254-0.608,0.382-0.949,0.382c-0.342,0-0.684-0.128-0.949-0.382l-4.705-4.512 C5.838,9.957,5.82,9.089,6.344,8.542c0.524-0.547,1.392-0.565,1.939-0.04l3.756,3.601l3.755-3.601 c0.547-0.524,1.415-0.506,1.939,0.04C18.256,9.089,18.238,9.956,17.692,10.481z"></path></svg>',
'reddit' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22,11.816c0-1.256-1.021-2.277-2.277-2.277c-0.593,0-1.122,0.24-1.526,0.614c-1.481-0.965-3.455-1.594-5.647-1.69 l1.171-3.702l3.18,0.748c0.008,1.028,0.846,1.862,1.876,1.862c1.035,0,1.877-0.842,1.877-1.878c0-1.035-0.842-1.877-1.877-1.877 c-0.769,0-1.431,0.466-1.72,1.13l-3.508-0.826c-0.203-0.047-0.399,0.067-0.46,0.261l-1.35,4.268 c-2.316,0.038-4.411,0.67-5.97,1.671C5.368,9.765,4.853,9.539,4.277,9.539C3.021,9.539,2,10.56,2,11.816 c0,0.814,0.433,1.523,1.078,1.925c-0.037,0.221-0.061,0.444-0.061,0.672c0,3.292,4.011,5.97,8.941,5.97s8.941-2.678,8.941-5.97 c0-0.214-0.02-0.424-0.053-0.632C21.533,13.39,22,12.661,22,11.816z M18.776,4.394c0.606,0,1.1,0.493,1.1,1.1s-0.493,1.1-1.1,1.1 s-1.1-0.494-1.1-1.1S18.169,4.394,18.776,4.394z M2.777,11.816c0-0.827,0.672-1.5,1.499-1.5c0.313,0,0.598,0.103,0.838,0.269 c-0.851,0.676-1.477,1.479-1.812,2.36C2.983,12.672,2.777,12.27,2.777,11.816z M11.959,19.606c-4.501,0-8.164-2.329-8.164-5.193 S7.457,9.22,11.959,9.22s8.164,2.329,8.164,5.193S16.46,19.606,11.959,19.606z M20.636,13.001c-0.326-0.89-0.948-1.701-1.797-2.384 c0.248-0.186,0.55-0.301,0.883-0.301c0.827,0,1.5,0.673,1.5,1.5C21.223,12.299,20.992,12.727,20.636,13.001z M8.996,14.704 c-0.76,0-1.397-0.616-1.397-1.376c0-0.76,0.637-1.397,1.397-1.397c0.76,0,1.376,0.637,1.376,1.397 C10.372,14.088,9.756,14.704,8.996,14.704z M16.401,13.328c0,0.76-0.616,1.376-1.376,1.376c-0.76,0-1.399-0.616-1.399-1.376 c0-0.76,0.639-1.397,1.399-1.397C15.785,11.931,16.401,12.568,16.401,13.328z M15.229,16.708c0.152,0.152,0.152,0.398,0,0.55 c-0.674,0.674-1.727,1.002-3.219,1.002c-0.004,0-0.007-0.002-0.011-0.002c-0.004,0-0.007,0.002-0.011,0.002 c-1.492,0-2.544-0.328-3.218-1.002c-0.152-0.152-0.152-0.398,0-0.55c0.152-0.152,0.399-0.151,0.55,0 c0.521,0.521,1.394,0.775,2.669,0.775c0.004,0,0.007,0.002,0.011,0.002c0.004,0,0.007-0.002,0.011-0.002 c1.275,0,2.148-0.253,2.669-0.775C14.831,16.556,15.078,16.556,15.229,16.708z"></path></svg>',
'skype' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M10.113,2.699c0.033-0.006,0.067-0.013,0.1-0.02c0.033,0.017,0.066,0.033,0.098,0.051L10.113,2.699z M2.72,10.223 c-0.006,0.034-0.011,0.069-0.017,0.103c0.018,0.032,0.033,0.064,0.051,0.095L2.72,10.223z M21.275,13.771 c0.007-0.035,0.011-0.071,0.018-0.106c-0.018-0.031-0.033-0.064-0.052-0.095L21.275,13.771z M13.563,21.199 c0.032,0.019,0.065,0.035,0.096,0.053c0.036-0.006,0.071-0.011,0.105-0.017L13.563,21.199z M22,16.386 c0,1.494-0.581,2.898-1.637,3.953c-1.056,1.057-2.459,1.637-3.953,1.637c-0.967,0-1.914-0.251-2.75-0.725 c0.036-0.006,0.071-0.011,0.105-0.017l-0.202-0.035c0.032,0.019,0.065,0.035,0.096,0.053c-0.543,0.096-1.099,0.147-1.654,0.147 c-1.275,0-2.512-0.25-3.676-0.743c-1.125-0.474-2.135-1.156-3.002-2.023c-0.867-0.867-1.548-1.877-2.023-3.002 c-0.493-1.164-0.743-2.401-0.743-3.676c0-0.546,0.049-1.093,0.142-1.628c0.018,0.032,0.033,0.064,0.051,0.095L2.72,10.223 c-0.006,0.034-0.011,0.069-0.017,0.103C2.244,9.5,2,8.566,2,7.615c0-1.493,0.582-2.898,1.637-3.953 c1.056-1.056,2.46-1.638,3.953-1.638c0.915,0,1.818,0.228,2.622,0.655c-0.033,0.007-0.067,0.013-0.1,0.02l0.199,0.031 c-0.032-0.018-0.066-0.034-0.098-0.051c0.002,0,0.003-0.001,0.004-0.001c0.586-0.112,1.187-0.169,1.788-0.169 c1.275,0,2.512,0.249,3.676,0.742c1.124,0.476,2.135,1.156,3.002,2.024c0.868,0.867,1.548,1.877,2.024,3.002 c0.493,1.164,0.743,2.401,0.743,3.676c0,0.575-0.054,1.15-0.157,1.712c-0.018-0.031-0.033-0.064-0.052-0.095l0.034,0.201 c0.007-0.035,0.011-0.071,0.018-0.106C21.754,14.494,22,15.432,22,16.386z M16.817,14.138c0-1.331-0.613-2.743-3.033-3.282 l-2.209-0.49c-0.84-0.192-1.807-0.444-1.807-1.237c0-0.794,0.679-1.348,1.903-1.348c2.468,0,2.243,1.696,3.468,1.696 c0.645,0,1.209-0.379,1.209-1.031c0-1.521-2.435-2.663-4.5-2.663c-2.242,0-4.63,0.952-4.63,3.488c0,1.221,0.436,2.521,2.839,3.123 l2.984,0.745c0.903,0.223,1.129,0.731,1.129,1.189c0,0.762-0.758,1.507-2.129,1.507c-2.679,0-2.307-2.062-3.743-2.062 c-0.645,0-1.113,0.444-1.113,1.078c0,1.236,1.501,2.886,4.856,2.886C15.236,17.737,16.817,16.199,16.817,14.138z"></path></svg>',
'snapchat' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.065,2a5.526,5.526,0,0,1,3.132.892A5.854,5.854,0,0,1,17.326,5.4a5.821,5.821,0,0,1,.351,2.33q0,.612-.117,2.487a.809.809,0,0,0,.365.091,1.93,1.93,0,0,0,.664-.176,1.93,1.93,0,0,1,.664-.176,1.3,1.3,0,0,1,.729.234.7.7,0,0,1,.351.6.839.839,0,0,1-.41.7,2.732,2.732,0,0,1-.9.41,3.192,3.192,0,0,0-.9.378.728.728,0,0,0-.41.618,1.575,1.575,0,0,0,.156.56,6.9,6.9,0,0,0,1.334,1.953,5.6,5.6,0,0,0,1.881,1.315,5.875,5.875,0,0,0,1.042.3.42.42,0,0,1,.365.456q0,.911-2.852,1.341a1.379,1.379,0,0,0-.143.507,1.8,1.8,0,0,1-.182.605.451.451,0,0,1-.429.241,5.878,5.878,0,0,1-.807-.085,5.917,5.917,0,0,0-.833-.085,4.217,4.217,0,0,0-.807.065,2.42,2.42,0,0,0-.82.293,6.682,6.682,0,0,0-.755.5q-.351.267-.755.527a3.886,3.886,0,0,1-.989.436A4.471,4.471,0,0,1,11.831,22a4.307,4.307,0,0,1-1.256-.176,3.784,3.784,0,0,1-.976-.436q-.4-.26-.749-.527a6.682,6.682,0,0,0-.755-.5,2.422,2.422,0,0,0-.807-.293,4.432,4.432,0,0,0-.82-.065,5.089,5.089,0,0,0-.853.1,5,5,0,0,1-.762.1.474.474,0,0,1-.456-.241,1.819,1.819,0,0,1-.182-.618,1.411,1.411,0,0,0-.143-.521q-2.852-.429-2.852-1.341a.42.42,0,0,1,.365-.456,5.793,5.793,0,0,0,1.042-.3,5.524,5.524,0,0,0,1.881-1.315,6.789,6.789,0,0,0,1.334-1.953A1.575,1.575,0,0,0,6,12.9a.728.728,0,0,0-.41-.618,3.323,3.323,0,0,0-.9-.384,2.912,2.912,0,0,1-.9-.41.814.814,0,0,1-.41-.684.71.71,0,0,1,.338-.593,1.208,1.208,0,0,1,.716-.241,1.976,1.976,0,0,1,.625.169,2.008,2.008,0,0,0,.69.169.919.919,0,0,0,.416-.091q-.117-1.849-.117-2.474A5.861,5.861,0,0,1,6.385,5.4,5.516,5.516,0,0,1,8.625,2.819,7.075,7.075,0,0,1,12.062,2Z"></path></svg>',
'soundcloud' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M8.9,16.1L9,14L8.9,9.5c0-0.1,0-0.1-0.1-0.1c0,0-0.1-0.1-0.1-0.1c-0.1,0-0.1,0-0.1,0.1c0,0-0.1,0.1-0.1,0.1L8.3,14l0.1,2.1 c0,0.1,0,0.1,0.1,0.1c0,0,0.1,0.1,0.1,0.1C8.8,16.3,8.9,16.3,8.9,16.1z M11.4,15.9l0.1-1.8L11.4,9c0-0.1,0-0.2-0.1-0.2 c0,0-0.1,0-0.1,0s-0.1,0-0.1,0c-0.1,0-0.1,0.1-0.1,0.2l0,0.1l-0.1,5c0,0,0,0.7,0.1,2v0c0,0.1,0,0.1,0.1,0.1c0.1,0.1,0.1,0.1,0.2,0.1 c0.1,0,0.1,0,0.2-0.1c0.1,0,0.1-0.1,0.1-0.2L11.4,15.9z M2.4,12.9L2.5,14l-0.2,1.1c0,0.1,0,0.1-0.1,0.1c0,0-0.1,0-0.1-0.1L2.1,14 l0.1-1.1C2.2,12.9,2.3,12.9,2.4,12.9C2.3,12.9,2.4,12.9,2.4,12.9z M3.1,12.2L3.3,14l-0.2,1.8c0,0.1,0,0.1-0.1,0.1 c-0.1,0-0.1,0-0.1-0.1L2.8,14L3,12.2C3,12.2,3,12.2,3.1,12.2C3.1,12.2,3.1,12.2,3.1,12.2z M3.9,11.9L4.1,14l-0.2,2.1 c0,0.1,0,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1L3.5,14l0.2-2.1c0-0.1,0-0.1,0.1-0.1C3.9,11.8,3.9,11.8,3.9,11.9z M4.7,11.9L4.9,14 l-0.2,2.1c0,0.1-0.1,0.1-0.1,0.1c-0.1,0-0.1,0-0.1-0.1L4.3,14l0.2-2.2c0-0.1,0-0.1,0.1-0.1C4.7,11.7,4.7,11.8,4.7,11.9z M5.6,12 l0.2,2l-0.2,2.1c0,0.1-0.1,0.1-0.1,0.1c0,0-0.1,0-0.1,0c0,0,0-0.1,0-0.1L5.1,14l0.2-2c0,0,0-0.1,0-0.1s0.1,0,0.1,0 C5.5,11.9,5.5,11.9,5.6,12L5.6,12z M6.4,10.7L6.6,14l-0.2,2.1c0,0,0,0.1,0,0.1c0,0-0.1,0-0.1,0c-0.1,0-0.1-0.1-0.2-0.2L5.9,14 l0.2-3.3c0-0.1,0.1-0.2,0.2-0.2c0,0,0.1,0,0.1,0C6.4,10.7,6.4,10.7,6.4,10.7z M7.2,10l0.2,4.1l-0.2,2.1c0,0,0,0.1,0,0.1 c0,0-0.1,0-0.1,0c-0.1,0-0.2-0.1-0.2-0.2l-0.1-2.1L6.8,10c0-0.1,0.1-0.2,0.2-0.2c0,0,0.1,0,0.1,0S7.2,9.9,7.2,10z M8,9.6L8.2,14 L8,16.1c0,0.1-0.1,0.2-0.2,0.2c-0.1,0-0.2-0.1-0.2-0.2L7.5,14l0.1-4.4c0-0.1,0-0.1,0.1-0.1c0,0,0.1-0.1,0.1-0.1c0.1,0,0.1,0,0.1,0.1 C8,9.6,8,9.6,8,9.6z M11.4,16.1L11.4,16.1L11.4,16.1z M9.7,9.6L9.8,14l-0.1,2.1c0,0.1,0,0.1-0.1,0.2s-0.1,0.1-0.2,0.1 c-0.1,0-0.1,0-0.1-0.1s-0.1-0.1-0.1-0.2L9.2,14l0.1-4.4c0-0.1,0-0.1,0.1-0.2s0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1S9.7,9.5,9.7,9.6 L9.7,9.6z M10.6,9.8l0.1,4.3l-0.1,2c0,0.1,0,0.1-0.1,0.2c0,0-0.1,0.1-0.2,0.1c-0.1,0-0.1,0-0.2-0.1c0,0-0.1-0.1-0.1-0.2L10,14 l0.1-4.3c0-0.1,0-0.1,0.1-0.2c0,0,0.1-0.1,0.2-0.1c0.1,0,0.1,0,0.2,0.1S10.6,9.7,10.6,9.8z M12.4,14l-0.1,2c0,0.1,0,0.1-0.1,0.2 c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2l-0.1-1l-0.1-1l0.1-5.5v0c0-0.1,0-0.2,0.1-0.2 c0.1,0,0.1-0.1,0.2-0.1c0,0,0.1,0,0.1,0c0.1,0,0.1,0.1,0.1,0.2L12.4,14z M22.1,13.9c0,0.7-0.2,1.3-0.7,1.7c-0.5,0.5-1.1,0.7-1.7,0.7 h-6.8c-0.1,0-0.1,0-0.2-0.1c-0.1-0.1-0.1-0.1-0.1-0.2V8.2c0-0.1,0.1-0.2,0.2-0.3c0.5-0.2,1-0.3,1.6-0.3c1.1,0,2.1,0.4,2.9,1.1 c0.8,0.8,1.3,1.7,1.4,2.8c0.3-0.1,0.6-0.2,1-0.2c0.7,0,1.3,0.2,1.7,0.7C21.8,12.6,22.1,13.2,22.1,13.9L22.1,13.9z"></path></svg>',
'spotify' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,2C6.477,2,2,6.477,2,12c0,5.523,4.477,10,10,10c5.523,0,10-4.477,10-10C22,6.477,17.523,2,12,2 M16.586,16.424 c-0.18,0.295-0.563,0.387-0.857,0.207c-2.348-1.435-5.304-1.76-8.785-0.964c-0.335,0.077-0.67-0.133-0.746-0.469 c-0.077-0.335,0.132-0.67,0.469-0.746c3.809-0.871,7.077-0.496,9.713,1.115C16.673,15.746,16.766,16.13,16.586,16.424 M17.81,13.7 c-0.226,0.367-0.706,0.482-1.072,0.257c-2.687-1.652-6.785-2.131-9.965-1.166C6.36,12.917,5.925,12.684,5.8,12.273 C5.675,11.86,5.908,11.425,6.32,11.3c3.632-1.102,8.147-0.568,11.234,1.328C17.92,12.854,18.035,13.335,17.81,13.7 M17.915,10.865 c-3.223-1.914-8.54-2.09-11.618-1.156C5.804,9.859,5.281,9.58,5.131,9.086C4.982,8.591,5.26,8.069,5.755,7.919 c3.532-1.072,9.404-0.865,13.115,1.338c0.445,0.264,0.59,0.838,0.327,1.282C18.933,10.983,18.359,11.129,17.915,10.865"></path></svg>',
'threads' => '<svg viewBox="0 -6 192 204" xmlns="http://www.w3.org/2000/svg"><path d="M141.537 88.9883C140.71 88.5919 139.87 88.2104 139.019 87.8451C137.537 60.5382 122.616 44.905 97.5619 44.745C97.4484 44.7443 97.3355 44.7443 97.222 44.7443C82.2364 44.7443 69.7731 51.1409 62.102 62.7807L75.881 72.2328C81.6116 63.5383 90.6052 61.6848 97.2286 61.6848C97.3051 61.6848 97.3819 61.6848 97.4576 61.6855C105.707 61.7381 111.932 64.1366 115.961 68.814C118.893 72.2193 120.854 76.925 121.825 82.8638C114.511 81.6207 106.601 81.2385 98.145 81.7233C74.3247 83.0954 59.0111 96.9879 60.0396 116.292C60.5615 126.084 65.4397 134.508 73.775 140.011C80.8224 144.663 89.899 146.938 99.3323 146.423C111.79 145.74 121.563 140.987 128.381 132.296C133.559 125.696 136.834 117.143 138.28 106.366C144.217 109.949 148.617 114.664 151.047 120.332C155.179 129.967 155.42 145.8 142.501 158.708C131.182 170.016 117.576 174.908 97.0135 175.059C74.2042 174.89 56.9538 167.575 45.7381 153.317C35.2355 139.966 29.8077 120.682 29.6052 96C29.8077 71.3178 35.2355 52.0336 45.7381 38.6827C56.9538 24.4249 74.2039 17.11 97.0132 16.9405C119.988 17.1113 137.539 24.4614 149.184 38.788C154.894 45.8136 159.199 54.6488 162.037 64.9503L178.184 60.6422C174.744 47.9622 169.331 37.0357 161.965 27.974C147.036 9.60668 125.202 0.195148 97.0695 0H96.9569C68.8816 0.19447 47.2921 9.6418 32.7883 28.0793C19.8819 44.4864 13.2244 67.3157 13.0007 95.9325L13 96L13.0007 96.0675C13.2244 124.684 19.8819 147.514 32.7883 163.921C47.2921 182.358 68.8816 191.806 96.9569 192H97.0695C122.03 191.827 139.624 185.292 154.118 170.811C173.081 151.866 172.51 128.119 166.26 113.541C161.776 103.087 153.227 94.5962 141.537 88.9883ZM98.4405 129.507C88.0005 130.095 77.1544 125.409 76.6196 115.372C76.2232 107.93 81.9158 99.626 99.0812 98.6368C101.047 98.5234 102.976 98.468 104.871 98.468C111.106 98.468 116.939 99.0737 122.242 100.233C120.264 124.935 108.662 128.946 98.4405 129.507Z"></path></svg>',
'tiktok' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.601273,3.99398422 C22.3543419,3.81786432 22.035286,3.77722295 21.7519316,3.88579503 C20.7673827,4.3053476 19.6367473,4.19781761 18.749359,3.60023293 C17.8619707,3.00264826 17.3390468,1.99663905 17.3606558,0.92862387 C17.366873,0.687165991 17.2757319,0.453316101 17.1076605,0.279488738 C16.937965,0.101864383 16.7030375,0.000936521363 16.4571011,0 L12.8428824,0 C12.343863,0 11.9393277,0.403649581 11.9393277,0.901576573 L11.9393277,16.3365675 C11.9393277,17.581385 10.9279897,18.5905089 9.68044104,18.5905089 C8.43289237,18.5905089 7.42155434,17.581385 7.42155434,16.3365675 C7.42155434,15.09175 8.43289237,14.0826261 9.68044104,14.0826261 C10.1794605,14.0826261 10.5839957,13.6789765 10.5839957,13.1810495 L10.5839957,9.57474321 C10.5839957,9.07681622 10.1794605,8.67316663 9.68044104,8.67316663 C5.44083962,8.67813472 2.00520525,12.1062476 2.00022626,16.3365675 C1.98771579,17.9546233 2.49430163,19.5342383 3.44591375,20.8444504 C3.61458557,21.0808398 5.05966461,19.9481604 4.91870788,19.7535427 C4.19555103,18.760421 3.80646351,17.5641499 3.80733562,16.3365675 C3.81165144,13.4484211 5.91803869,10.991254 8.77688636,10.5394301 L8.77688636,12.3425833 C6.70706914,12.8134053 5.34862709,14.7938709 5.65804701,16.8895228 C5.96746693,18.9851748 7.84059425,20.4905907 9.95854931,20.3457987 C12.0765044,20.2010067 13.7263573,18.4547454 13.7464371,16.3365675 L13.7464371,1.80315315 L15.6167953,1.80315315 C16.0103639,4.20249558 18.0864975,5.96506252 20.5230972,5.96843692 C20.7496837,5.96688212 20.975975,5.95182905 21.2007632,5.92335809 L21.2007632,7.67241664 C19.7293748,7.92650626 18.2152284,7.66195137 16.917914,6.92410808 C16.6383532,6.76305694 16.2939201,6.76305694 16.0143593,6.92410808 C15.7336844,7.0857977 15.5612953,7.38509793 15.562582,7.7084797 L15.562582,16.3365675 C15.5580692,18.2941869 14.5756972,20.1206948 12.9432814,21.2065896 C11.9060301,21.8965766 10.6930991,22.229824 9.48148608,22.189012 C8.78627447,22.1655944 8.08246121,22.0477035 7.42155434,21.774707 C7.12504167,21.5395062 5.484375,20.8444504 4.91870788,19.7535427 C4.66351437,19.2613936 3.0238563,20.6306805 3.44591375,20.8444504 C4.91870788,23.1351563 7.99726562,23.9999684 9.69851213,23.9999684 C13.7074483,23.9999684 17.0406982,20.9190082 17.3606558,16.931608 C17.3657425,16.8836579 17.3657425,16.8353059 17.3606558,16.7873558 L17.3606558,9.10592339 C18.9684136,9.66657941 20.7106733,9.71696914 22.3482777,9.25017564 C22.7469793,9.13449784 23.0153499,8.76257691 22.998837,8.34859907 L22.998837,4.7873716 C23.0148813,4.47165088 22.8640303,4.17060935 22.601273,3.99398422 Z" /></svg>',
'tumblr' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M16.749,17.396c-0.357,0.17-1.041,0.319-1.551,0.332c-1.539,0.041-1.837-1.081-1.85-1.896V9.847h3.861V6.937h-3.847V2.039 c0,0-2.77,0-2.817,0c-0.046,0-0.127,0.041-0.138,0.144c-0.165,1.499-0.867,4.13-3.783,5.181v2.484h1.945v6.282 c0,2.151,1.587,5.206,5.775,5.135c1.413-0.024,2.982-0.616,3.329-1.126L16.749,17.396z"></path></svg>',
'twitch' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M16.499,8.089h-1.636v4.91h1.636V8.089z M12,8.089h-1.637v4.91H12V8.089z M4.228,3.178L3,6.451v13.092h4.499V22h2.456 l2.454-2.456h3.681L21,14.636V3.178H4.228z M19.364,13.816l-2.864,2.865H12l-2.453,2.453V16.68H5.863V4.814h13.501V13.816z"></path></svg>',
'twitter' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.23,5.924c-0.736,0.326-1.527,0.547-2.357,0.646c0.847-0.508,1.498-1.312,1.804-2.27 c-0.793,0.47-1.671,0.812-2.606,0.996C18.324,4.498,17.257,4,16.077,4c-2.266,0-4.103,1.837-4.103,4.103 c0,0.322,0.036,0.635,0.106,0.935C8.67,8.867,5.647,7.234,3.623,4.751C3.27,5.357,3.067,6.062,3.067,6.814 c0,1.424,0.724,2.679,1.825,3.415c-0.673-0.021-1.305-0.206-1.859-0.513c0,0.017,0,0.034,0,0.052c0,1.988,1.414,3.647,3.292,4.023 c-0.344,0.094-0.707,0.144-1.081,0.144c-0.264,0-0.521-0.026-0.772-0.074c0.522,1.63,2.038,2.816,3.833,2.85 c-1.404,1.1-3.174,1.756-5.096,1.756c-0.331,0-0.658-0.019-0.979-0.057c1.816,1.164,3.973,1.843,6.29,1.843 c7.547,0,11.675-6.252,11.675-11.675c0-0.178-0.004-0.355-0.012-0.531C20.985,7.47,21.68,6.747,22.23,5.924z"></path></svg>',
'vimeo' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22.396,7.164c-0.093,2.026-1.507,4.799-4.245,8.32C15.322,19.161,12.928,21,10.97,21c-1.214,0-2.24-1.119-3.079-3.359 c-0.56-2.053-1.119-4.106-1.68-6.159C5.588,9.243,4.921,8.122,4.206,8.122c-0.156,0-0.701,0.328-1.634,0.98L1.594,7.841 c1.027-0.902,2.04-1.805,3.037-2.708C6.001,3.95,7.03,3.327,7.715,3.264c1.619-0.156,2.616,0.951,2.99,3.321 c0.404,2.557,0.685,4.147,0.841,4.769c0.467,2.121,0.981,3.181,1.542,3.181c0.435,0,1.09-0.688,1.963-2.065 c0.871-1.376,1.338-2.422,1.401-3.142c0.125-1.187-0.343-1.782-1.401-1.782c-0.498,0-1.012,0.115-1.541,0.341 c1.023-3.35,2.977-4.977,5.862-4.884C21.511,3.066,22.52,4.453,22.396,7.164z"></path></svg>',
'vk' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M22,7.1c0.2,0.4-0.4,1.5-1.6,3.1c-0.2,0.2-0.4,0.5-0.7,0.9c-0.5,0.7-0.9,1.1-0.9,1.4c-0.1,0.3-0.1,0.6,0.1,0.8 c0.1,0.1,0.4,0.4,0.8,0.9h0l0,0c1,0.9,1.6,1.7,2,2.3c0,0,0,0.1,0.1,0.1c0,0.1,0,0.1,0.1,0.3c0,0.1,0,0.2,0,0.4 c0,0.1-0.1,0.2-0.3,0.3c-0.1,0.1-0.4,0.1-0.6,0.1l-2.7,0c-0.2,0-0.4,0-0.6-0.1c-0.2-0.1-0.4-0.1-0.5-0.2l-0.2-0.1 c-0.2-0.1-0.5-0.4-0.7-0.7s-0.5-0.6-0.7-0.8c-0.2-0.2-0.4-0.4-0.6-0.6C14.8,15,14.6,15,14.4,15c0,0,0,0-0.1,0c0,0-0.1,0.1-0.2,0.2 c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.1-0.1,0.3-0.2,0.5c-0.1,0.2-0.1,0.5-0.1,0.8c0,0.1,0,0.2,0,0.3c0,0.1-0.1,0.2-0.1,0.2l0,0.1 c-0.1,0.1-0.3,0.2-0.6,0.2h-1.2c-0.5,0-1,0-1.5-0.2c-0.5-0.1-1-0.3-1.4-0.6s-0.7-0.5-1.1-0.7s-0.6-0.4-0.7-0.6l-0.3-0.3 c-0.1-0.1-0.2-0.2-0.3-0.3s-0.4-0.5-0.7-0.9s-0.7-1-1.1-1.6c-0.4-0.6-0.8-1.3-1.3-2.2C2.9,9.4,2.5,8.5,2.1,7.5C2,7.4,2,7.3,2,7.2 c0-0.1,0-0.1,0-0.2l0-0.1c0.1-0.1,0.3-0.2,0.6-0.2l2.9,0c0.1,0,0.2,0,0.2,0.1S5.9,6.9,5.9,7L6,7c0.1,0.1,0.2,0.2,0.3,0.3 C6.4,7.7,6.5,8,6.7,8.4C6.9,8.8,7,9,7.1,9.2l0.2,0.3c0.2,0.4,0.4,0.8,0.6,1.1c0.2,0.3,0.4,0.5,0.5,0.7s0.3,0.3,0.4,0.4 c0.1,0.1,0.3,0.1,0.4,0.1c0.1,0,0.2,0,0.3-0.1c0,0,0,0,0.1-0.1c0,0,0.1-0.1,0.1-0.2c0.1-0.1,0.1-0.3,0.1-0.5c0-0.2,0.1-0.5,0.1-0.8 c0-0.4,0-0.8,0-1.3c0-0.3,0-0.5-0.1-0.8c0-0.2-0.1-0.4-0.1-0.5L9.6,7.6C9.4,7.3,9.1,7.2,8.7,7.1C8.6,7.1,8.6,7,8.7,6.9 C8.9,6.7,9,6.6,9.1,6.5c0.4-0.2,1.2-0.3,2.5-0.3c0.6,0,1,0.1,1.4,0.1c0.1,0,0.3,0.1,0.3,0.1c0.1,0.1,0.2,0.1,0.2,0.3 c0,0.1,0.1,0.2,0.1,0.3s0,0.3,0,0.5c0,0.2,0,0.4,0,0.6c0,0.2,0,0.4,0,0.7c0,0.3,0,0.6,0,0.9c0,0.1,0,0.2,0,0.4c0,0.2,0,0.4,0,0.5 c0,0.1,0,0.3,0,0.4s0.1,0.3,0.1,0.4c0.1,0.1,0.1,0.2,0.2,0.3c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.3-0.1c0.1-0.1,0.2-0.2,0.4-0.4 s0.3-0.4,0.5-0.7c0.2-0.3,0.5-0.7,0.7-1.1c0.4-0.7,0.8-1.5,1.1-2.3c0-0.1,0.1-0.1,0.1-0.2c0-0.1,0.1-0.1,0.1-0.1l0,0l0.1,0 c0,0,0,0,0.1,0s0.2,0,0.2,0l3,0c0.3,0,0.5,0,0.7,0S21.9,7,21.9,7L22,7.1z"></path></svg>',
'whatsapp' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M16.75,13.96C17,14.09 17.16,14.16 17.21,14.26C17.27,14.37 17.25,14.87 17,15.44C16.8,16 15.76,16.54 15.3,16.56C14.84,16.58 14.83,16.92 12.34,15.83C9.85,14.74 8.35,12.08 8.23,11.91C8.11,11.74 7.27,10.53 7.31,9.3C7.36,8.08 8,7.5 8.26,7.26C8.5,7 8.77,6.97 8.94,7H9.41C9.56,7 9.77,6.94 9.96,7.45L10.65,9.32C10.71,9.45 10.75,9.6 10.66,9.76L10.39,10.17L10,10.59C9.88,10.71 9.74,10.84 9.88,11.09C10,11.35 10.5,12.18 11.2,12.87C12.11,13.75 12.91,14.04 13.15,14.17C13.39,14.31 13.54,14.29 13.69,14.13L14.5,13.19C14.69,12.94 14.85,13 15.08,13.08L16.75,13.96M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C10.03,22 8.2,21.43 6.65,20.45L2,22L3.55,17.35C2.57,15.8 2,13.97 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12C4,13.72 4.54,15.31 5.46,16.61L4.5,19.5L7.39,18.54C8.69,19.46 10.28,20 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4Z" /></svg>',
// phpcs:disable WordPress.WP.CapitalPDangit.Misspelled
'wordpress' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.158,12.786L9.46,20.625c0.806,0.237,1.657,0.366,2.54,0.366c1.047,0,2.051-0.181,2.986-0.51 c-0.024-0.038-0.046-0.079-0.065-0.124L12.158,12.786z M3.009,12c0,3.559,2.068,6.634,5.067,8.092L3.788,8.341 C3.289,9.459,3.009,10.696,3.009,12z M18.069,11.546c0-1.112-0.399-1.881-0.741-2.48c-0.456-0.741-0.883-1.368-0.883-2.109 c0-0.826,0.627-1.596,1.51-1.596c0.04,0,0.078,0.005,0.116,0.007C16.472,3.904,14.34,3.009,12,3.009 c-3.141,0-5.904,1.612-7.512,4.052c0.211,0.007,0.41,0.011,0.579,0.011c0.94,0,2.396-0.114,2.396-0.114 C7.947,6.93,8.004,7.642,7.52,7.699c0,0-0.487,0.057-1.029,0.085l3.274,9.739l1.968-5.901l-1.401-3.838 C9.848,7.756,9.389,7.699,9.389,7.699C8.904,7.67,8.961,6.93,9.446,6.958c0,0,1.484,0.114,2.368,0.114 c0.94,0,2.397-0.114,2.397-0.114c0.485-0.028,0.542,0.684,0.057,0.741c0,0-0.488,0.057-1.029,0.085l3.249,9.665l0.897-2.996 C17.841,13.284,18.069,12.316,18.069,11.546z M19.889,7.686c0.039,0.286,0.06,0.593,0.06,0.924c0,0.912-0.171,1.938-0.684,3.22 l-2.746,7.94c2.673-1.558,4.47-4.454,4.47-7.771C20.991,10.436,20.591,8.967,19.889,7.686z M12,22C6.486,22,2,17.514,2,12 C2,6.486,6.486,2,12,2c5.514,0,10,4.486,10,10C22,17.514,17.514,22,12,22z"></path></svg>',
'x' => '<svg viewBox="0 -46 300 392" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M178.57 127.15 290.27 0h-26.46l-97.03 110.38L89.34 0H0l117.13 166.93L0 300.25h26.46l102.4-116.59 81.8 116.59h89.34M36.01 19.54H76.66l187.13 262.13h-40.66"/></svg>',
'yelp' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12.271,16.718v1.417q-.011,3.257-.067,3.4a.707.707,0,0,1-.569.446,4.637,4.637,0,0,1-2.024-.424A4.609,4.609,0,0,1,7.8,20.565a.844.844,0,0,1-.19-.4.692.692,0,0,1,.044-.29,3.181,3.181,0,0,1,.379-.524q.335-.412,2.019-2.409.011,0,.669-.781a.757.757,0,0,1,.44-.274.965.965,0,0,1,.552.039.945.945,0,0,1,.418.324.732.732,0,0,1,.139.468Zm-1.662-2.8a.783.783,0,0,1-.58.781l-1.339.435q-3.067.981-3.257.981a.711.711,0,0,1-.6-.4,2.636,2.636,0,0,1-.19-.836,9.134,9.134,0,0,1,.011-1.857,3.559,3.559,0,0,1,.335-1.389.659.659,0,0,1,.625-.357,22.629,22.629,0,0,1,2.253.859q.781.324,1.283.524l.937.379a.771.771,0,0,1,.4.34A.982.982,0,0,1,10.609,13.917Zm9.213,3.313a4.467,4.467,0,0,1-1.021,1.8,4.559,4.559,0,0,1-1.512,1.417.671.671,0,0,1-.7-.078q-.156-.112-2.052-3.2l-.524-.859a.761.761,0,0,1-.128-.513.957.957,0,0,1,.217-.513.774.774,0,0,1,.926-.29q.011.011,1.327.446,2.264.736,2.7.887a2.082,2.082,0,0,1,.524.229.673.673,0,0,1,.245.68Zm-7.5-7.049q.056,1.137-.6,1.361-.647.19-1.272-.792L6.237,4.08a.7.7,0,0,1,.212-.691,5.788,5.788,0,0,1,2.314-1,5.928,5.928,0,0,1,2.5-.352.681.681,0,0,1,.547.5q.034.2.245,3.407T12.327,10.181Zm7.384,1.2a.679.679,0,0,1-.29.658q-.167.112-3.67.959-.747.167-1.015.257l.011-.022a.769.769,0,0,1-.513-.044.914.914,0,0,1-.413-.357.786.786,0,0,1,0-.971q.011-.011.836-1.137,1.394-1.908,1.673-2.275a2.423,2.423,0,0,1,.379-.435A.7.7,0,0,1,17.435,8a4.482,4.482,0,0,1,1.372,1.489,4.81,4.81,0,0,1,.9,1.868v.034Z"></path></svg>',
'youtube' => '<svg viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg>',
);
}

131
inc/core/IconsHelper.php Normal file
View File

@ -0,0 +1,131 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Icons helpers.
*
* @package PressBook
*/
namespace PressBook;
/**
* SVG icons related helpers.
*/
class IconsHelper implements Serviceable {
/**
* Register service features.
*/
public function register() {
add_filter( 'walker_nav_menu_start_el', array( $this, 'nav_menu_social_icons' ), 10, 4 );
}
/**
* Display SVG icons in social links menu.
*
* @param string $item_output The menu item output.
* @param WP_Post $item Menu item object.
* @param int $depth Depth of the menu.
* @param array $args wp_nav_menu() arguments.
* @return string $item_output The menu item output with social icon.
*/
public function nav_menu_social_icons( $item_output, $item, $depth, $args ) {
// Change SVG icon inside social links menu if there is supported URL.
if ( 'social' === $args->theme_location ) {
$svg = self::get_social_link_svg( $item->url, 26 );
if ( empty( $svg ) ) {
$svg = self::get_icon_svg( 'link' );
}
$item_output = str_replace( $args->link_after, '</span>' . $svg, $item_output );
}
return $item_output;
}
/**
* Gets the SVG code for a given icon.
*
* @param string $icon Icon key.
* @param integer $size Icon size.
* @return string
*/
public static function get_icon_svg( $icon, $size = 24 ) {
return Icons::get_svg( 'ui', $icon, $size );
}
/**
* Gets the SVG code for a given social icon.
*
* @param string $icon Icon key.
* @param int $size Icon size.
* @return string
*/
public static function get_social_icon_svg( $icon, $size = 24 ) {
return Icons::get_svg( 'social', $icon, $size );
}
/**
* Detects the social network from a URL and returns the SVG code for its icon.
*
* @param string $uri Social link uri.
* @param int $size Icon size.
* @return string
*/
public static function get_social_link_svg( $uri, $size = 24 ) {
return Icons::get_social_link_svg( $uri, $size );
}
/**
* Output and Get Theme SVG.
* Output and get the SVG markup for an icon in the Icons class.
*
* @param string $icon Icon key.
* @param integer $size Icon size.
* @param string $group The icon group.
*/
public static function the_theme_svg( $icon, $size = 24, $group = 'ui' ) {
echo self::get_theme_svg( $icon, $size, $group ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Escaped in IconsHelper::get_theme_svg().
}
/**
* Get information about the SVG icon.
*
* @param string $icon Icon key.
* @param integer $size Icon size.
* @param string $group The icon group.
*/
public static function get_theme_svg( $icon, $size = 24, $group = 'ui' ) {
// Make sure that only our allowed tags and attributes are included.
$svg = wp_kses(
Icons::get_svg( $group, $icon, $size ),
array(
'svg' => array(
'class' => true,
'xmlns' => true,
'width' => true,
'height' => true,
'viewbox' => true,
'aria-hidden' => true,
'role' => true,
'focusable' => true,
),
'path' => array(
'fill' => true,
'fill-rule' => true,
'd' => true,
'transform' => true,
),
'polygon' => array(
'fill' => true,
'fill-rule' => true,
'points' => true,
'transform' => true,
'focusable' => true,
),
)
);
if ( ! $svg ) {
return false;
}
return $svg;
}
}

80
inc/core/Jetpack.php Normal file
View File

@ -0,0 +1,80 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Jetpack compatibility.
*
* @link https://jetpack.com/
*
* @package PressBook
*/
namespace PressBook;
/**
* Setup Jetpack for the theme.
*/
class Jetpack implements Serviceable {
/**
* Register service features.
*/
public function register() {
if ( class_exists( '\Jetpack' ) ) {
add_action( 'after_setup_theme', array( $this, 'jetpack_setup' ) );
}
}
/**
* Jetpack setup function.
*
* See: https://jetpack.com/support/infinite-scroll/
* See: https://jetpack.com/support/responsive-videos/
* See: https://jetpack.com/support/content-options/
*/
public function jetpack_setup() {
// Add theme support for Infinite Scroll.
add_theme_support(
'infinite-scroll',
array(
'container' => 'primary',
'render' => array( $this, 'infinite_scroll_render' ),
'footer' => 'page',
)
);
// Add theme support for Responsive Videos.
add_theme_support( 'jetpack-responsive-videos' );
// Add theme support for Content Options.
add_theme_support(
'jetpack-content-options',
array(
'post-details' => array(
'stylesheet' => 'pressbook-style',
'date' => '.posted-on',
'categories' => '.cat-links',
'tags' => '.tag-links',
'author' => '.byline',
'comment' => '.comments-link',
),
'featured-images' => array(
'archive' => true,
'post' => true,
'page' => true,
),
)
);
}
/**
* Custom render function for Infinite Scroll.
*/
public function infinite_scroll_render() {
while ( have_posts() ) {
the_post();
if ( is_search() ) {
get_template_part( 'template-parts/content', 'search' );
} else {
get_template_part( 'template-parts/content' );
}
}
}
}

105
inc/core/Menu.php Normal file
View File

@ -0,0 +1,105 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Menu service.
*
* @package PressBook
*/
namespace PressBook;
use PressBook\Options\PrimaryNavbar;
/**
* Register menu locations, add menu dropdown icons for the theme.
*/
class Menu implements Serviceable {
/**
* Register service features.
*/
public function register() {
add_action( 'after_setup_theme', array( $this, 'register_nav_menus' ) );
add_filter( 'walker_nav_menu_start_el', array( $this, 'add_dropdown_icons' ), 10, 4 );
}
/**
* Register menu locations.
*/
public function register_nav_menus() {
// This theme uses wp_nav_menu() in three locations.
register_nav_menus(
apply_filters(
'pressbook_register_nav_menus_args',
array(
'menu-1' => esc_html__( 'Primary', 'pressbook' ),
'menu-2' => esc_html__( 'Top Menu', 'pressbook' ),
'social' => esc_html__( 'Social Links Menu', 'pressbook' ),
)
)
);
}
/**
* Filter the HTML output of a nav menu item to add the dropdown button that reveal the sub-menu.
*
* @param string $item_output Nav menu item HTML.
* @param object $item Nav menu item.
* @param int $depth The depth of the menu.
* @param array $args Array of menu args, such as theme location.
* @return string Modified nav menu item HTML.
*/
public function add_dropdown_icons( $item_output, $item, $depth, $args ) {
// Only add the sub-menu button to the main navigation.
if ( 'menu-1' === $args->theme_location ) {
// Skip if the item has no sub-menu.
if ( in_array( 'menu-item-has-children', $item->classes, true ) ) {
$item_output .= '<button class="main-navigation-arrow-btn" aria-expanded="false"><span class="screen-reader-text">' . esc_html__( 'Toggle sub-menu', 'pressbook' ) . '</span>' . IconsHelper::get_theme_svg( 'chevron_down' ) . '</button>';
}
}
return $item_output;
}
/**
* Output HTML for the primary menu.
*/
public static function primary_menu() {
if ( PrimaryNavbar::get_primary_navbar_search() ) {
$search = ( '<li class="primary-menu-search">' .
'<a href="#" class="primary-menu-search-toggle" aria-expanded="false"><span class="screen-reader-text">' . esc_html__( 'Toggle search form', 'pressbook' ) . '</span>' . IconsHelper::get_theme_svg( 'search' ) . IconsHelper::get_theme_svg( 'close' ) . '</a>' .
'<div class="search-form-wrap">' . get_search_form( array( 'echo' => false ) ) . '</div>' .
'</li>' );
} else {
$search = '';
}
wp_nav_menu(
array(
'theme_location' => 'menu-1',
'menu_id' => 'primary-menu',
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s' . $search . '</ul>',
)
);
}
/**
* Get top menus class.
*
* @return string
*/
public static function top_menus_class() {
$left_menu_active = has_nav_menu( 'social' );
$right_menu_active = has_nav_menu( 'menu-2' );
$top_menus_class = 'top-menus';
if ( $left_menu_active && $right_menu_active ) {
$top_menus_class .= ' top-menus-left-right';
} elseif ( $left_menu_active ) {
$top_menus_class .= ' top-menus-left';
} elseif ( $right_menu_active ) {
$top_menus_class .= ' top-menus-right';
}
return apply_filters( 'pressbook_top_menus_class', $top_menus_class );
}
}

27
inc/core/Options.php Normal file
View File

@ -0,0 +1,27 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Options base class.
*
* @package PressBook
*/
namespace PressBook;
/**
* Base class for theme options service classes.
*/
abstract class Options implements Serviceable {
/**
* Allows to define customizer sections, settings, and controls.
*/
public function register() {
add_action( 'customize_register', array( $this, 'customize_register' ) );
}
/**
* Define customizer sections, settings, and controls.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
abstract public function customize_register( $wp_customize );
}

View File

@ -0,0 +1,96 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Alpha color picker customizer control.
*
* This control adds a second slider for opacity to the stock WordPress color picker,
* and it includes logic to seamlessly convert between RGBa and Hex color values as
* opacity is added to or removed from a color.
*
* This Alpha Color Picker is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this Alpha Color Picker. If not, see <http://www.gnu.org/licenses/>.
*
* @package PressBook
*/
namespace PressBook\Options;
use \WP_Customize_Control;
if ( class_exists( '\WP_Customize_Control' ) ) {
/**
* Alpha color picker control class.
*/
class AlphaColorControl extends WP_Customize_Control {
/**
* Control name.
*
* @var string
*/
public $type = 'alpha-color';
/**
* Add support for palettes to be passed in.
*
* Supported palette values are true, false, or an array of RGBa and Hex colors.
*
* @var bool
*/
public $palette;
/**
* Add support for showing the opacity value on the slider handle.
*
* @var array
*/
public $show_opacity;
/**
* Enqueue scripts and styles.
*/
public function enqueue() {
wp_enqueue_style( 'alpha-color-picker', get_theme_file_uri( 'inc/alpha-color-picker.css' ), array( 'wp-color-picker' ), PRESSBOOK_VERSION );
wp_enqueue_script( 'alpha-color-picker', get_theme_file_uri( 'js/alpha-color-picker.js' ), array( 'jquery', 'wp-color-picker' ), PRESSBOOK_VERSION, true );
}
/**
* Render the control.
*/
public function render_content() {
// Process the palette.
if ( is_array( $this->palette ) ) {
$palette = implode( '|', $this->palette );
} else {
// Default to true.
$palette = ( ( false === $this->palette ) || ( 'false' === $this->palette ) ) ? 'false' : 'true';
}
// Support passing show_opacity as string or boolean. Default to true.
$show_opacity = ( ( false === $this->show_opacity ) || ( 'false' === $this->show_opacity ) ) ? 'false' : 'true';
// Output the label and description if they were passed in.
if ( isset( $this->label ) && ( '' !== $this->label ) ) {
echo '<span class="customize-control-title">' . esc_html( $this->label ) . '</span>';
}
if ( isset( $this->description ) && ( '' !== $this->description ) ) {
echo '<span class="description customize-control-description">' . esc_html( $this->description ) . '</span>';
}
?>
<label>
<input class="alpha-color-control" type="text" data-show-opacity="<?php echo esc_attr( $show_opacity ); ?>" data-palette="<?php echo esc_attr( $palette ); ?>" data-default-color="<?php echo esc_attr( $this->settings['default']->default ); ?>" <?php $this->link(); ?>>
</label>
<?php
}
}
}

View File

@ -0,0 +1,58 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer block section base class.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
/**
* Base class for block section service classes.
*/
abstract class BlockSection extends Options {
/**
* Get an array of pattern-blocks formatted as [ ID => Title ].
*
* @return array
*/
public function pattern_blocks_choices() {
$pattern_blocks = get_posts(
array(
'post_type' => 'wp_block',
'numberposts' => 100,
)
);
$pattern_blocks_choices = array( 0 => esc_html__( 'Select a block', 'pressbook' ) );
foreach ( $pattern_blocks as $block ) {
$pattern_blocks_choices[ $block->ID ] = $block->post_title;
}
return $pattern_blocks_choices;
}
/**
* Block description.
*
* @return string
*/
public function block_description() {
return wp_kses(
sprintf(
/* translators: %s: URL to the pattern-blocks admin page. */
__( 'This is the content of the block section. You can create or edit the block section in the <a href="%s" target="_blank">Pattern Blocks Manager (opens in a new window)</a>.<br>After creating the pattern block, you may need to refresh this customizer page and then select the newly created block.<br>The selected block content will appear on the block section.', 'pressbook' ),
esc_url( admin_url( 'edit.php?post_type=wp_block' ) )
),
array(
'a' => array(
'href' => array(),
'target' => array(),
),
'br' => array(),
)
);
}
}

493
inc/core/Options/Blog.php Normal file
View File

@ -0,0 +1,493 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer blog options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Blog options service class.
*/
class Blog extends Options {
/**
* Add blog options for theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_blog( $wp_customize );
$this->set_archive_post_layout_lg( $wp_customize );
$this->set_archive_content( $wp_customize );
$this->set_show_archv_title( $wp_customize );
$this->set_hide_post_meta_all( $wp_customize );
$this->set_hide_post_meta_date( $wp_customize );
$this->set_hide_post_meta_author( $wp_customize );
$this->set_hide_post_meta_cat( $wp_customize );
$this->set_hide_post_meta_tag( $wp_customize );
$this->set_featured_label( $wp_customize );
}
/**
* Section: Blog Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_blog( $wp_customize ) {
$wp_customize->add_section(
'sec_blog',
array(
'title' => esc_html__( 'Blog Options', 'pressbook' ),
'description' => esc_html__( 'You can customize the blog options in here.', 'pressbook' ),
'priority' => 156,
)
);
}
/**
* Add setting: Archive Post Layout (Large-Screen Devices).
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_archive_post_layout_lg( $wp_customize ) {
$wp_customize->add_setting(
'set_archive_post_layout_lg',
array(
'default' => self::get_archive_post_layout_lg( true ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_archive_post_layout_lg',
array(
'section' => 'sec_blog',
'type' => 'radio',
'choices' => array(
'rows' => esc_html__( 'Thumbnail-Content - Rows', 'pressbook' ),
'columns' => esc_html__( 'Thumbnail-Content - Columns (Contain)', 'pressbook' ),
'cover' => esc_html__( 'Thumbnail-Content - Columns (Cover)', 'pressbook' ),
),
'label' => esc_html__( 'Blog Archive Post Layout (Large-Screen Devices)', 'pressbook' ),
'description' => esc_html__( 'Select the layout for the blog post in archive pages. Default: Thumbnail-Content - Columns (Cover)', 'pressbook' ),
)
);
}
/**
* Get setting: Archive Post Layout (Large-Screen Devices).
*
* @param bool $get_default Get default.
* @return string
*/
public static function get_archive_post_layout_lg( $get_default = false ) {
$default = apply_filters( 'pressbook_default_archive_post_layout_lg', 'cover' );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_archive_post_layout_lg', $default );
}
/**
* Add setting: Archive Content.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_archive_content( $wp_customize ) {
$wp_customize->add_setting(
'set_archive_content',
array(
'default' => self::get_archive_content( true ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_archive_content',
array(
'section' => 'sec_blog',
'type' => 'radio',
'choices' => array(
'full' => esc_html__( 'Full text', 'pressbook' ),
'excerpt' => esc_html__( 'Summary', 'pressbook' ),
),
'label' => esc_html__( 'Blog Archive Content', 'pressbook' ),
'description' => esc_html__( 'Select the content to show in the blog archive pages. Default: Summary', 'pressbook' ),
)
);
}
/**
* Get setting: Archive Content.
*
* @param bool $get_default Get default.
* @return string
*/
public static function get_archive_content( $get_default = false ) {
$default = apply_filters( 'pressbook_default_archive_content', 'excerpt' );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_archive_content', $default );
}
/**
* Add setting: Show Archive Page Title.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_show_archv_title( $wp_customize ) {
$wp_customize->add_setting(
'set_show_archv_title',
array(
'type' => 'theme_mod',
'default' => self::get_show_archv_title( true ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_show_archv_title',
array(
'section' => 'sec_blog',
'type' => 'checkbox',
'label' => esc_html__( 'Show Archive Page Title', 'pressbook' ),
'description' => esc_html__( 'In archive pages, you can show the archive title and archive description. This is applicable to any archive pages like tag, category, etc.', 'pressbook' ),
)
);
}
/**
* Get setting: Show Archive Page Title.
*
* @param bool $get_default Get default.
* @return bool
*/
public static function get_show_archv_title( $get_default = false ) {
$default = apply_filters( 'pressbook_default_show_archive_title', true );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_show_archv_title', $default );
}
/**
* Add setting: Hide Post Meta: All.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_hide_post_meta_all( $wp_customize ) {
$wp_customize->add_setting(
'set_hide_post_meta[all]',
array(
'type' => 'theme_mod',
'default' => self::get_hide_post_meta_default( 'all' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_hide_post_meta[all]',
array(
'section' => 'sec_blog',
'type' => 'checkbox',
'label' => esc_html__( 'Post Meta: Hide All', 'pressbook' ),
'description' => esc_html__( 'Hide all the post meta data including date, author, number of comments, etc.', 'pressbook' ),
)
);
}
/**
* Add setting: Hide Post Meta: Date.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_hide_post_meta_date( $wp_customize ) {
$wp_customize->add_setting(
'set_hide_post_meta[date]',
array(
'type' => 'theme_mod',
'default' => self::get_hide_post_meta_default( 'date' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_hide_post_meta[date]',
array(
'section' => 'sec_blog',
'type' => 'checkbox',
'label' => esc_html__( 'Post Meta: Hide Date', 'pressbook' ),
'description' => esc_html__( 'Hide only the post date. Checking the "Post Meta: Hide All" option will override this option.', 'pressbook' ),
)
);
}
/**
* Add setting: Hide Post Meta: Author.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_hide_post_meta_author( $wp_customize ) {
$wp_customize->add_setting(
'set_hide_post_meta[author]',
array(
'type' => 'theme_mod',
'default' => self::get_hide_post_meta_default( 'author' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_hide_post_meta[author]',
array(
'section' => 'sec_blog',
'type' => 'checkbox',
'label' => esc_html__( 'Post Meta: Hide Author', 'pressbook' ),
'description' => esc_html__( 'Hide only the post author. Checking the "Post Meta: Hide All" option will override this option.', 'pressbook' ),
)
);
}
/**
* Add setting: Hide Post: Hide Categories.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_hide_post_meta_cat( $wp_customize ) {
$wp_customize->add_setting(
'set_hide_post_meta[cat]',
array(
'type' => 'theme_mod',
'default' => self::get_hide_post_meta_default( 'cat' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_hide_post_meta[cat]',
array(
'section' => 'sec_blog',
'type' => 'checkbox',
'label' => esc_html__( 'Post: Hide Categories', 'pressbook' ),
'description' => esc_html__( 'Hide the post categories.', 'pressbook' ),
)
);
}
/**
* Add setting: Hide Post: Hide Tags.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_hide_post_meta_tag( $wp_customize ) {
$wp_customize->add_setting(
'set_hide_post_meta[tag]',
array(
'type' => 'theme_mod',
'default' => self::get_hide_post_meta_default( 'tag' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_hide_post_meta[tag]',
array(
'section' => 'sec_blog',
'type' => 'checkbox',
'label' => esc_html__( 'Post: Hide Tags', 'pressbook' ),
'description' => esc_html__( 'Hide the post tags.', 'pressbook' ),
)
);
}
/**
* Get setting: Hide Post Meta.
*
* @return array
*/
public static function get_hide_post_meta() {
return wp_parse_args(
get_theme_mod( 'set_hide_post_meta', array() ),
self::get_hide_post_meta_default()
);
}
/**
* Get default setting: Hide Post Meta.
*
* @param string $key Setting key.
* @return mixed|array
*/
public static function get_hide_post_meta_default( $key = '' ) {
$default = apply_filters(
'pressbook_default_hide_post_meta',
array(
'all' => false,
'date' => false,
'author' => false,
'cat' => false,
'tag' => false,
)
);
if ( array_key_exists( $key, $default ) ) {
return $default[ $key ];
}
return $default;
}
/**
* Add setting: Featured (Sticky Post) Label.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_featured_label( $wp_customize ) {
$wp_customize->add_setting(
'set_featured_label',
array(
'default' => self::get_featured_label( true ),
'transport' => 'refresh',
'sanitize_callback' => 'sanitize_text_field',
)
);
$wp_customize->add_control(
'set_featured_label',
array(
'section' => 'sec_blog',
'type' => 'text',
'label' => esc_html__( 'Featured (Sticky Post) Label', 'pressbook' ),
'description' => esc_html__( 'You can change the "Featured" label for the sticky posts. Leave it empty for default text.', 'pressbook' ),
)
);
}
/**
* Get setting: Featured (Sticky Post) Label.
*
* @param bool $get_default Get default.
* @return string
*/
public static function get_featured_label( $get_default = false ) {
$default = apply_filters( 'pressbook_default_featured_label', '' );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_featured_label', $default );
}
/**
* Get text: Featured (Sticky Post) Label.
*
* @return string
*/
public static function featured_label_text() {
$label = self::get_featured_label();
if ( '' !== $label ) {
return $label;
}
return esc_html_x( 'Featured', 'Label for sticky posts', 'pressbook' );
}
/**
* Get entry meta class.
*
* @return string
*/
public static function entry_meta_class() {
$hide_post_meta = self::get_hide_post_meta();
$entry_meta_class = 'entry-meta';
if ( $hide_post_meta['all'] ) {
$entry_meta_class .= ' hide-entry-meta';
}
if ( $hide_post_meta['date'] ) {
$entry_meta_class .= ' hide-posted-on';
}
if ( $hide_post_meta['author'] ) {
$entry_meta_class .= ' hide-posted-by';
}
return apply_filters( 'pressbook_entry_meta_class', $entry_meta_class );
}
/**
* Get entry meta categories class.
*
* @return string
*/
public static function entry_meta_cat_class() {
$hide_post_meta = self::get_hide_post_meta();
$entry_meta_cat_class = 'cat-links';
if ( $hide_post_meta['cat'] ) {
$entry_meta_cat_class .= ' hide-clip';
}
return apply_filters( 'pressbook_entry_meta_cat_class', $entry_meta_cat_class );
}
/**
* Get entry meta tags class.
*
* @return string
*/
public static function entry_meta_tag_class() {
$hide_post_meta = self::get_hide_post_meta();
$entry_meta_tag_class = 'tag-links';
if ( $hide_post_meta['tag'] ) {
$entry_meta_tag_class .= ' hide-clip';
}
return apply_filters( 'pressbook_entry_meta_tag_class', $entry_meta_tag_class );
}
/**
* Get archive title class and option.
*
* @return array
*/
public static function archv_title() {
$show_archv_title = self::get_show_archv_title();
$archv_title_class = 'page-title';
$archv_header_class = 'pb-archv-header';
if ( $show_archv_title ) {
$archv_title_class .= ' pb-archv-title';
$archv_header_class .= ' pb-archv-header-show';
} else {
$archv_title_class .= ' screen-reader-text';
}
return array(
'show' => $show_archv_title,
'class' => apply_filters( 'pressbook_archv_title_class', $archv_title_class ),
'header' => apply_filters( 'pressbook_archv_header_class', $archv_header_class ),
);
}
}

194
inc/core/Options/Colors.php Normal file
View File

@ -0,0 +1,194 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer colors options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Colors options service class.
*/
class Colors extends Options {
/**
* Add colors options for the theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->set_header_bg_color( $wp_customize );
$this->set_site_title_color( $wp_customize );
$this->set_tagline_color( $wp_customize );
$this->set_button_bg_color_1( $wp_customize );
$this->set_button_bg_color_2( $wp_customize );
}
/**
* Add setting: Header Background Color.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_header_bg_color( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[header_bg_color]',
array(
'default' => CSSRules::default_styles( 'header_bg_color' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_alpha_color' ),
)
);
$wp_customize->add_control(
new AlphaColorControl(
$wp_customize,
'set_styles[header_bg_color]',
array(
'section' => 'colors',
'label' => esc_html__( 'Header Background Color', 'pressbook' ),
'settings' => 'set_styles[header_bg_color]',
'palette' => self::default_alpha_palette(),
'show_opacity' => true,
)
)
);
}
/**
* Add setting: Site Title Color.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_site_title_color( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[site_title_color]',
array(
'default' => CSSRules::default_styles( 'site_title_color' ),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color',
)
);
$wp_customize->add_control(
new \WP_Customize_Color_Control(
$wp_customize,
'set_styles[site_title_color]',
array(
'section' => 'colors',
'label' => esc_html__( 'Site Title Color', 'pressbook' ),
)
)
);
}
/**
* Add setting: Tagline Color.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_tagline_color( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[tagline_color]',
array(
'default' => CSSRules::default_styles( 'tagline_color' ),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color',
)
);
$wp_customize->add_control(
new \WP_Customize_Color_Control(
$wp_customize,
'set_styles[tagline_color]',
array(
'section' => 'colors',
'label' => esc_html__( 'Tagline Color', 'pressbook' ),
)
)
);
}
/**
* Add setting: Button Background Color 1.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_button_bg_color_1( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[button_bg_color_1]',
array(
'default' => CSSRules::default_styles( 'button_bg_color_1' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_alpha_color' ),
)
);
$wp_customize->add_control(
new AlphaColorControl(
$wp_customize,
'set_styles[button_bg_color_1]',
array(
'section' => 'colors',
'label' => esc_html__( 'Button Gradient Background 1', 'pressbook' ),
'settings' => 'set_styles[button_bg_color_1]',
'palette' => true,
'show_opacity' => true,
)
)
);
}
/**
* Add setting: Button Background Color 2.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_button_bg_color_2( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[button_bg_color_2]',
array(
'default' => CSSRules::default_styles( 'button_bg_color_2' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_alpha_color' ),
)
);
$wp_customize->add_control(
new AlphaColorControl(
$wp_customize,
'set_styles[button_bg_color_2]',
array(
'section' => 'colors',
'label' => esc_html__( 'Button Gradient Background 2', 'pressbook' ),
'settings' => 'set_styles[button_bg_color_2]',
'palette' => true,
'show_opacity' => true,
)
)
);
}
/**
* Get default alpha color palette.
*
* @return array
*/
public static function default_alpha_palette() {
return apply_filters(
'pressbook_default_alpha_color_palette',
array(
'#ffffff',
'#000000',
'rgba(28,28,28,0.95)',
'rgba(7,18,66,0.95)',
'rgba(0,33,21,0.95)',
'rgba(0,0,0,0.8)',
'rgba(22,0,0,0.95)',
)
);
}
}

View File

@ -0,0 +1,176 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer content layout options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
/**
* Content layout options service class.
*/
class Content extends Options {
/**
* Add content layout options for the theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_content( $wp_customize );
$this->set_content_layout_no_t_padding( $wp_customize );
$this->set_content_layout_no_b_padding( $wp_customize );
$this->set_content_layout_no_x_padding( $wp_customize );
}
/**
* Section: Content Layout Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_content( $wp_customize ) {
$wp_customize->add_section(
'sec_content',
array(
'title' => esc_html__( 'Content Layout', 'pressbook' ),
'description' => esc_html__( 'You can customize the content layout options in here.', 'pressbook' ),
'priority' => 154,
)
);
}
/**
* Add setting: Remove Top Padding.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_content_layout_no_t_padding( $wp_customize ) {
$wp_customize->add_setting(
'set_content_layout[no_t_padding]',
array(
'default' => self::get_content_layout_default( 'no_t_padding' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_content_layout[no_t_padding]',
array(
'section' => 'sec_content',
'type' => 'checkbox',
'label' => esc_html__( 'Remove Top Padding', 'pressbook' ),
)
);
}
/**
* Add setting: Remove Bottom Padding.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_content_layout_no_b_padding( $wp_customize ) {
$wp_customize->add_setting(
'set_content_layout[no_b_padding]',
array(
'default' => self::get_content_layout_default( 'no_b_padding' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_content_layout[no_b_padding]',
array(
'section' => 'sec_content',
'type' => 'checkbox',
'label' => esc_html__( 'Remove Bottom Padding', 'pressbook' ),
)
);
}
/**
* Add setting: Remove Horizontal Padding.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_content_layout_no_x_padding( $wp_customize ) {
$wp_customize->add_setting(
'set_content_layout[no_x_padding]',
array(
'default' => self::get_content_layout_default( 'no_x_padding' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_content_layout[no_x_padding]',
array(
'section' => 'sec_content',
'type' => 'checkbox',
'label' => esc_html__( 'Remove Horizontal Padding', 'pressbook' ),
)
);
}
/**
* Get setting: Content Layout.
*
* @return array
*/
public static function get_content_layout() {
return wp_parse_args(
get_theme_mod( 'set_content_layout', array() ),
self::get_content_layout_default()
);
}
/**
* Get default setting: Content Layout.
*
* @param string $key Setting key.
* @return mixed|array
*/
public static function get_content_layout_default( $key = '' ) {
$default = apply_filters(
'pressbook_default_content_layout',
array(
'no_t_padding' => false,
'no_b_padding' => false,
'no_x_padding' => false,
)
);
if ( array_key_exists( $key, $default ) ) {
return $default[ $key ];
}
return $default;
}
/**
* Get body classes for content layout.
*
* @return string
*/
public static function get_content_layout_body_class() {
$content_layout = self::get_content_layout();
$body_class = '';
if ( $content_layout['no_t_padding'] ) {
$body_class .= ' content-no-t-padding';
}
if ( $content_layout['no_b_padding'] ) {
$body_class .= ' content-no-b-padding';
}
if ( $content_layout['no_x_padding'] ) {
$body_class .= ' content-no-x-padding';
}
return ltrim( $body_class );
}
}

147
inc/core/Options/Fonts.php Normal file
View File

@ -0,0 +1,147 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer fonts options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Fonts options service class.
*/
class Fonts extends Options {
/**
* Fonts choices.
*
* @var array
*/
protected $choices = array();
/**
* Add fonts options for theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_fonts( $wp_customize );
$this->set_button_font_wgt( $wp_customize );
$this->set_heading_font_wgt( $wp_customize );
$this->set_site_title_font_wgt( $wp_customize );
}
/**
* Section: Fonts Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_fonts( $wp_customize ) {
$wp_customize->add_section(
'sec_fonts',
array(
'title' => esc_html__( 'Fonts', 'pressbook' ),
'description' => esc_html__( 'You can customize the fonts options in here.', 'pressbook' ),
'priority' => 42,
)
);
}
/**
* Add setting: Button Font Weight.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_button_font_wgt( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[button_font_wgt]',
array(
'default' => CSSRules::default_styles( 'button_font_wgt' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_styles[button_font_wgt]',
array(
'section' => 'sec_fonts',
'type' => 'select',
'choices' => $this->font_weights(),
'label' => esc_html__( 'Button Font Weight', 'pressbook' ),
'description' => esc_html__( 'Default: 600', 'pressbook' ),
)
);
}
/**
* Add setting: Heading Font Weight.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_heading_font_wgt( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[heading_font_wgt]',
array(
'default' => CSSRules::default_styles( 'heading_font_wgt' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_styles[heading_font_wgt]',
array(
'section' => 'sec_fonts',
'type' => 'select',
'choices' => $this->font_weights(),
'label' => esc_html__( 'Heading Font Weight', 'pressbook' ),
'description' => esc_html__( 'Default: 700', 'pressbook' ),
)
);
}
/**
* Add setting: Site Title Font Weight.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_site_title_font_wgt( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[site_title_font_wgt]',
array(
'default' => CSSRules::default_styles( 'site_title_font_wgt' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_styles[site_title_font_wgt]',
array(
'section' => 'sec_fonts',
'type' => 'select',
'choices' => $this->font_weights(),
'label' => esc_html__( 'Site Title Font Weight', 'pressbook' ),
'description' => esc_html__( 'Default: 700', 'pressbook' ),
)
);
}
/**
* Font Weights.
*
* @return array
*/
public function font_weights() {
return array(
'400' => esc_html_x( '400', 'Font Weight', 'pressbook' ),
'500' => esc_html_x( '500', 'Font Weight', 'pressbook' ),
'600' => esc_html_x( '600', 'Font Weight', 'pressbook' ),
'700' => esc_html_x( '700', 'Font Weight', 'pressbook' ),
);
}
}

237
inc/core/Options/Footer.php Normal file
View File

@ -0,0 +1,237 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer footer options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Footer options service class.
*/
class Footer extends Options {
/**
* Add footer options for theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_footer( $wp_customize );
$this->set_copyright_text( $wp_customize );
$this->set_hide_go_to_top( $wp_customize );
$this->set_footer_bg_color( $wp_customize );
$this->set_footer_credit_link_color( $wp_customize );
}
/**
* Section: Footer Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_footer( $wp_customize ) {
$wp_customize->add_section(
'sec_footer',
array(
'title' => esc_html__( 'Footer Options', 'pressbook' ),
'description' => esc_html__( 'You can customize the footer options in here.', 'pressbook' ),
'priority' => 160,
)
);
}
/**
* Add setting: Copyright Text.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_copyright_text( $wp_customize ) {
$wp_customize->add_setting(
'set_copyright_text',
array(
'default' => self::get_copyright_text( true ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_copyright_text' ),
)
);
$wp_customize->add_control(
'set_copyright_text',
array(
'section' => 'sec_footer',
'type' => 'textarea',
'label' => esc_html__( 'Copyright Text', 'pressbook' ),
'description' => esc_html__( 'You can change the copyright text in the footer. You may use the following tags: em, strong, span, a, br.', 'pressbook' ),
)
);
$wp_customize->selective_refresh->add_partial(
'set_copyright_text',
array(
'selector' => '.copyright-text',
'container_inclusive' => true,
'render_callback' => array( $this, 'render_copyright_text' ),
)
);
}
/**
* Get setting: Copyright Text.
*
* @param bool $get_default Get default.
* @return string
*/
public static function get_copyright_text( $get_default = false ) {
$default = apply_filters(
'pressbook_default_copyright_text',
sprintf(
/* translators: 1: current year, 2: blog name */
esc_html__( 'Copyright &copy; %1$s %2$s.', 'pressbook' ),
esc_html( date_i18n( _x( 'Y', 'copyright date format', 'pressbook' ) ) ),
get_bloginfo( 'name', 'display' ) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
)
);
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_copyright_text', $default );
}
/**
* Render copyright text for selective refresh.
*
* @return void
*/
public function render_copyright_text() {
get_template_part( 'template-parts/footer/copyright-text' );
}
/**
* Add setting: Hide Go To Top Button.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_hide_go_to_top( $wp_customize ) {
$wp_customize->add_setting(
'set_hide_go_to_top',
array(
'type' => 'theme_mod',
'default' => self::get_hide_go_to_top( true ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_hide_go_to_top',
array(
'section' => 'sec_footer',
'type' => 'checkbox',
'label' => esc_html__( 'Hide Go To Top Button', 'pressbook' ),
)
);
}
/**
* Get setting: Hide Go To Top Button.
*
* @param bool $get_default Get default.
* @return bool
*/
public static function get_hide_go_to_top( $get_default = false ) {
$default = apply_filters( 'pressbook_default_hide_go_to_top', false );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_hide_go_to_top', $default );
}
/**
* Add setting: Footer Background Color.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_footer_bg_color( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[footer_bg_color]',
array(
'default' => CSSRules::default_styles( 'footer_bg_color' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_alpha_color' ),
)
);
$wp_customize->add_control(
new AlphaColorControl(
$wp_customize,
'set_styles[footer_bg_color]',
array(
'section' => 'sec_footer',
'label' => esc_html__( 'Footer Background Color', 'pressbook' ),
'settings' => 'set_styles[footer_bg_color]',
'palette' => Colors::default_alpha_palette(),
'show_opacity' => true,
)
)
);
}
/**
* Add setting: Footer Credit Link Color.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_footer_credit_link_color( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[footer_credit_link_color]',
array(
'default' => CSSRules::default_styles( 'footer_credit_link_color' ),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color',
)
);
$wp_customize->add_control(
new \WP_Customize_Color_Control(
$wp_customize,
'set_styles[footer_credit_link_color]',
array(
'section' => 'sec_footer',
'label' => esc_html__( 'Footer Credit Link Color', 'pressbook' ),
)
)
);
}
/**
* Get allowed tags for copyright text.
*
* @return array
*/
public static function copyright_text_allowed_tags() {
return apply_filters(
'pressbook_copyright_text_allowed_tags',
array(
'span' => array( 'class' => array() ),
'em' => array(),
'strong' => array(),
'br' => array(),
'a' => array(
'href' => array(),
'title' => array(),
'rel' => array(),
'class' => array(),
),
)
);
}
}

View File

@ -0,0 +1,332 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer footer block options service.
*
* @package PressBook
*/
namespace PressBook\Options;
/**
* Footer block options service class.
*/
class FooterBlock extends BlockSection {
const SETTING_KEYS = array( 'id', 'full_width', 'b_margin', 'in_front', 'in_blog', 'in_archive', 'in_post', 'in_page' );
/**
* Add footer block options for the theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_footer_block( $wp_customize );
$this->set_footer_block( $wp_customize, 1 );
$this->selective_refresh_block_1( $wp_customize, 1 );
}
/**
* Section: Footer Block Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_footer_block( $wp_customize ) {
$wp_customize->add_section(
'sec_footer_block',
array(
'title' => esc_html__( 'Footer Block', 'pressbook' ),
'description' => esc_html__( 'You can customize the footer block options in here.', 'pressbook' ),
'priority' => 153,
)
);
}
/**
* Add setting: Footer Block.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
* @param int $number Block number.
*/
public function set_footer_block( $wp_customize, $number = 1 ) {
$setting_key = ( 'set_footer_block[' . absint( $number ) . ']' );
$set_id = ( $setting_key . '[id]' );
$wp_customize->add_setting(
$set_id,
array(
'type' => 'theme_mod',
'default' => self::get_footer_block_default( 'id' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_block_post' ),
)
);
$wp_customize->add_control(
$set_id,
array(
'section' => 'sec_footer_block',
'type' => 'select',
'choices' => $this->pattern_blocks_choices(),
'label' => sprintf(
/* translators: %s: footer block number */
esc_html__( 'Footer Block %s', 'pressbook' ),
absint( $number )
),
'description' => $this->block_description(),
)
);
$set_full_width = ( $setting_key . '[full_width]' );
$wp_customize->add_setting(
$set_full_width,
array(
'type' => 'theme_mod',
'default' => self::get_footer_block_default( 'full_width' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_full_width,
array(
'section' => 'sec_footer_block',
'type' => 'checkbox',
'label' => esc_html__( 'Set Full Width', 'pressbook' ),
'description' => sprintf(
/* translators: %s: footer block number */
esc_html__( 'Footer Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_b_margin = ( $setting_key . '[b_margin]' );
$wp_customize->add_setting(
$set_b_margin,
array(
'type' => 'theme_mod',
'default' => self::get_footer_block_default( 'b_margin' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_b_margin,
array(
'section' => 'sec_footer_block',
'type' => 'checkbox',
'label' => esc_html__( 'Bottom Margin', 'pressbook' ),
'description' => sprintf(
/* translators: %s: footer block number */
esc_html__( 'Footer Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_front = ( $setting_key . '[in_front]' );
$wp_customize->add_setting(
$set_in_front,
array(
'type' => 'theme_mod',
'default' => self::get_footer_block_default( 'in_front' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_front,
array(
'section' => 'sec_footer_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Front Page', 'pressbook' ),
'description' => sprintf(
/* translators: %s: footer block number */
esc_html__( 'Footer Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_blog = ( $setting_key . '[in_blog]' );
$wp_customize->add_setting(
$set_in_blog,
array(
'type' => 'theme_mod',
'default' => self::get_footer_block_default( 'in_blog' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_blog,
array(
'section' => 'sec_footer_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Blog Page', 'pressbook' ),
'description' => sprintf(
/* translators: %s: footer block number */
esc_html__( 'Footer Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_archive = ( $setting_key . '[in_archive]' );
$wp_customize->add_setting(
$set_in_archive,
array(
'type' => 'theme_mod',
'default' => self::get_footer_block_default( 'in_archive' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_archive,
array(
'section' => 'sec_footer_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Archive Pages', 'pressbook' ),
'description' => sprintf(
/* translators: %s: footer block number */
esc_html__( 'Footer Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_post = ( $setting_key . '[in_post]' );
$wp_customize->add_setting(
$set_in_post,
array(
'type' => 'theme_mod',
'default' => self::get_footer_block_default( 'in_post' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_post,
array(
'section' => 'sec_footer_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Posts', 'pressbook' ),
'description' => sprintf(
/* translators: %s: footer block number */
esc_html__( 'Footer Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_page = ( $setting_key . '[in_page]' );
$wp_customize->add_setting(
$set_in_page,
array(
'type' => 'theme_mod',
'default' => self::get_footer_block_default( 'in_page' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_page,
array(
'section' => 'sec_footer_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Pages', 'pressbook' ),
'description' => sprintf(
/* translators: %s: footer block number */
esc_html__( 'Footer Block %s', 'pressbook' ),
absint( $number )
),
)
);
}
/**
* Get setting: Footer Block.
*
* @param int $number Block number.
* @return array.
*/
public static function get_footer_block( $number = 1 ) {
$setting_key = get_theme_mod( 'set_footer_block', array() );
if ( array_key_exists( $number, $setting_key ) ) {
return wp_parse_args(
$setting_key[ $number ],
self::get_footer_block_default()
);
}
return self::get_footer_block_default();
}
/**
* Get default setting: Footer Block.
*
* @param string $key Setting key.
* @return mixed|array
*/
public static function get_footer_block_default( $key = '' ) {
$default = apply_filters(
'pressbook_default_footer_block',
array(
'id' => '',
'full_width' => false,
'b_margin' => true,
'in_front' => true,
'in_blog' => true,
'in_archive' => false,
'in_post' => false,
'in_page' => false,
)
);
if ( array_key_exists( $key, $default ) ) {
return $default[ $key ];
}
return $default;
}
/**
* Selective Refresh: Footer Block 1.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
* @param int $number Block number.
*/
public function selective_refresh_block_1( $wp_customize, $number ) {
$setting_key = ( 'set_footer_block[' . absint( $number ) . ']' );
foreach ( static::SETTING_KEYS as $key ) {
$wp_customize->selective_refresh->add_partial(
( $setting_key . '[' . $key . ']' ),
array(
'selector' => '.footer-block-' . absint( $number ),
'container_inclusive' => true,
'render_callback' => function() {
get_template_part( 'template-parts/footer/block-section' );
},
)
);
}
}
}

View File

@ -0,0 +1,127 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer general options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
/**
* General options service class.
*/
class General extends Options {
/**
* Add general options for theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_general( $wp_customize );
$this->set_search_form_button_text( $wp_customize );
$this->set_read_more_text( $wp_customize );
}
/**
* Section: General Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_general( $wp_customize ) {
$wp_customize->add_section(
'sec_general',
array(
'title' => esc_html__( 'General Options', 'pressbook' ),
'description' => esc_html__( 'You can customize the general options in here.', 'pressbook' ),
'priority' => 156,
)
);
}
/**
* Add setting: Search Form Button Text.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_search_form_button_text( $wp_customize ) {
$wp_customize->add_setting(
'set_search_form_button_text',
array(
'default' => self::get_search_form_button_text( true ),
'transport' => 'refresh',
'sanitize_callback' => 'sanitize_text_field',
)
);
$wp_customize->add_control(
'set_search_form_button_text',
array(
'section' => 'sec_general',
'type' => 'text',
'label' => esc_html__( 'Search Form Button Text', 'pressbook' ),
'description' => esc_html__( 'You can change the search form button text. Leave it empty for default text. This does not change the button text of search form widget block. To change that, you can directly edit the search form widget block in the editor itself.', 'pressbook' ),
)
);
}
/**
* Get setting: Search Form Button Text.
*
* @param bool $get_default Get default.
* @return string
*/
public static function get_search_form_button_text( $get_default = false ) {
$default = apply_filters( 'pressbook_default_search_form_button_text', '' );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_search_form_button_text', $default );
}
/**
* Add setting: Read More Text.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_read_more_text( $wp_customize ) {
$wp_customize->add_setting(
'set_read_more_text',
array(
'default' => self::get_read_more_text( true ),
'transport' => 'refresh',
'sanitize_callback' => 'sanitize_text_field',
)
);
$wp_customize->add_control(
'set_read_more_text',
array(
'section' => 'sec_general',
'type' => 'text',
'label' => esc_html__( 'Read More Text', 'pressbook' ),
'description' => esc_html__( 'You can change the "Read More" text. Leave it empty for default text.', 'pressbook' ),
)
);
}
/**
* Get setting: Read More Text.
*
* @param bool $get_default Get default.
* @return string
*/
public static function get_read_more_text( $get_default = false ) {
$default = apply_filters( 'pressbook_default_read_more_text', '' );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_read_more_text', $default );
}
}

View File

@ -0,0 +1,332 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer header block options service.
*
* @package PressBook
*/
namespace PressBook\Options;
/**
* Header block options service class.
*/
class HeaderBlock extends BlockSection {
const SETTING_KEYS = array( 'id', 'full_width', 't_margin', 'in_front', 'in_blog', 'in_archive', 'in_post', 'in_page' );
/**
* Add header block options for the theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_header_block( $wp_customize );
$this->set_header_block( $wp_customize, 1 );
$this->selective_refresh_block_1( $wp_customize, 1 );
}
/**
* Section: Header Block Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_header_block( $wp_customize ) {
$wp_customize->add_section(
'sec_header_block',
array(
'title' => esc_html__( 'Header Block', 'pressbook' ),
'description' => esc_html__( 'You can customize the header block options in here.', 'pressbook' ),
'priority' => 153,
)
);
}
/**
* Add setting: Header Block.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
* @param int $number Block number.
*/
public function set_header_block( $wp_customize, $number = 1 ) {
$setting_key = ( 'set_header_block[' . absint( $number ) . ']' );
$set_id = ( $setting_key . '[id]' );
$wp_customize->add_setting(
$set_id,
array(
'type' => 'theme_mod',
'default' => self::get_header_block_default( 'id' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_block_post' ),
)
);
$wp_customize->add_control(
$set_id,
array(
'section' => 'sec_header_block',
'type' => 'select',
'choices' => $this->pattern_blocks_choices(),
'label' => sprintf(
/* translators: %s: header block number */
esc_html__( 'Header Block %s', 'pressbook' ),
absint( $number )
),
'description' => $this->block_description(),
)
);
$set_full_width = ( $setting_key . '[full_width]' );
$wp_customize->add_setting(
$set_full_width,
array(
'type' => 'theme_mod',
'default' => self::get_header_block_default( 'full_width' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_full_width,
array(
'section' => 'sec_header_block',
'type' => 'checkbox',
'label' => esc_html__( 'Set Full Width', 'pressbook' ),
'description' => sprintf(
/* translators: %s: header block number */
esc_html__( 'Header Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_t_margin = ( $setting_key . '[t_margin]' );
$wp_customize->add_setting(
$set_t_margin,
array(
'type' => 'theme_mod',
'default' => self::get_header_block_default( 't_margin' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_t_margin,
array(
'section' => 'sec_header_block',
'type' => 'checkbox',
'label' => esc_html__( 'Top Margin', 'pressbook' ),
'description' => sprintf(
/* translators: %s: header block number */
esc_html__( 'Header Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_front = ( $setting_key . '[in_front]' );
$wp_customize->add_setting(
$set_in_front,
array(
'type' => 'theme_mod',
'default' => self::get_header_block_default( 'in_front' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_front,
array(
'section' => 'sec_header_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Front Page', 'pressbook' ),
'description' => sprintf(
/* translators: %s: header block number */
esc_html__( 'Header Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_blog = ( $setting_key . '[in_blog]' );
$wp_customize->add_setting(
$set_in_blog,
array(
'type' => 'theme_mod',
'default' => self::get_header_block_default( 'in_blog' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_blog,
array(
'section' => 'sec_header_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Blog Page', 'pressbook' ),
'description' => sprintf(
/* translators: %s: header block number */
esc_html__( 'Header Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_archive = ( $setting_key . '[in_archive]' );
$wp_customize->add_setting(
$set_in_archive,
array(
'type' => 'theme_mod',
'default' => self::get_header_block_default( 'in_archive' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_archive,
array(
'section' => 'sec_header_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Archive Pages', 'pressbook' ),
'description' => sprintf(
/* translators: %s: header block number */
esc_html__( 'Header Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_post = ( $setting_key . '[in_post]' );
$wp_customize->add_setting(
$set_in_post,
array(
'type' => 'theme_mod',
'default' => self::get_header_block_default( 'in_post' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_post,
array(
'section' => 'sec_header_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Posts', 'pressbook' ),
'description' => sprintf(
/* translators: %s: header block number */
esc_html__( 'Header Block %s', 'pressbook' ),
absint( $number )
),
)
);
$set_in_page = ( $setting_key . '[in_page]' );
$wp_customize->add_setting(
$set_in_page,
array(
'type' => 'theme_mod',
'default' => self::get_header_block_default( 'in_page' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
$set_in_page,
array(
'section' => 'sec_header_block',
'type' => 'checkbox',
'label' => esc_html__( 'Show in Pages', 'pressbook' ),
'description' => sprintf(
/* translators: %s: header block number */
esc_html__( 'Header Block %s', 'pressbook' ),
absint( $number )
),
)
);
}
/**
* Get setting: Header Block.
*
* @param int $number Block number.
* @return array.
*/
public static function get_header_block( $number = 1 ) {
$setting_key = get_theme_mod( 'set_header_block', array() );
if ( array_key_exists( $number, $setting_key ) ) {
return wp_parse_args(
$setting_key[ $number ],
self::get_header_block_default()
);
}
return self::get_header_block_default();
}
/**
* Get default setting: Header Block.
*
* @param string $key Setting key.
* @return mixed|array
*/
public static function get_header_block_default( $key = '' ) {
$default = apply_filters(
'pressbook_default_header_block',
array(
'id' => '',
'full_width' => false,
't_margin' => true,
'in_front' => true,
'in_blog' => true,
'in_archive' => false,
'in_post' => false,
'in_page' => false,
)
);
if ( array_key_exists( $key, $default ) ) {
return $default[ $key ];
}
return $default;
}
/**
* Selective Refresh: Header Block 1.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
* @param int $number Block number.
*/
public function selective_refresh_block_1( $wp_customize, $number ) {
$setting_key = ( 'set_header_block[' . absint( $number ) . ']' );
foreach ( static::SETTING_KEYS as $key ) {
$wp_customize->selective_refresh->add_partial(
( $setting_key . '[' . $key . ']' ),
array(
'selector' => '.header-block-' . absint( $number ),
'container_inclusive' => true,
'render_callback' => function() {
get_template_part( 'template-parts/header/block-section' );
},
)
);
}
}
}

View File

@ -0,0 +1,154 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer header image options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Header image options service class.
*/
class HeaderImage extends Options {
/**
* Add header image options for the theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->set_header_bg_position( $wp_customize );
$this->set_header_bg_repeat( $wp_customize );
$this->set_header_bg_size( $wp_customize );
}
/**
* Add setting: Header Background Position.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_header_bg_position( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[header_bg_position]',
array(
'default' => CSSRules::default_styles( 'header_bg_position' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_styles[header_bg_position]',
array(
'section' => 'header_image',
'type' => 'select',
'choices' => $this->background_positions(),
'label' => esc_html__( 'Header Background Position', 'pressbook' ),
'description' => esc_html__( 'Default: Center Center', 'pressbook' ),
)
);
}
/**
* Add setting: Header Background Repeat.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_header_bg_repeat( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[header_bg_repeat]',
array(
'default' => CSSRules::default_styles( 'header_bg_repeat' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_styles[header_bg_repeat]',
array(
'section' => 'header_image',
'type' => 'radio',
'choices' => $this->background_repeat(),
'label' => esc_html__( 'Header Background Repeat', 'pressbook' ),
'description' => esc_html__( 'Default: Repeat', 'pressbook' ),
)
);
}
/**
* Add setting: Header Background Size.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_header_bg_size( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[header_bg_size]',
array(
'default' => CSSRules::default_styles( 'header_bg_size' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_styles[header_bg_size]',
array(
'section' => 'header_image',
'type' => 'radio',
'choices' => $this->background_sizes(),
'label' => esc_html__( 'Header Background Size', 'pressbook' ),
'description' => esc_html__( 'Default: Contain', 'pressbook' ),
)
);
}
/**
* Background Positions.
*
* @return array
*/
public function background_positions() {
return array(
'left-top' => esc_html__( 'Left Top', 'pressbook' ),
'left-center' => esc_html__( 'Left Center', 'pressbook' ),
'left-bottom' => esc_html__( 'Left Bottom', 'pressbook' ),
'right-top' => esc_html__( 'Right Top', 'pressbook' ),
'right-center' => esc_html__( 'Right Center', 'pressbook' ),
'right-bottom' => esc_html__( 'Right Bottom', 'pressbook' ),
'center-top' => esc_html__( 'Center Top', 'pressbook' ),
'center-center' => esc_html__( 'Center Center', 'pressbook' ),
'center-bottom' => esc_html__( 'Center Bottom', 'pressbook' ),
);
}
/**
* Background Repeat.
*
* @return array
*/
public function background_repeat() {
return array(
'repeat' => esc_html__( 'Repeat', 'pressbook' ),
'repeat-x' => esc_html__( 'Repeat X', 'pressbook' ),
'repeat-y' => esc_html__( 'Repeat Y', 'pressbook' ),
'no-repeat' => esc_html__( 'No Repeat', 'pressbook' ),
);
}
/**
* Background Sizes.
*
* @return array
*/
public function background_sizes() {
return array(
'auto' => esc_html__( 'Auto', 'pressbook' ),
'cover' => esc_html__( 'Cover', 'pressbook' ),
'contain' => esc_html__( 'Contain', 'pressbook' ),
);
}
}

View File

@ -0,0 +1,115 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer primary navbar options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Primary navbar options service class.
*/
class PrimaryNavbar extends Options {
/**
* Add primary navbar options for theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_primary_navbar( $wp_customize );
$this->set_primary_navbar_bg_color( $wp_customize );
$this->set_primary_navbar_search( $wp_customize );
}
/**
* Section: Primary Navbar Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_primary_navbar( $wp_customize ) {
$wp_customize->add_section(
'sec_primary_navbar',
array(
'title' => esc_html__( 'Primary Navbar', 'pressbook' ),
'description' => esc_html__( 'You can customize the primary navbar options in here.', 'pressbook' ),
'priority' => 153,
)
);
}
/**
* Add setting: Primary Navbar Background Color.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_primary_navbar_bg_color( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[primary_navbar_bg_color]',
array(
'default' => CSSRules::default_styles( 'primary_navbar_bg_color' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_alpha_color' ),
)
);
$wp_customize->add_control(
new AlphaColorControl(
$wp_customize,
'set_styles[primary_navbar_bg_color]',
array(
'section' => 'sec_primary_navbar',
'label' => esc_html__( 'Primary Navbar Background Color', 'pressbook' ),
'settings' => 'set_styles[primary_navbar_bg_color]',
'palette' => true,
'show_opacity' => true,
)
)
);
}
/**
* Add setting: Enable Primary Navbar Search Form.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_primary_navbar_search( $wp_customize ) {
$wp_customize->add_setting(
'set_primary_navbar_search',
array(
'type' => 'theme_mod',
'default' => self::get_primary_navbar_search( true ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_primary_navbar_search',
array(
'section' => 'sec_primary_navbar',
'type' => 'checkbox',
'label' => esc_html__( 'Enable Primary Navbar Search Form', 'pressbook' ),
)
);
}
/**
* Get setting: Enable Primary Navbar Search Form.
*
* @param bool $get_default Get default.
* @return bool
*/
public static function get_primary_navbar_search( $get_default = false ) {
$default = apply_filters( 'pressbook_default_primary_navbar_search', true );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_primary_navbar_search', $default );
}
}

View File

@ -0,0 +1,89 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Options Sanitizer.
*
* @package PressBook
*/
namespace PressBook\Options;
/**
* Sanitizer for theme options.
*/
class Sanitizer {
/**
* Checkbox sanitization.
*
* Sanitization callback for 'checkbox' type controls. This callback sanitizes `$checked`
* as a boolean value, either TRUE or FALSE.
*
* @param bool $checked Whether the checkbox is checked.
* @return bool Whether the checkbox is checked.
*/
public static function sanitize_checkbox( $checked ) {
return ( isset( $checked ) && true === $checked ) ? true : false;
}
/**
* Sanitize select.
*
* @param string $input The input from the setting.
* @param object $setting The selected setting.
*
* @return string $input|$setting->default The input from the setting or the default setting.
*/
public static function sanitize_select( $input, $setting ) {
$input = sanitize_key( $input );
$choices = $setting->manager->get_control( $setting->id )->choices;
return ( array_key_exists( $input, $choices ) ? $input : $setting->default );
}
/**
* Sanitize block post.
*
* @param int $input post id.
* @return int
*/
public static function sanitize_block_post( $input ) {
$post_id = absint( $input );
if ( $post_id && 'wp_block' === get_post_type( $post_id ) ) {
return $post_id;
}
return 0;
}
/**
* Function to sanitize alpha color.
*
* @param string $value Hex or RGBA color.
*
* @return string
*/
public static function sanitize_alpha_color( $value ) {
// This pattern will check and match 3/6/8-character hex, rgb, rgba, hsl, & hsla colors.
$pattern = '/^(\#[\da-f]{3}|\#[\da-f]{6}|\#[\da-f]{8}|rgba\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)(,\s*(0\.\d+|1))\)|hsla\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)(,\s*(0\.\d+|1))\)|rgb\(((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*,\s*){2}((\d{1,2}|1\d\d|2([0-4]\d|5[0-5]))\s*)|hsl\(\s*((\d{1,2}|[1-2]\d{2}|3([0-5]\d|60)))\s*,\s*((\d{1,2}|100)\s*%)\s*,\s*((\d{1,2}|100)\s*%)\))$/';
\preg_match( $pattern, $value, $matches );
// Return the 1st match found.
if ( isset( $matches[0] ) ) {
if ( is_string( $matches[0] ) ) {
return $matches[0];
}
if ( is_array( $matches[0] ) && isset( $matches[0][0] ) ) {
return $matches[0][0];
}
}
// If no match was found, return an empty string.
return '';
}
/**
* Sanitize copyright text.
*
* @param string $input Input text.
* @return string
*/
public static function sanitize_copyright_text( $input ) {
$allowed = Footer::copyright_text_allowed_tags();
return wp_kses( $input, $allowed );
}
}

View File

@ -0,0 +1,341 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer sidebar layout options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Sidebar layout options service class.
*/
class Sidebar extends Options {
/**
* Add sidebar layout options for the theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_sidebar( $wp_customize );
$this->set_side_widget_layout_double_lg( $wp_customize );
$this->set_side_widget_border_color( $wp_customize );
$this->set_side_widget_no_t_padding( $wp_customize );
$this->set_side_widget_no_b_padding( $wp_customize );
$this->set_side_widget_no_x_padding( $wp_customize );
$this->set_side_widget_no_shadow( $wp_customize );
$this->set_sticky_sidebar( $wp_customize );
}
/**
* Section: Sidebar Layout Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_sidebar( $wp_customize ) {
$wp_customize->add_section(
'sec_sidebar',
array(
'title' => esc_html__( 'Sidebar Layout', 'pressbook' ),
'description' => esc_html__( 'You can customize the sidebar layout options in here.', 'pressbook' ),
'priority' => 155,
)
);
}
/**
* Add setting: Double Sidebars Layout (Large-Screen Devices).
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_side_widget_layout_double_lg( $wp_customize ) {
$wp_customize->add_setting(
'set_side_widget[layout_double_lg]',
array(
'default' => self::get_side_widget_default( 'layout_double_lg' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$wp_customize->add_control(
'set_side_widget[layout_double_lg]',
array(
'section' => 'sec_sidebar',
'type' => 'radio',
'choices' => array(
'' => esc_html__( 'One Left and One Right', 'pressbook' ),
'left' => esc_html__( 'Both Sidebars to the Left', 'pressbook' ),
'right' => esc_html__( 'Both Sidebars to the Right', 'pressbook' ),
),
'label' => esc_html__( 'Double Sidebars Layout (Large-Screen Devices)', 'pressbook' ),
'description' => esc_html__( 'Set the layout for the double sidebars. This applies only when both the sidebars (left and right) are active. A sidebar is active when there is at least one widget in it.', 'pressbook' ),
)
);
}
/**
* Add setting: Side Widget Border Color.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_side_widget_border_color( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[side_widget_border_color]',
array(
'default' => CSSRules::default_styles( 'side_widget_border_color' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_alpha_color' ),
)
);
$wp_customize->add_control(
new AlphaColorControl(
$wp_customize,
'set_styles[side_widget_border_color]',
array(
'section' => 'sec_sidebar',
'label' => esc_html__( 'Side Widget Border Color', 'pressbook' ),
'settings' => 'set_styles[side_widget_border_color]',
'palette' => Colors::default_alpha_palette(),
'show_opacity' => true,
)
)
);
}
/**
* Add setting: Remove Top Padding.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_side_widget_no_t_padding( $wp_customize ) {
$wp_customize->add_setting(
'set_side_widget[no_t_padding]',
array(
'default' => self::get_side_widget_default( 'no_t_padding' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_side_widget[no_t_padding]',
array(
'section' => 'sec_sidebar',
'type' => 'checkbox',
'label' => esc_html__( 'Remove Top Padding', 'pressbook' ),
)
);
}
/**
* Add setting: Remove Bottom Padding.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_side_widget_no_b_padding( $wp_customize ) {
$wp_customize->add_setting(
'set_side_widget[no_b_padding]',
array(
'default' => self::get_side_widget_default( 'no_b_padding' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_side_widget[no_b_padding]',
array(
'section' => 'sec_sidebar',
'type' => 'checkbox',
'label' => esc_html__( 'Remove Bottom Padding', 'pressbook' ),
)
);
}
/**
* Add setting: Remove Horizontal Padding.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_side_widget_no_x_padding( $wp_customize ) {
$wp_customize->add_setting(
'set_side_widget[no_x_padding]',
array(
'default' => self::get_side_widget_default( 'no_x_padding' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_side_widget[no_x_padding]',
array(
'section' => 'sec_sidebar',
'type' => 'checkbox',
'label' => esc_html__( 'Remove Horizontal Padding', 'pressbook' ),
)
);
}
/**
* Add setting: Remove Box Shadow.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_side_widget_no_shadow( $wp_customize ) {
$wp_customize->add_setting(
'set_side_widget[no_shadow]',
array(
'default' => self::get_side_widget_default( 'no_shadow' ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_side_widget[no_shadow]',
array(
'section' => 'sec_sidebar',
'type' => 'checkbox',
'label' => esc_html__( 'Remove Box Shadow', 'pressbook' ),
)
);
}
/**
* Get setting: Side Widget.
*
* @return array
*/
public static function get_side_widget() {
return wp_parse_args(
get_theme_mod( 'set_side_widget', array() ),
self::get_side_widget_default()
);
}
/**
* Get default setting: Side Widget.
*
* @param string $key Setting key.
* @return mixed|array
*/
public static function get_side_widget_default( $key = '' ) {
$default = apply_filters(
'pressbook_default_side_widget',
array(
'layout_double_lg' => '',
'no_t_padding' => false,
'no_b_padding' => false,
'no_x_padding' => false,
'no_shadow' => false,
)
);
if ( array_key_exists( $key, $default ) ) {
return $default[ $key ];
}
return $default;
}
/**
* Add setting: Sticky Sidebar.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_sticky_sidebar( $wp_customize ) {
$wp_customize->add_setting(
'set_sticky_sidebar',
array(
'default' => self::get_sticky_sidebar( true ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_sticky_sidebar',
array(
'section' => 'sec_sidebar',
'type' => 'checkbox',
'label' => esc_html__( 'Sticky-Floating Sidebar', 'pressbook' ),
'description' => esc_html__( 'You can enable or disable sticky sidebar that floats on scrolling.', 'pressbook' ),
)
);
}
/**
* Get setting: Sticky Sidebar.
*
* @param bool $get_default Get default.
* @return bool
*/
public static function get_sticky_sidebar( $get_default = false ) {
$default = apply_filters( 'pressbook_default_sticky_sidebar', true );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_sticky_sidebar', $default );
}
/**
* Get body classes for side widget.
*
* @return string
*/
public static function get_side_widget_body_class() {
$side_widget = self::get_side_widget();
$body_class = '';
if ( $side_widget['layout_double_lg'] ) {
$body_class .= ' side-widget-ld-lg-' . esc_attr( $side_widget['layout_double_lg'] );
}
if ( $side_widget['no_t_padding'] ) {
$body_class .= ' side-widget-no-t-padding';
}
if ( $side_widget['no_b_padding'] ) {
$body_class .= ' side-widget-no-b-padding';
}
if ( $side_widget['no_x_padding'] ) {
$body_class .= ' side-widget-no-x-padding';
}
if ( $side_widget['no_shadow'] ) {
$body_class .= ' side-widget-no-shadow';
}
return ltrim( $body_class );
}
/**
* Get sticky sidebar breakpoint screen width.
*
* @return int
*/
public static function get_sticky_breakpoint() {
$double_bp = 1279;
$single_bp = 1023;
if ( is_active_sidebar( 'sidebar-1' ) ) {
if ( is_active_sidebar( 'sidebar-2' ) ) {
return $double_bp;
} else {
return $single_bp;
}
} elseif ( is_active_sidebar( 'sidebar-2' ) ) {
return $single_bp;
} else {
return $single_bp;
}
}
}

View File

@ -0,0 +1,450 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer site identity options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Site identity options service class.
*/
class SiteIdentity extends Options {
const SETTING_NAMES = array( 'logo', 'site_title', 'tagline' );
const SETTING_SIZES = array( 'lg', 'md', 'sm' );
/**
* Register service features.
*/
public function register() {
add_action( 'customize_register', array( $this, 'customize_register' ) );
add_action( 'customize_preview_init', array( $this, 'customize_preview_scripts' ) );
}
/**
* Add site identity options for theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
// Selective refresh for site title.
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
// Selective refresh for site tagline.
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
$this->set_hide_site_title( $wp_customize );
$this->set_hide_site_tagline( $wp_customize );
foreach ( self::SETTING_NAMES as $name ) {
foreach ( self::SETTING_SIZES as $size ) {
$this->set_size( $wp_customize, $name, $size );
$this->selective_refresh_size( $wp_customize, $name, $size );
}
}
}
/**
* Add setting: Hide Site Title.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_hide_site_title( $wp_customize ) {
$wp_customize->add_setting(
'set_hide_site_title',
array(
'type' => 'theme_mod',
'default' => self::get_hide_site_title( true ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_hide_site_title',
array(
'section' => 'title_tagline',
'type' => 'checkbox',
'label' => esc_html__( 'Hide Site Title', 'pressbook' ),
)
);
$wp_customize->selective_refresh->add_partial(
'set_hide_site_title',
array(
'selector' => '.site-branding',
'container_inclusive' => true,
'render_callback' => array( $this, 'render_site_branding' ),
)
);
}
/**
* Get setting: Hide Site Title.
*
* @param bool $get_default Get default.
* @return bool
*/
public static function get_hide_site_title( $get_default = false ) {
$default = apply_filters( 'pressbook_default_hide_site_title', false );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_hide_site_title', $default );
}
/**
* Add setting: Hide Site Tagline.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_hide_site_tagline( $wp_customize ) {
$wp_customize->add_setting(
'set_hide_site_tagline',
array(
'type' => 'theme_mod',
'default' => self::get_hide_site_tagline( true ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_hide_site_tagline',
array(
'section' => 'title_tagline',
'type' => 'checkbox',
'label' => esc_html__( 'Hide Site Tagline', 'pressbook' ),
)
);
$wp_customize->selective_refresh->add_partial(
'set_hide_site_tagline',
array(
'selector' => '.site-branding',
'container_inclusive' => true,
'render_callback' => array( $this, 'render_site_branding' ),
)
);
}
/**
* Get setting: Hide Site Tagline.
*
* @param bool $get_default Get default.
* @return bool
*/
public static function get_hide_site_tagline( $get_default = false ) {
$default = apply_filters( 'pressbook_default_hide_site_tagline', false );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_hide_site_tagline', $default );
}
/**
* Add setting: Size.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
* @param string $name Setting name.
* @param string $size Screen size.
*/
public function set_size( $wp_customize, $name, $size ) {
$key = ( 'set_' . $name . '_size[' . $size . ']' );
$wp_customize->add_setting(
$key,
array(
'type' => 'theme_mod',
'default' => self::get_size_default( $name, $size ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_select' ),
)
);
$method_label = ( 'get_' . $name . '_size_label' );
$wp_customize->add_control(
$key,
array(
'section' => 'title_tagline',
'type' => 'select',
'choices' => $this->sizes(),
'label' => self::$method_label()['label'][ $size ],
'description' => self::$method_label()['desc'][ $size ],
)
);
}
/**
* Get setting: Size.
*
* @param string $name Setting name.
* @return array
*/
public static function get_size( $name ) {
return wp_parse_args(
get_theme_mod( ( 'set_' . $name . '_size' ), array() ),
self::get_size_default( $name )
);
}
/**
* Get default setting: Size.
*
* @param string $name Setting name.
* @param string $size Screen size.
* @return array|string
*/
public static function get_size_default( $name, $size = '' ) {
$method_default = ( 'get_' . $name . '_size_default' );
$default = apply_filters(
( 'pressbook_default_' . $name . '_size' ),
self::$method_default()
);
if ( '' === $size ) {
return $default;
}
if ( array_key_exists( $size, $default ) ) {
return $default[ $size ];
}
return '';
}
/**
* Get default setting: Logo Size.
*
* @return array
*/
public static function get_logo_size_default() {
return array(
'sm' => 1,
'md' => 1,
'lg' => 1,
);
}
/**
* Get default setting: Size Title Size.
*
* @return array
*/
public static function get_site_title_size_default() {
return array(
'sm' => 2,
'md' => 2,
'lg' => 2,
);
}
/**
* Get default setting: Tagline Size.
*
* @return array
*/
public static function get_tagline_size_default() {
return array(
'sm' => 2,
'md' => 2,
'lg' => 2,
);
}
/**
* Get setting label: Logo Size.
*
* @return array
*/
public static function get_logo_size_label() {
return array(
'label' => array(
'sm' => esc_html__( 'Logo Size (Small-Screen Devices)', 'pressbook' ),
'md' => esc_html__( 'Logo Size (Medium-Screen Devices)', 'pressbook' ),
'lg' => esc_html__( 'Logo Size (Large-Screen Devices)', 'pressbook' ),
),
'desc' => array(
'sm' => esc_html_x( 'Default: Size 1', 'Default: Logo Size (Small-Screen Devices)', 'pressbook' ),
'md' => esc_html_x( 'Default: Size 1', 'Default: Logo Size (Medium-Screen Devices)', 'pressbook' ),
'lg' => esc_html_x( 'Default: Size 1', 'Default: Logo Size (Large-Screen Devices)', 'pressbook' ),
),
);
}
/**
* Get setting label: Site Title Size.
*
* @return array
*/
public static function get_site_title_size_label() {
return array(
'label' => array(
'sm' => esc_html__( 'Site Title Size (Small-Screen Devices)', 'pressbook' ),
'md' => esc_html__( 'Site Title Size (Medium-Screen Devices)', 'pressbook' ),
'lg' => esc_html__( 'Site Title Size (Large-Screen Devices)', 'pressbook' ),
),
'desc' => array(
'sm' => esc_html_x( 'Default: Size 2', 'Default: Site Title Size (Small-Screen Devices)', 'pressbook' ),
'md' => esc_html_x( 'Default: Size 2', 'Default: Site Title Size (Medium-Screen Devices)', 'pressbook' ),
'lg' => esc_html_x( 'Default: Size 2', 'Default: Site Title Size (Large-Screen Devices)', 'pressbook' ),
),
);
}
/**
* Get setting label: Tagline Size.
*
* @return array
*/
public static function get_tagline_size_label() {
return array(
'label' => array(
'sm' => esc_html__( 'Tagline Size (Small-Screen Devices)', 'pressbook' ),
'md' => esc_html__( 'Tagline Size (Medium-Screen Devices)', 'pressbook' ),
'lg' => esc_html__( 'Tagline Size (Large-Screen Devices)', 'pressbook' ),
),
'desc' => array(
'sm' => esc_html_x( 'Default: Size 2', 'Default: Tagline Size (Small-Screen Devices)', 'pressbook' ),
'md' => esc_html_x( 'Default: Size 2', 'Default: Tagline Size (Medium-Screen Devices)', 'pressbook' ),
'lg' => esc_html_x( 'Default: Size 2', 'Default: Tagline Size (Large-Screen Devices)', 'pressbook' ),
),
);
}
/**
* Selective Refresh: Size.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
* @param string $name Setting name.
* @param string $size Screen size.
*/
public function selective_refresh_size( $wp_customize, $name, $size ) {
$wp_customize->selective_refresh->add_partial(
( 'set_' . $name . '_size[' . $size . ']' ),
array(
'selector' => '.site-branding',
'container_inclusive' => true,
'render_callback' => array( $this, 'render_site_branding' ),
)
);
}
/**
* Render site branding for selective refresh.
*
* @return void
*/
public function render_site_branding() {
get_template_part( 'template-parts/header/site-branding' );
}
/**
* Get available sizes.
*
* @return array.
*/
public function sizes() {
return array(
'1' => esc_html__( 'Size 1', 'pressbook' ),
'2' => esc_html__( 'Size 2', 'pressbook' ),
'3' => esc_html__( 'Size 3', 'pressbook' ),
'4' => esc_html__( 'Size 4', 'pressbook' ),
'5' => esc_html__( 'Size 5', 'pressbook' ),
);
}
/**
* Binds JS handlers to make theme customizer preview reload changes asynchronously.
*/
public function customize_preview_scripts() {
wp_enqueue_script( 'pressbook-customizer', get_template_directory_uri() . '/js/customizer.js', array( 'customize-preview', 'jquery' ), PRESSBOOK_VERSION, true );
wp_localize_script(
'pressbook-customizer',
'pressbook',
array(
'styles' => CSSRules::output_array(),
'handle_id' => apply_filters( 'pressbook_inline_style_handle_id', 'pressbook-style-inline-css' ),
)
);
}
/**
* Get site logo title class.
*
* @return string
*/
public static function logo_title_class() {
$logo_title_classs = 'site-logo-title';
if ( self::get_hide_site_title() && self::get_hide_site_tagline() ) {
$logo_title_classs .= ' site-logo-only';
}
$top_banner = TopBanner::get_top_banner();
if ( '' !== wp_get_attachment_image( $top_banner['image'] ) ) {
if ( ! $top_banner['hide_sm'] ) {
$logo_title_classs .= ' has-banner-next-sm';
}
if ( ! $top_banner['hide_md'] ) {
$logo_title_classs .= ' has-banner-next-md';
}
$logo_title_classs .= ' has-banner-next-lg';
}
$logo = self::get_size( 'logo' );
foreach ( self::SETTING_SIZES as $size ) {
$logo_title_classs .= ( ' logo--' . $size . '-size-' . $logo[ $size ] );
}
return apply_filters( 'pressbook_site_logo_title_classs', $logo_title_classs );
}
/**
* Get site title class.
*
* @return string
*/
public static function title_class() {
$title_class = 'site-title';
if ( self::get_hide_site_title() ) {
$title_class .= ' hide-clip';
}
$site_title = self::get_size( 'site_title' );
foreach ( self::SETTING_SIZES as $size ) {
$title_class .= ( ' site-title--' . $size . '-size-' . $site_title[ $size ] );
}
return apply_filters( 'pressbook_site_title_class', $title_class );
}
/**
* Get site tagline class.
*
* @return string
*/
public static function tagline_class() {
$tagline_class = 'site-tagline';
if ( self::get_hide_site_tagline() ) {
$tagline_class .= ' hide-clip';
}
$site_tagline = self::get_size( 'tagline' );
foreach ( self::SETTING_SIZES as $size ) {
$tagline_class .= ( ' tagline--' . $size . '-size-' . $site_tagline[ $size ] );
}
return apply_filters( 'pressbook_site_tagline_class', $tagline_class );
}
}

View File

@ -0,0 +1,473 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer top banner options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Top banner options service class
*/
class TopBanner extends Options {
const MAIN_SETTING_KEYS = array( 'image', 'link_url', 'link_title', 'link_rel', 'link_new_tab', 'shadow' );
const DEVICE_SETTING_KEYS = array( 'hide_sm', 'hide_md' );
/**
* Add top banner options for theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_top_banner( $wp_customize );
$this->set_top_banner_image( $wp_customize );
$this->set_top_banner_link_url( $wp_customize );
$this->set_top_banner_link_title( $wp_customize );
$this->set_top_banner_link_rel( $wp_customize );
$this->set_top_banner_link_new_tab( $wp_customize );
$this->set_top_banner_shadow( $wp_customize );
$this->set_top_banner_max_height( $wp_customize );
$this->set_top_banner_hide_sm( $wp_customize );
$this->set_top_banner_hide_md( $wp_customize );
$this->selective_refresh_top_banner_main_keys( $wp_customize );
$this->selective_refresh_top_banner_device_keys( $wp_customize );
$this->set_top_banner_block( $wp_customize );
}
/**
* Section: Top Banner Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_top_banner( $wp_customize ) {
$wp_customize->add_section(
'sec_top_banner',
array(
'title' => esc_html__( 'Top Banner', 'pressbook' ),
'description' => esc_html__( 'You can customize the top banner options in here.', 'pressbook' ),
'priority' => 152,
)
);
}
/**
* Add setting: Top Banner Image.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_image( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner[image]',
array(
'default' => self::get_top_banner_default( 'image' ),
'transport' => 'postMessage',
'sanitize_callback' => 'absint',
)
);
$wp_customize->add_control(
new \WP_Customize_Cropped_Image_Control(
$wp_customize,
'set_top_banner[image]',
array(
'section' => 'sec_top_banner',
'label' => esc_html__( 'Top Banner Image', 'pressbook' ),
'description' => esc_html__( 'Select the top banner image. The theme works best with an image size of 728 x 90 pixels. ', 'pressbook' ),
'flex_width' => true,
'flex_height' => true,
'width' => 728,
'height' => 90,
)
)
);
}
/**
* Add setting: Top Banner Link - URL.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_link_url( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner[link_url]',
array(
'default' => self::get_top_banner_default( 'link_url' ),
'transport' => 'postMessage',
'sanitize_callback' => 'esc_url_raw',
)
);
$wp_customize->add_control(
'set_top_banner[link_url]',
array(
'section' => 'sec_top_banner',
'type' => 'url',
'label' => esc_html__( 'Top Banner Link - URL', 'pressbook' ),
'description' => esc_html__( 'Enter the URL for the banner link.', 'pressbook' ),
)
);
}
/**
* Add setting: Top Banner Link - Title.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_link_title( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner[link_title]',
array(
'default' => self::get_top_banner_default( 'link_title' ),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_text_field',
)
);
$wp_customize->add_control(
'set_top_banner[link_title]',
array(
'section' => 'sec_top_banner',
'type' => 'text',
'label' => esc_html__( 'Top Banner Link - Title', 'pressbook' ),
'description' => esc_html__( 'Enter the "title" attribute for the banner link.', 'pressbook' ),
)
);
}
/**
* Add setting: Top Banner Link - Rel.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_link_rel( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner[link_rel]',
array(
'default' => self::get_top_banner_default( 'link_rel' ),
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_text_field',
)
);
$wp_customize->add_control(
'set_top_banner[link_rel]',
array(
'section' => 'sec_top_banner',
'type' => 'text',
'label' => esc_html__( 'Top Banner Link - Rel', 'pressbook' ),
'description' => esc_html__( 'Enter the "rel" attribute for the banner link.', 'pressbook' ),
)
);
}
/**
* Add setting: Top Banner Link - Open in New Tab.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_link_new_tab( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner[link_new_tab]',
array(
'default' => self::get_top_banner_default( 'link_new_tab' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_top_banner[link_new_tab]',
array(
'section' => 'sec_top_banner',
'type' => 'checkbox',
'label' => esc_html__( 'Top Banner Link - Open in New Tab', 'pressbook' ),
)
);
}
/**
* Add setting: Top Banner Shadow Effect.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_shadow( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner[shadow]',
array(
'default' => self::get_top_banner_default( 'shadow' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_top_banner[shadow]',
array(
'section' => 'sec_top_banner',
'type' => 'checkbox',
'label' => esc_html__( 'Top Banner Shadow Effect', 'pressbook' ),
)
);
}
/**
* Add setting: Top Banner Maximum Height.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_max_height( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[top_banner_max_height]',
array(
'default' => CSSRules::default_styles( 'top_banner_max_height' ),
'transport' => 'postMessage',
'sanitize_callback' => 'absint',
)
);
$wp_customize->add_control(
'set_styles[top_banner_max_height]',
array(
'section' => 'sec_top_banner',
'type' => 'number',
'label' => esc_html__( 'Top Banner Maximum Height', 'pressbook' ),
'description' => esc_html__( 'Set the maximum height allowed for the top banner image in pixels. Default: 150', 'pressbook' ),
)
);
}
/**
* Add setting: Hide in Small-Screen Devices.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_hide_sm( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner[hide_sm]',
array(
'default' => self::get_top_banner_default( 'hide_sm' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_top_banner[hide_sm]',
array(
'section' => 'sec_top_banner',
'type' => 'checkbox',
'label' => esc_html__( 'Hide in Small-Screen Devices', 'pressbook' ),
)
);
}
/**
* Add setting: Hide in Medium-Screen Devices.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_hide_md( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner[hide_md]',
array(
'default' => self::get_top_banner_default( 'hide_md' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_checkbox' ),
)
);
$wp_customize->add_control(
'set_top_banner[hide_md]',
array(
'section' => 'sec_top_banner',
'type' => 'checkbox',
'label' => esc_html__( 'Hide in Medium-Screen Devices', 'pressbook' ),
)
);
}
/**
* Get setting: Top Banner.
*
* @return array
*/
public static function get_top_banner() {
return wp_parse_args(
get_theme_mod( 'set_top_banner', array() ),
self::get_top_banner_default()
);
}
/**
* Get default setting: Top Banner.
*
* @param string $key Setting key.
* @return mixed|array
*/
public static function get_top_banner_default( $key = '' ) {
$default = apply_filters(
'pressbook_default_top_banner',
array(
'image' => '',
'link_url' => '#',
'link_title' => '',
'link_rel' => '',
'link_new_tab' => true,
'shadow' => false,
'hide_sm' => true,
'hide_md' => false,
)
);
if ( array_key_exists( $key, $default ) ) {
return $default[ $key ];
}
return $default;
}
/**
* Selective Refresh: Top Banner Main Keys.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function selective_refresh_top_banner_main_keys( $wp_customize ) {
foreach ( self::MAIN_SETTING_KEYS as $key ) {
$wp_customize->selective_refresh->add_partial(
( 'set_top_banner[' . $key . ']' ),
array(
'selector' => '.top-banner',
'container_inclusive' => true,
'render_callback' => function() {
get_template_part( 'template-parts/header/top-banner' );
},
)
);
}
}
/**
* Selective Refresh: Top Banner Device Keys.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function selective_refresh_top_banner_device_keys( $wp_customize ) {
foreach ( self::DEVICE_SETTING_KEYS as $key ) {
$wp_customize->selective_refresh->add_partial(
( 'set_top_banner[' . $key . ']' ),
array(
'selector' => '.site-branding',
'container_inclusive' => true,
'render_callback' => function() {
get_template_part( 'template-parts/header/site-branding' );
},
)
);
}
}
/**
* Get top banner class.
*
* @param array $top_banner Top banner settings.
* @return string
*/
public static function top_banner_class( $top_banner ) {
$top_banner_class = 'top-banner';
if ( $top_banner['shadow'] ) {
$top_banner_class .= ' top-banner-shadow';
}
if ( $top_banner['hide_sm'] ) {
$top_banner_class .= ' top-banner-hide-sm';
}
if ( $top_banner['hide_md'] ) {
$top_banner_class .= ' top-banner-hide-md';
}
return apply_filters( 'pressbook_top_banner_class', $top_banner_class, $top_banner );
}
/**
* Add setting: Top Banner Block Section.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_banner_block( $wp_customize ) {
$wp_customize->add_setting(
'set_top_banner_block',
array(
'type' => 'theme_mod',
'default' => self::get_top_banner_block( true ),
'transport' => 'refresh',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_block_post' ),
)
);
$wp_customize->add_control(
'set_top_banner_block',
array(
'section' => 'sec_top_banner',
'type' => 'select',
'choices' => $this->pattern_blocks_choices(),
'label' => esc_html__( 'Top Banner Block Section', 'pressbook' ),
'description' => wp_kses(
sprintf(
/* translators: %s: URL to the pattern-blocks admin page. */
__( 'You can use this to replace top banner image and use any custom block (For example: "Custom HTML block"). This is the content of the block section. You can create or edit the block section in the <a href="%s" target="_blank">Pattern Blocks Manager (opens in a new window)</a>.<br>After creating the pattern block, you may need to refresh this customizer page and then select the newly created block.<br>The selected block content will appear on the block section, replacing the top banner image and overriding its related options.', 'pressbook' ),
esc_url( admin_url( 'edit.php?post_type=wp_block' ) )
),
array(
'a' => array(
'href' => array(),
'target' => array(),
),
'br' => array(),
)
),
)
);
}
/**
* Get setting: Top Banner Block Section.
*
* @param bool $get_default Get default.
* @return string
*/
public static function get_top_banner_block( $get_default = false ) {
$default = apply_filters( 'pressbook_top_banner_block_default', '' );
if ( $get_default ) {
return $default;
}
return get_theme_mod( 'set_top_banner_block', $default );
}
/**
* Get an array of pattern-blocks formatted as [ ID => Title ].
*
* @return array
*/
public function pattern_blocks_choices() {
$pattern_blocks = get_posts(
array(
'post_type' => 'wp_block',
'numberposts' => 100,
)
);
$pattern_blocks_choices = array( 0 => esc_html__( 'Select a block', 'pressbook' ) );
foreach ( $pattern_blocks as $block ) {
$pattern_blocks_choices[ $block->ID ] = $block->post_title;
}
return $pattern_blocks_choices;
}
}

View File

@ -0,0 +1,104 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Customizer top navbar options service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\CSSRules;
/**
* Top navbar options service class.
*/
class TopNavbar extends Options {
/**
* Add top navbar options for theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_top_navbar( $wp_customize );
$this->set_top_navbar_bg_color_1( $wp_customize );
$this->set_top_navbar_bg_color_2( $wp_customize );
}
/**
* Section: Top Navbar Options.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_top_navbar( $wp_customize ) {
$wp_customize->add_section(
'sec_top_navbar',
array(
'title' => esc_html__( 'Top Navbar', 'pressbook' ),
'description' => esc_html__( 'You can customize the top navbar options in here.', 'pressbook' ),
'priority' => 151,
)
);
}
/**
* Add setting: Top Navbar Background Color 1.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_navbar_bg_color_1( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[top_navbar_bg_color_1]',
array(
'default' => CSSRules::default_styles( 'top_navbar_bg_color_1' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_alpha_color' ),
)
);
$wp_customize->add_control(
new AlphaColorControl(
$wp_customize,
'set_styles[top_navbar_bg_color_1]',
array(
'section' => 'sec_top_navbar',
'label' => esc_html__( 'Top Navbar Gradient Background 1', 'pressbook' ),
'settings' => 'set_styles[top_navbar_bg_color_1]',
'palette' => true,
'show_opacity' => true,
)
)
);
}
/**
* Add setting: Top Navbar Background Color 1.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function set_top_navbar_bg_color_2( $wp_customize ) {
$wp_customize->add_setting(
'set_styles[top_navbar_bg_color_2]',
array(
'default' => CSSRules::default_styles( 'top_navbar_bg_color_2' ),
'transport' => 'postMessage',
'sanitize_callback' => array( Sanitizer::class, 'sanitize_alpha_color' ),
)
);
$wp_customize->add_control(
new AlphaColorControl(
$wp_customize,
'set_styles[top_navbar_bg_color_2]',
array(
'section' => 'sec_top_navbar',
'label' => esc_html__( 'Top Navbar Gradient Background 2', 'pressbook' ),
'settings' => 'set_styles[top_navbar_bg_color_2]',
'palette' => true,
'show_opacity' => true,
)
)
);
}
}

229
inc/core/Options/Upsell.php Normal file
View File

@ -0,0 +1,229 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Upsell customizer service.
*
* @package PressBook
*/
namespace PressBook\Options;
use PressBook\Options;
use PressBook\Helpers;
/**
* Upsell service class.
*/
class Upsell extends Options {
/**
* Add upsell in the theme customizer.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function customize_register( $wp_customize ) {
$this->sec_upsell( $wp_customize );
}
/**
* Section: Upsell.
*
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
*/
public function sec_upsell( $wp_customize ) {
if ( method_exists( $wp_customize, 'register_section_type' ) ) {
$wp_customize->register_section_type( \PressBook_Upsell_Section::class );
}
if ( method_exists( $wp_customize, 'register_control_type' ) ) {
$wp_customize->register_control_type( \PressBook_Upsell_Control::class );
}
$wp_customize->add_section(
new \PressBook_Upsell_Section(
$wp_customize,
'pressbook_premium',
array(
'title' => esc_html__( 'Premium Available', 'pressbook' ),
'button_text' => esc_html__( 'Get Premium', 'pressbook' ),
'button_url' => esc_url( Helpers::get_upsell_buy_url() ),
'priority' => 1,
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'addon_colors',
array(
'section' => 'colors',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'More color options like button text color, link color, theme accent color, RGBA colors, fonts selector, and many more options are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_fonts',
array(
'section' => 'sec_fonts',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'Advanced typography settings: font-family, font-size, body font-weight, line-height, over 50+ Google fonts, and custom Google font loader are available to select for the headings and body text in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_top_navbar',
array(
'section' => 'sec_top_navbar',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'Multiple eye-catching block patterns, custom gradient color options, header blocks, footer blocks, and many more options are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) . '#description' ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_top_banner',
array(
'section' => 'sec_top_banner',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'Multiple eye-catching block patterns, custom gradient color scheme, header blocks, footer blocks are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) . '#description' ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_primary_navbar',
array(
'section' => 'sec_primary_navbar',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'More color options for primary navigation are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) . '#description' ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_header_block',
array(
'section' => 'sec_header_block',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'More header blocks and footer blocks are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_footer_block',
array(
'section' => 'sec_footer_block',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'More footer blocks and header blocks are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_content',
array(
'section' => 'sec_content',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'Content background, text color, button color, link color and many more options are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_sidebar',
array(
'section' => 'sec_sidebar',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'Sidebar background, text color, post meta color, and many more options are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_blog',
array(
'section' => 'sec_blog',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'More blog options and advanced theme options are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
$wp_customize->add_control(
new \PressBook_Upsell_Control(
$wp_customize,
'sec_footer',
array(
'section' => 'sec_footer',
'type' => 'pressbook-addon',
'label' => esc_html__( 'Learn More', 'pressbook' ),
'description' => esc_html__( 'More footer and color options are available in our premium version.', 'pressbook' ),
'url' => ( esc_url( Helpers::get_upsell_detail_url() ) ),
'priority' => 999,
'settings' => ( isset( $wp_customize->selective_refresh ) ) ? array() : 'blogname',
)
)
);
}
}

235
inc/core/PageSettings.php Normal file
View File

@ -0,0 +1,235 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Design related page settings.
*
* @package PressBook
*/
namespace PressBook;
/**
* Register design related page settings.
*/
class PageSettings implements Serviceable {
const META_KEY = 'pressbook_settings';
/**
* Register service features.
*/
public function register() {
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
add_action( 'save_post', array( $this, 'save_meta_boxes' ), 10, 2 );
}
/**
* Add meta boxes for design related page settings.
*/
public function add_meta_boxes() {
add_meta_box( 'pressbook-page-settings', esc_html__( 'PressBook Page Settings', 'pressbook' ), array( $this, 'metabox_html' ), array( 'page' ), 'side', 'default' );
}
/**
* Save metabox fields.
*
* @param int $post_id post id.
* @param WP_Post $post post object.
*/
public function save_meta_boxes( $post_id, $post ) {
$nonce_key = ( 'pressbook_settings_nonce_' . $post_id );
if ( ! array_key_exists( $nonce_key, $_POST ) ||
! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $nonce_key ] ) ), $nonce_key ) ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( ! in_array( $post->post_type, array( 'page' ), true ) ) {
return;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
return;
}
if ( wp_is_post_revision( $post ) ) {
return;
}
$hide_title = array_key_exists( 'pressbook_hide_title', $_POST ) ? (bool) $_POST['pressbook_hide_title'] : self::get_meta_default( 'hide_title' );
$no_t_margin = array_key_exists( 'pressbook_no_t_margin', $_POST ) ? (bool) $_POST['pressbook_no_t_margin'] : self::get_meta_default( 'no_t_margin' );
$no_b_margin = array_key_exists( 'pressbook_no_b_margin', $_POST ) ? (bool) $_POST['pressbook_no_b_margin'] : self::get_meta_default( 'no_b_margin' );
$no_t_padding = array_key_exists( 'pressbook_no_t_padding', $_POST ) ? (bool) $_POST['pressbook_no_t_padding'] : self::get_meta_default( 'no_t_padding' );
$no_b_padding = array_key_exists( 'pressbook_no_b_padding', $_POST ) ? (bool) $_POST['pressbook_no_b_padding'] : self::get_meta_default( 'no_b_padding' );
$no_x_padding = array_key_exists( 'pressbook_no_x_padding', $_POST ) ? (bool) $_POST['pressbook_no_x_padding'] : self::get_meta_default( 'no_x_padding' );
$transparent_bg = array_key_exists( 'pressbook_transparent_bg', $_POST ) ? (bool) $_POST['pressbook_transparent_bg'] : self::get_meta_default( 'transparent_bg' );
if ( metadata_exists( 'post', $post_id, self::META_KEY ) ||
// Add meta key only if any of the setting is not same as the default setting.
( ( self::get_meta_default( 'hide_title' ) !== $hide_title ) ||
( self::get_meta_default( 'no_t_margin' ) !== $no_t_margin ) ||
( self::get_meta_default( 'no_b_margin' ) !== $no_b_margin ) ||
( self::get_meta_default( 'no_t_padding' ) !== $no_t_padding ) ||
( self::get_meta_default( 'no_b_padding' ) !== $no_b_padding ) ||
( self::get_meta_default( 'no_x_padding' ) !== $no_x_padding ) ||
( self::get_meta_default( 'transparent_bg' ) !== $transparent_bg )
)
) {
update_post_meta(
$post_id,
self::META_KEY,
array(
'hide_title' => $hide_title,
'no_t_margin' => $no_t_margin,
'no_b_margin' => $no_b_margin,
'no_t_padding' => $no_t_padding,
'no_b_padding' => $no_b_padding,
'no_x_padding' => $no_x_padding,
'transparent_bg' => $transparent_bg,
)
);
}
}
/**
* Metabox HTML output.
*
* @param WP_Post $post post object.
*/
public function metabox_html( $post ) {
$settings = self::get_meta( $post->ID );
$nonce_key = ( 'pressbook_settings_nonce_' . $post->ID );
?>
<input type="hidden" name="<?php echo esc_attr( $nonce_key ); ?>" value="<?php echo esc_attr( wp_create_nonce( $nonce_key ) ); ?>">
<p class="pressbook-metabox-field">
<input <?php checked( ( (bool) $settings['hide_title'] ), true, true ); ?> id="pressbook_hide_title" type="checkbox" name="pressbook_hide_title" value="1">
<label for="pressbook_hide_title"><?php esc_html_e( 'Disable Header Title', 'pressbook' ); ?></label>
</p>
<p class="pressbook-metabox-field">
<input <?php checked( ( (bool) $settings['no_t_margin'] ), true, true ); ?> id="pressbook_no_t_margin" type="checkbox" name="pressbook_no_t_margin" value="1">
<label for="pressbook_no_t_margin"><?php esc_html_e( 'Remove Top Margin', 'pressbook' ); ?></label>
</p>
<p class="pressbook-metabox-field">
<input <?php checked( ( (bool) $settings['no_b_margin'] ), true, true ); ?> id="pressbook_no_b_margin" type="checkbox" name="pressbook_no_b_margin" value="1">
<label for="pressbook_no_b_margin"><?php esc_html_e( 'Remove Bottom Margin', 'pressbook' ); ?></label>
</p>
<p><?php esc_html_e( 'Below settings override customizer settings for page content layout (only if checked).', 'pressbook' ); ?></p>
<p class="pressbook-metabox-field">
<input <?php checked( ( (bool) $settings['no_t_padding'] ), true, true ); ?> id="pressbook_no_t_padding" type="checkbox" name="pressbook_no_t_padding" value="1">
<label for="pressbook_no_t_padding"><?php esc_html_e( 'Force Remove Top Padding', 'pressbook' ); ?></label>
</p>
<p class="pressbook-metabox-field">
<input <?php checked( ( (bool) $settings['no_b_padding'] ), true, true ); ?> id="pressbook_no_b_padding" type="checkbox" name="pressbook_no_b_padding" value="1">
<label for="pressbook_no_b_padding"><?php esc_html_e( 'Force Remove Bottom Padding', 'pressbook' ); ?></label>
</p>
<p class="pressbook-metabox-field">
<input <?php checked( ( (bool) $settings['no_x_padding'] ), true, true ); ?> id="pressbook_no_x_padding" type="checkbox" name="pressbook_no_x_padding" value="1">
<label for="pressbook_no_x_padding"><?php esc_html_e( 'Force Remove Horizontal Padding', 'pressbook' ); ?></label>
</p>
<p class="pressbook-metabox-field">
<input <?php checked( ( (bool) $settings['transparent_bg'] ), true, true ); ?> id="pressbook_transparent_bg" type="checkbox" name="pressbook_transparent_bg" value="1">
<label for="pressbook_transparent_bg"><?php esc_html_e( 'Force Transparent Background', 'pressbook' ); ?></label>
</p>
<?php
}
/**
* Get meta settings.
*
* @param int $id Post ID.
* @return array
*/
public static function get_meta( $id ) {
return wp_parse_args(
( is_array( get_post_meta( $id, self::META_KEY, true ) ) ? get_post_meta( $id, self::META_KEY, true ) : array() ),
self::get_meta_default()
);
}
/**
* Get default meta settings.
*
* @param string $key Setting key.
* @return mixed|array
*/
public static function get_meta_default( $key = '' ) {
$default = apply_filters(
'pressbook_settings',
array(
'hide_title' => false,
'no_t_margin' => false,
'no_b_margin' => false,
'no_t_padding' => false,
'no_b_padding' => false,
'no_x_padding' => false,
'transparent_bg' => false,
)
);
if ( array_key_exists( $key, $default ) ) {
return $default[ $key ];
}
return $default;
}
/**
* Get meta settings for template parts.
*
* @param int $id Post ID.
* @return array
*/
public static function get_meta_config( $id ) {
$meta = self::get_meta( $id );
if ( $meta['no_t_margin'] ) {
$wrapper_class = ' no-t-margin';
} else {
$wrapper_class = '';
}
$site_main_class = '';
if ( $meta['no_b_margin'] ) {
$site_main_class .= ' no-b-margin';
}
if ( $meta['no_t_padding'] ) {
$site_main_class .= ' no-t-padding';
}
if ( $meta['no_b_padding'] ) {
$site_main_class .= ' no-b-padding';
}
if ( $meta['no_x_padding'] ) {
$site_main_class .= ' no-x-padding';
}
if ( $meta['transparent_bg'] ) {
$site_main_class .= ' u-transparent-bg';
}
return array(
'page_content' => ( $meta['hide_title'] ? 'page-no-title' : 'page' ),
'wrapper_class' => $wrapper_class,
'site_main_class' => $site_main_class,
);
}
}

103
inc/core/Scripts.php Normal file
View File

@ -0,0 +1,103 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Scripts service.
*
* @package PressBook
*/
namespace PressBook;
use PressBook\CSSRules;
use PressBook\Options\Sidebar;
/**
* Enqueue theme styles and scripts.
*/
class Scripts implements Serviceable {
/**
* Register service features.
*/
public function register() {
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
}
/**
* Enqueue styles and scripts.
*/
public function enqueue_scripts() {
// Enqueue fonts.
wp_enqueue_style( 'pressbook-fonts', static::fonts_url(), array(), null ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
// Theme stylesheet.
wp_enqueue_style( 'pressbook-style', get_template_directory_uri() . '/style.min.css', array(), PRESSBOOK_VERSION );
wp_style_add_data( 'pressbook-style', 'rtl', 'replace' );
// Add output of customizer settings as inline style.
wp_add_inline_style( 'pressbook-style', CSSRules::output() );
// Theme script.
wp_enqueue_script( 'pressbook-script', get_template_directory_uri() . '/js/script.min.js', array(), PRESSBOOK_VERSION, true );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
if ( Sidebar::get_sticky_sidebar() ) {
// Resize observer polyfill.
wp_enqueue_script( 'resize-observer-polyfill', get_template_directory_uri() . '/js/ResizeObserver.min.js', array(), true, true );
// Sticky sidebar.
wp_enqueue_script( 'sticky-sidebar', get_template_directory_uri() . '/js/sticky-sidebar.min.js', array(), true, true );
$pressbook_sticky_bp = Sidebar::get_sticky_breakpoint();
wp_add_inline_script(
'sticky-sidebar',
'try{new StickySidebar(".site-content > .pb-content-sidebar > .c-sidebar",{topSpacing:100,bottomSpacing:0,containerSelector:".site-content > .pb-content-sidebar",minWidth:' . esc_attr( $pressbook_sticky_bp ) . '});new StickySidebar(".site-content > .pb-content-sidebar > .c-sidebar-right",{topSpacing:100,bottomSpacing:0,containerSelector:".site-content > .pb-content-sidebar",minWidth:' . esc_attr( $pressbook_sticky_bp ) . '});}catch(e){}'
);
}
}
/**
* Get fonts URL.
*/
public static function fonts_url() {
$fonts_url = '';
$font_families = array();
$query_params = array();
/* translators: If there are characters in your language that are not supported by Inter, translate this to 'off'. Do not translate into your own language. */
$inter = _x( 'on', 'Inter font: on or off', 'pressbook' );
if ( 'off' !== $inter ) {
array_push( $font_families, 'Inter:wght@400;600' );
}
/* translators: If there are characters in your language that are not supported by Lato, translate this to 'off'. Do not translate into your own language. */
$lato = _x( 'on', 'Lato font: on or off', 'pressbook' );
if ( 'off' !== $lato ) {
array_push( $font_families, 'Lato:ital,wght@0,400;0,700;1,400;1,700' );
}
if ( count( $font_families ) > 0 ) {
foreach ( $font_families as $font_family ) {
array_push( $query_params, ( 'family=' . $font_family ) );
}
array_push( $query_params, 'display=swap' );
$fonts_url = ( 'https://fonts.googleapis.com/css2?' . implode( '&', $query_params ) );
}
$fonts_url = apply_filters( 'pressbook_fonts_url', $fonts_url );
$fonts_url = esc_url_raw( $fonts_url );
if ( function_exists( 'wptt_get_webfont_url' ) ) {
return wptt_get_webfont_url( $fonts_url );
}
return $fonts_url;
}
}

18
inc/core/Serviceable.php Normal file
View File

@ -0,0 +1,18 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Service interface contract.
*
* @package PressBook
*/
namespace PressBook;
/**
* Interface for service instance.
*/
interface Serviceable {
/**
* Register a service.
*/
public function register();
}

117
inc/core/Setup.php Normal file
View File

@ -0,0 +1,117 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Theme setup service.
*
* @package PressBook
*/
namespace PressBook;
/**
* Register theme setup hook.
*/
class Setup implements Serviceable {
const DEFAULT_BACKGROUND = 'ededed';
/**
* Register service features.
*/
public function register() {
add_action( 'after_setup_theme', array( $this, 'set_content_width' ), 0 );
add_action( 'after_setup_theme', array( $this, 'register_theme_features' ) );
}
/**
* Set the content width in pixels, based on the theme's design and stylesheet.
*
* Priority 0 to make it available to lower priority callbacks.
*
* @global int $content_width
*/
public function set_content_width() {
$GLOBALS['content_width'] = apply_filters( 'pressbook_content_width', 650 );
}
/**
* Register theme features.
*/
public function register_theme_features() {
/*
* Make theme available for translation.
* Translations can be filed in the /languages/ directory.
* If you're building a theme based on PressBook, use a find and replace
* to change 'pressbook' to the name of your theme in all the template files.
*/
load_theme_textdomain( 'pressbook', get_template_directory() . '/languages' );
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
/*
* Let WordPress manage the document title.
* By adding theme support, we declare that this theme does not use a
* hard-coded <title> tag in the document head, and expect WordPress to
* provide it for us.
*/
add_theme_support( 'title-tag' );
/*
* Enable support for Post Thumbnails on posts and pages.
*
* @link https://developer.wordpress.org/themes/functionality/featured-images-post-thumbnails/
*/
add_theme_support( 'post-thumbnails' );
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5',
apply_filters(
'pressbook_html5_args',
array(
'navigation-widgets',
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
'style',
'script',
)
)
);
// Set up the WordPress core custom background feature.
add_theme_support(
'custom-background',
apply_filters(
'pressbook_custom_background_args',
array(
'default-color' => self::DEFAULT_BACKGROUND,
'default-image' => '',
)
)
);
// Add support for block styles.
add_theme_support( 'wp-block-styles' );
// Add support for wide alignment.
add_theme_support( 'align-wide' );
// Add support for responsive embedded content.
add_theme_support( 'responsive-embeds' );
// Add theme support for selective refresh for widgets.
add_theme_support( 'customize-selective-refresh-widgets' );
// Add support for custom line height controls.
add_theme_support( 'custom-line-height' );
// Add theme support for padding controls.
add_theme_support( 'custom-spacing' );
}
}

167
inc/core/TemplateTags.php Normal file
View File

@ -0,0 +1,167 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Template tags.
*
* @package PressBook
*/
namespace PressBook;
use PressBook\Options\Blog;
/**
* Theme template tags.
*/
class TemplateTags {
/**
* Displays an optional post thumbnail.
*
* Wraps the post thumbnail in an anchor element on index views, or a div
* element when on single views.
*/
public static function post_thumbnail() {
if ( post_password_required() || is_attachment() || ! has_post_thumbnail() ) {
return;
}
if ( is_singular() ) {
?>
<div class="post-thumbnail">
<?php the_post_thumbnail(); ?>
</div><!-- .post-thumbnail -->
<?php
} else {
?>
<a class="post-thumbnail" href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1">
<?php
the_post_thumbnail(
'post-thumbnail',
array(
'alt' => the_title_attribute(
array(
'echo' => false,
)
),
)
);
?>
</a><!-- .post-thumbnail -->
<?php
}
}
/**
* Prints HTML with meta information for the current post-date/time.
*/
public static function posted_on() {
?>
<span class="posted-on">
<?php IconsHelper::the_theme_svg( 'calendar' ); ?>
<a href="<?php the_permalink(); ?>" rel="bookmark">
<?php
printf(
wp_kses(
/* translators: %s: post date */
_x( '<span class="screen-reader-text">Posted on </span>%s', 'post date', 'pressbook' ),
array(
'span' => array(
'class' => array(),
),
)
),
sprintf(
( ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) ? '<time class="entry-date published" datetime="%1$s">%2$s</time><time class="updated" datetime="%3$s">%4$s</time>' : '<time class="entry-date published updated" datetime="%1$s">%2$s</time>' ),
esc_attr( get_the_date( DATE_W3C ) ),
esc_html( get_the_date() ),
esc_attr( get_the_modified_date( DATE_W3C ) ),
esc_html( get_the_modified_date() )
)
)
?>
</a>
</span><!-- .posted-on -->
<?php
}
/**
* Prints HTML with meta information for the current author.
*/
public static function posted_by() {
?>
<span class="posted-by byline">
<?php IconsHelper::the_theme_svg( 'user' ); ?>
<a href="<?php echo esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ); ?>">
<?php
printf(
wp_kses(
/* translators: %s: post author */
_x( '<span class="screen-reader-text">By </span>%s', 'post author', 'pressbook' ),
array(
'span' => array(
'class' => array(),
),
)
),
esc_html( get_the_author() )
)
?>
</a>
</span><!-- .posted-by -->
<?php
}
/**
* Prints HTML with meta information for comments.
*/
public static function comments() {
if ( ! post_password_required() && ( comments_open() || get_comments_number() ) ) {
?>
<span class="comments-link">
<?php
IconsHelper::the_theme_svg( 'comment' );
comments_popup_link();
?>
</span><!-- .comments-link -->
<?php
}
}
/**
* Prints HTML for the edit post link.
*/
public static function edit_post_link() {
edit_post_link( null, '<span class="post-edit-link-wrap">&raquo; ', '</span>' );
}
/**
* Prints HTML with meta information for the categories.
*/
public static function post_categories() {
if ( 'post' === get_post_type() && has_category() ) {
?>
<span class="<?php echo esc_attr( Blog::entry_meta_cat_class() ); ?>">
<?php
IconsHelper::the_theme_svg( 'category' );
the_category( ', ' );
?>
</span><!-- .cat-links -->
<?php
}
}
/**
* Prints HTML with meta information for the tags.
*/
public static function post_tags() {
if ( 'post' === get_post_type() && has_tag() ) {
?>
<span class="<?php echo esc_attr( Blog::entry_meta_tag_class() ); ?>">
<?php
IconsHelper::the_theme_svg( 'tag' );
the_tags( ( '<span class="screen-reader-text">' . esc_html_x( 'Tags:', 'String to use before the tags for screen readers.', 'pressbook' ) . '</span>' ), ', ' );
?>
</span><!-- .tag-links -->
<?php
}
}
}

68
inc/core/Theme.php Normal file
View File

@ -0,0 +1,68 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Theme services.
*
* @package PressBook
*/
namespace PressBook;
/**
* Register and initialize theme services.
*/
class Theme {
/**
* Get theme services.
*/
public static function get_services() {
return apply_filters(
'pressbook_services',
array(
Setup::class,
Menu::class,
Widget::class,
Header::class,
Enhance::class,
Scripts::class,
IconsHelper::class,
Editor::class,
PageSettings::class,
WooCommerce::class,
Jetpack::class,
Options\SiteIdentity::class,
Options\Colors::class,
Options\Fonts::class,
Options\HeaderImage::class,
Options\TopNavbar::class,
Options\TopBanner::class,
Options\PrimaryNavbar::class,
Options\HeaderBlock::class,
Options\Content::class,
Options\Sidebar::class,
Options\Blog::class,
Options\General::class,
Options\FooterBlock::class,
Options\Footer::class,
Options\Upsell::class,
)
);
}
/**
* Initialize theme services.
*/
public static function init() {
foreach ( self::get_services() as $class ) {
self::register_service( new $class() );
}
}
/**
* Register a theme service.
*
* @param Serviceable $service Service instance.
*/
private static function register_service( Serviceable $service ) {
$service->register();
}
}

144
inc/core/Widget.php Normal file
View File

@ -0,0 +1,144 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* Widget service.
*
* @package PressBook
*/
namespace PressBook;
/**
* Register theme widget area.
*/
class Widget implements Serviceable {
const FOOTER_WIDGETS_COUNT = 4;
/**
* Register service features.
*/
public function register() {
add_action( 'widgets_init', array( $this, 'widgets_init' ) );
if ( is_admin() && isset( $GLOBALS['pagenow'] ) && in_array( $GLOBALS['pagenow'], array( 'widgets.php', 'nav-menus.php' ), true ) ) {
add_action( 'wp_print_styles', array( $this, 'print_styles' ) );
add_action( 'enqueue_block_assets', array( $this, 'enqueue_assets' ) );
add_editor_style( get_template_directory_uri() . '/inc/widgets-editor-style.css' );
}
}
/**
* Register widget area.
*/
public function widgets_init() {
register_sidebar(
array(
'name' => esc_html__( 'Left Sidebar', 'pressbook' ),
'id' => 'sidebar-2',
'description' => esc_html__( 'Add widgets here.', 'pressbook' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h3 class="widget-title">',
'after_title' => '</h3>',
)
);
register_sidebar(
array(
'name' => esc_html__( 'Right Sidebar', 'pressbook' ),
'id' => 'sidebar-1',
'description' => esc_html__( 'Add widgets here.', 'pressbook' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h3 class="widget-title">',
'after_title' => '</h3>',
)
);
for ( $i = 1; $i <= self::FOOTER_WIDGETS_COUNT; $i++ ) {
register_sidebar(
array(
/* translators: %s: footer widgets area number */
'name' => sprintf( esc_html__( 'Footer Widgets Area %s', 'pressbook' ), $i ),
'id' => 'footer-' . $i,
'description' => esc_html__( 'Add widgets here.', 'pressbook' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h3 class="widget-title">',
'after_title' => '</h3>',
)
);
}
}
/**
* Get total number of active footer widgets area.
* return int.
*/
public static function get_active_footer_widgets() {
$total_active = 0;
for ( $i = 1; $i <= self::FOOTER_WIDGETS_COUNT; $i++ ) {
if ( is_active_sidebar( 'footer-' . $i ) ) {
$total_active++;
}
}
return $total_active;
}
/**
* Remove theme inline style.
*/
public function print_styles() {
if ( wp_style_is( 'pressbook-style', 'enqueued' ) ) {
wp_style_add_data( 'pressbook-style', 'after', '' );
}
}
/**
* Enqueue styles and scripts.
*/
public function enqueue_assets() {
if ( $this->is_block_screen() ) {
wp_enqueue_style( 'pressbook-widgets-editor-legacy-style', get_template_directory_uri() . '/inc/widgets-editor-legacy.css', array(), PRESSBOOK_VERSION );
wp_style_add_data( 'pressbook-widgets-editor-legacy-style', 'rtl', 'replace' );
// Add output of customizer settings as inline style.
wp_add_inline_style( 'pressbook-widgets-editor-legacy-style', CSSRules::output_widgets_editor_legacy() );
}
}
/**
* Check if block editor screen.
*
* @return bool
*/
public function is_block_screen() {
if ( function_exists( '\get_current_screen' ) ) {
$current_screen = get_current_screen();
if ( $current_screen ) {
if ( \method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
return true;
}
}
}
return false;
}
/**
* Styles keys for the widgets editor legacy CSS output.
*
* @return array
*/
public static function legacy_styles_keys() {
return apply_filters(
'pressbook_default_widgets_editor_legacy_styles_keys',
array(
'button_bg_color_1',
'button_bg_color_2',
'button_font_wgt',
)
);
}
}

163
inc/core/WooCommerce.php Normal file
View File

@ -0,0 +1,163 @@
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
/**
* WooCommerce compatibility.
*
* @link https://woocommerce.com/
*
* @package PressBook
*/
namespace PressBook;
/**
* Setup WooCommerce for the theme.
*/
class WooCommerce implements Serviceable {
/**
* Register service features.
*/
public function register() {
if ( class_exists( '\WooCommerce' ) ) {
add_action( 'after_setup_theme', array( $this, 'woocommerce_setup' ) );
add_action( 'widgets_init', array( $this, 'widgets_init' ) );
add_action( 'wp', array( $this, 'woocommerce_modify' ) );
add_filter( 'body_class', array( $this, 'body_classes' ) );
}
}
/**
* WooCommerce setup function.
*
* @link https://docs.woocommerce.com/document/third-party-custom-theme-compatibility/
* @link https://github.com/woocommerce/woocommerce/wiki/Enabling-product-gallery-features-(zoom,-swipe,-lightbox)
* @link https://github.com/woocommerce/woocommerce/wiki/Declaring-WooCommerce-support-in-themes
*
* @return void
*/
public function woocommerce_setup() {
// Add support for WooCommerce.
add_theme_support(
'woocommerce',
array(
'product_grid' => array(
'default_rows' => 8,
'min_rows' => 5,
'max_rows' => 10,
'default_columns' => 4,
'min_columns' => 2,
'max_columns' => 4,
),
)
);
// Add support for WooCommerce features.
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
// Remove default WooCommerce wrappers.
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 );
remove_action( 'woocommerce_sidebar', 'woocommerce_get_sidebar', 10 );
}
/**
* Register shop widget area.
*/
public function widgets_init() {
register_sidebar(
array(
'name' => esc_html__( 'Shop Sidebar', 'pressbook' ),
'id' => 'sidebar-shop',
'description' => esc_html__( 'Add widgets here.', 'pressbook' ),
'before_widget' => '<section id="%1$s" class="widget %2$s">',
'after_widget' => '</section>',
'before_title' => '<h3 class="widget-title">',
'after_title' => '</h3>',
)
);
}
/**
* Modify WooCommerce templates.
*/
public function woocommerce_modify() {
add_action( 'woocommerce_before_main_content', array( $this, 'woocommerce_open_wrapper_columns' ), 7 );
add_action( 'woocommerce_before_main_content', array( $this, 'woocommerce_open_content_column' ), 9 );
add_action( 'woocommerce_after_main_content', array( $this, 'woocommerce_close_content_column' ), 7 );
if ( is_shop() || is_archive() ) {
// Output the shop sidebar.
add_action( 'woocommerce_after_main_content', 'woocommerce_get_sidebar', 9 );
}
add_action( 'woocommerce_after_main_content', array( $this, 'woocommerce_close_wrapper_columns' ), 11 );
}
/**
* Opening wrapper.
*/
public function woocommerce_open_wrapper_columns() {
?>
<div class="pb-content-sidebar u-wrapper">
<?php
}
/**
* Closing wrapper.
*/
public function woocommerce_close_wrapper_columns() {
?>
</div><!-- .pb-content-sidebar -->
<?php
}
/**
* Opening shop content.
*/
public function woocommerce_open_content_column() {
?>
<main id="primary" class="site-main">
<article id="post-<?php the_ID(); ?>" <?php post_class( 'pb-article pb-singular' ); ?>>
<div class="pb-content">
<div class="entry-content">
<?php
}
/**
* Closing shop content.
*/
public function woocommerce_close_content_column() {
?>
</div><!-- .entry-content -->
</div><!-- .pb-content -->
</article><!-- #post-<?php the_ID(); ?> -->
</main><!-- #primary -->
<?php
}
/**
* Adds custom classes to the array of body classes.
*
* @param array $classes Classes for the body element.
* @return array
*/
public function body_classes( $classes ) {
if ( is_active_sidebar( 'sidebar-shop' ) ) {
$classes[] = 'wc-sidebar';
} else {
$classes[] = 'wc-no-sidebar';
}
return $classes;
}
}

View File

@ -0,0 +1,42 @@
.control-section-pressbook-button .accordion-section-title:focus,
.control-section-pressbook-button .accordion-section-title:hover {
background-color: #fff;
}
.control-section-pressbook-button .accordion-section-title .button {
margin-top: -4px;
margin-left: 8px;
font-weight: 600;
background: linear-gradient(90deg,#4169e1 35%,#5e82ed 100%);
border-color: #4169e1;
color: #fff;
}
.control-section-pressbook-button .accordion-section-title .button:focus {
box-shadow: 0 0 0 1px #fff, 0 0 0 3px #4169e1;
}
.rtl .control-section-pressbook-button .accordion-section-title .button {
margin-left: 0;
margin-right: 8px;
}
li#accordion-section-pressbook_premium .accordion-section-title,
li#accordion-section-pressbook_premium.control-section-pressbook-button:hover .accordion-section-title {
color: #4169e1;
}
li#accordion-section-pressbook_premium.control-section-pressbook-button {
border-top: 1px solid #5e82ed;
border-bottom: 1px solid #5e82ed;
}
.customize-control-pressbook-addon {
margin-top: 10px;
}
.customize-control-pressbook-addon:before {
content: "";
height: 1px;
width: 44px;
display: block;
margin-bottom: 10px;
background: rgba(0,0,0,.1);
}
.customize-control-pressbook-addon .description {
margin-top: 8px;
margin-bottom: 8px;
}

View File

@ -0,0 +1,72 @@
<?php
/**
* Customize control upsell class.
*
* @package PressBook
*/
if ( class_exists( 'WP_Customize_Control' ) && ! class_exists( 'PressBook_Upsell_Control' ) ) {
/**
* Create in-section upsell control.
* Escape URL in the Customizer using esc_url().
*/
class PressBook_Upsell_Control extends WP_Customize_Control {
/**
* The type of customize control being rendered.
*
* @var string
*/
public $type = 'pressbook-addon';
/**
* Custom button URL to output.
*
* @var string
*/
public $url = '';
/**
* Description of control.
*
* @var string
*/
public $description = '';
/**
* Label of control.
*
* @var string
*/
public $label = '';
/**
* Load the CSS.
*/
public function enqueue() {
wp_enqueue_style( 'pressbook-customize-section-button', get_theme_file_uri( 'inc/customize-controls.css' ), array(), PRESSBOOK_VERSION );
}
/**
* Add custom parameters to pass to the JS via JSON.
*/
public function to_json() {
parent::to_json();
$this->json['url'] = esc_url( $this->url );
}
/**
* Outputs the template.
*
* @return void
*/
public function content_template() {
?>
<p class="description">{{{ data.description }}}</p>
<span class="get-addon">
<a href="{{{ data.url }}}" class="button button-primary" target="_blank">{{ data.label }}</a>
</span>
<?php
}
}
}

View File

@ -0,0 +1,94 @@
<?php
/**
* Customize section upsell button class.
*
* @package PressBook
*/
if ( class_exists( 'WP_Customize_Section' ) && ! class_exists( 'PressBook_Upsell_Section' ) ) {
/**
* Create upsell section.
*/
class PressBook_Upsell_Section extends WP_Customize_Section {
/**
* The type of customize section being rendered.
*
* @var string
*/
public $type = 'pressbook-button';
/**
* Custom button text to output.
*
* @var string
*/
public $button_text = '';
/**
* Custom button URL to output.
*
* @var string
*/
public $button_url = '';
/**
* Default priority of the section.
*
* @var string
*/
public $priority = 999;
/**
* Add custom parameters to pass to the JS via JSON.
*
* @return array
*/
public function json() {
$json = parent::json();
$theme = wp_get_theme();
$button_url = $this->button_url;
if ( ! $this->button_url && $theme->get( 'ThemeURI' ) ) {
// Fall back to the `Theme URI` defined in `style.css`.
$button_url = $theme->get( 'ThemeURI' );
} elseif ( ! $this->button_url && $theme->get( 'AuthorURI' ) ) {
// Fall back to the `Author URI` defined in `style.css`.
$button_url = $theme->get( 'AuthorURI' );
}
$json['button_text'] = $this->button_text ? esc_html( $this->button_text ) : $theme->get( 'Name' );
$json['button_url'] = esc_url( $button_url );
return $json;
}
/**
* Outputs the template.
*
* @return void
*/
protected function render_template() {
?>
<li id="accordion-section-{{ data.id }}" class="pressbook-upsell-accordion-section accordion-section control-section control-section-{{ data.type }} cannot-expand">
<h3 class="accordion-section-title">
{{ data.title }}
<# if ( data.button_text && data.button_url ) { #>
<a href="{{ data.button_url }}" class="button alignright" target="_blank">{{ data.button_text }}</a>
<# } #>
</h3>
</li>
<?php
}
}
}
/**
* Load the JS and CSS.
*/
function pressbook_customizer_controls_scripts() {
wp_enqueue_style( 'pressbook-customize-section-button', get_theme_file_uri( 'inc/customize-controls.css' ), array( 'customize-controls' ), PRESSBOOK_VERSION );
wp_enqueue_script( 'pressbook-customize-section-button', get_theme_file_uri( 'js/customize-controls.js' ), array( 'customize-controls' ), PRESSBOOK_VERSION, true );
}
add_action( 'customize_controls_enqueue_scripts', 'pressbook_customizer_controls_scripts' );

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,711 @@
<?php
/**
* Download webfonts locally.
*
* @package wptt/font-loader
* @license https://opensource.org/licenses/MIT
*/
if ( ! class_exists( 'WPTT_WebFont_Loader' ) ) {
/**
* Download webfonts locally.
*/
class WPTT_WebFont_Loader {
/**
* The font-format.
*
* Use "woff" or "woff2".
* This will change the user-agent user to make the request.
*
* @access protected
* @since 1.0.0
* @var string
*/
protected $font_format = 'woff2';
/**
* The remote URL.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $remote_url;
/**
* Base path.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $base_path;
/**
* Base URL.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $base_url;
/**
* Subfolder name.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $subfolder_name;
/**
* The fonts folder.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $fonts_folder;
/**
* The local stylesheet's path.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $local_stylesheet_path;
/**
* The local stylesheet's URL.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $local_stylesheet_url;
/**
* The remote CSS.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $remote_styles;
/**
* The final CSS.
*
* @access protected
* @since 1.1.0
* @var string
*/
protected $css;
/**
* Cleanup routine frequency.
*/
const CLEANUP_FREQUENCY = 'monthly';
/**
* Constructor.
*
* Get a new instance of the object for a new URL.
*
* @access public
* @since 1.1.0
* @param string $url The remote URL.
*/
public function __construct( $url = '' ) {
$this->remote_url = $url;
// Add a cleanup routine.
$this->schedule_cleanup();
add_action( 'delete_fonts_folder', array( $this, 'delete_fonts_folder' ) );
}
/**
* Get the local URL which contains the styles.
*
* Fallback to the remote URL if we were unable to write the file locally.
*
* @access public
* @since 1.1.0
* @return string
*/
public function get_url() {
// Check if the local stylesheet exists.
if ( $this->local_file_exists() ) {
// Attempt to update the stylesheet. Return the local URL on success.
if ( $this->write_stylesheet() ) {
return $this->get_local_stylesheet_url();
}
}
// If the local file exists, return its URL, with a fallback to the remote URL.
return file_exists( $this->get_local_stylesheet_path() )
? $this->get_local_stylesheet_url()
: $this->remote_url;
}
/**
* Get the local stylesheet URL.
*
* @access public
* @since 1.1.0
* @return string
*/
public function get_local_stylesheet_url() {
if ( ! $this->local_stylesheet_url ) {
$this->local_stylesheet_url = str_replace(
$this->get_base_path(),
$this->get_base_url(),
$this->get_local_stylesheet_path()
);
}
return $this->local_stylesheet_url;
}
/**
* Get styles with fonts downloaded locally.
*
* @access public
* @since 1.0.0
* @return string
*/
public function get_styles() {
// If we already have the local file, return its contents.
$local_stylesheet_contents = $this->get_local_stylesheet_contents();
if ( $local_stylesheet_contents ) {
return $local_stylesheet_contents;
}
// Get the remote URL contents.
$this->remote_styles = $this->get_remote_url_contents();
// Get an array of locally-hosted files.
$files = $this->get_local_files_from_css();
// Convert paths to URLs.
foreach ( $files as $remote => $local ) {
$files[ $remote ] = str_replace(
$this->get_base_path(),
$this->get_base_url(),
$local
);
}
$this->css = str_replace(
array_keys( $files ),
array_values( $files ),
$this->remote_styles
);
$this->write_stylesheet();
return $this->css;
}
/**
* Get local stylesheet contents.
*
* @access public
* @since 1.1.0
* @return string|false Returns the remote URL contents.
*/
public function get_local_stylesheet_contents() {
$local_path = $this->get_local_stylesheet_path();
// Check if the local stylesheet exists.
if ( $this->local_file_exists() ) {
// Attempt to update the stylesheet. Return false on fail.
if ( ! $this->write_stylesheet() ) {
return false;
}
}
ob_start();
include $local_path;
return ob_get_clean();
}
/**
* Get remote file contents.
*
* @access public
* @since 1.0.0
* @return string Returns the remote URL contents.
*/
public function get_remote_url_contents() {
/**
* The user-agent we want to use.
*
* The default user-agent is the only one compatible with woff (not woff2)
* which also supports unicode ranges.
*/
$user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8';
// Switch to a user-agent supporting woff2 if we don't need to support IE.
if ( 'woff2' === $this->font_format ) {
$user_agent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0';
}
// Get the response.
$response = wp_remote_get( $this->remote_url, array( 'user-agent' => $user_agent ) );
// Early exit if there was an error.
if ( is_wp_error( $response ) ) {
return '';
}
// Get the CSS from our response.
$contents = wp_remote_retrieve_body( $response );
return $contents;
}
/**
* Download files mentioned in our CSS locally.
*
* @access public
* @since 1.0.0
* @return array Returns an array of remote URLs and their local counterparts.
*/
public function get_local_files_from_css() {
$font_files = $this->get_remote_files_from_css();
$stored = get_site_option( 'downloaded_font_files', array() );
$change = false; // If in the end this is true, we need to update the cache option.
if ( ! defined( 'FS_CHMOD_DIR' ) ) {
define( 'FS_CHMOD_DIR', ( 0755 & ~ umask() ) );
}
// If the fonts folder don't exist, create it.
if ( ! file_exists( $this->get_fonts_folder() ) ) {
$this->get_filesystem()->mkdir( $this->get_fonts_folder(), FS_CHMOD_DIR );
}
foreach ( $font_files as $font_family => $files ) {
// The folder path for this font-family.
$folder_path = $this->get_fonts_folder() . '/' . $font_family;
// If the folder doesn't exist, create it.
if ( ! file_exists( $folder_path ) ) {
$this->get_filesystem()->mkdir( $folder_path, FS_CHMOD_DIR );
}
foreach ( $files as $url ) {
// Get the filename.
$filename = basename( wp_parse_url( $url, PHP_URL_PATH ) );
$font_path = $folder_path . '/' . $filename;
/**
* In Typekit, the filename will always be the same. We also need to check for query vars in their URLs.
* They provide this font variation description that we can use https://github.com/typekit/fvd
*/
$queries = wp_parse_url( $url, PHP_URL_QUERY );
if ( ! empty( $queries ) ) {
$query_args = array();
parse_str( $queries, $query_args );
if ( array_key_exists( 'fvd', $query_args ) ) {
$font_path .= $query_args['fvd'];
}
}
// Check if the file already exists.
if ( file_exists( $font_path ) ) {
// Skip if already cached.
if ( isset( $stored[ $url ] ) ) {
continue;
}
// Add file to the cache and change the $changed var to indicate we need to update the option.
$stored[ $url ] = $font_path;
$change = true;
// Since the file exists we don't need to proceed with downloading it.
continue;
}
/**
* If we got this far, we need to download the file.
*/
// require file.php if the download_url function doesn't exist.
if ( ! function_exists( 'download_url' ) ) {
require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
}
// Download file to temporary location.
$tmp_path = download_url( $url );
// Make sure there were no errors.
if ( is_wp_error( $tmp_path ) ) {
continue;
}
// Move temp file to final destination.
$success = $this->get_filesystem()->move( $tmp_path, $font_path, true );
if ( $success ) {
$stored[ $url ] = $font_path;
$change = true;
}
}
}
// If there were changes, update the option.
if ( $change ) {
// Cleanup the option and then save it.
foreach ( $stored as $url => $path ) {
if ( ! file_exists( $path ) ) {
unset( $stored[ $url ] );
}
}
update_site_option( 'downloaded_font_files', $stored );
}
return $stored;
}
/**
* Get font files from the CSS.
*
* @access public
* @since 1.0.0
* @return array Returns an array of font-families and the font-files used.
*/
public function get_remote_files_from_css() {
$font_faces = explode( '@font-face', $this->remote_styles );
$result = array();
// Loop all our font-face declarations.
foreach ( $font_faces as $font_face ) {
// Make sure we only process styles inside this declaration.
$style = explode( '}', $font_face )[0];
// Sanity check.
if ( false === strpos( $style, 'font-family' ) ) {
continue;
}
// Get an array of our font-families.
preg_match_all( '/font-family.*?\;/', $style, $matched_font_families );
// Get an array of our font-files.
preg_match_all( '/url\(.*?\)/i', $style, $matched_font_files );
// Get the font-family name.
$font_family = 'unknown';
if ( isset( $matched_font_families[0] ) && isset( $matched_font_families[0][0] ) ) {
$font_family = rtrim( ltrim( $matched_font_families[0][0], 'font-family:' ), ';' );
$font_family = trim( str_replace( array( "'", ';' ), '', $font_family ) );
$font_family = sanitize_key( strtolower( str_replace( ' ', '-', $font_family ) ) );
}
// Make sure the font-family is set in our array.
if ( ! isset( $result[ $font_family ] ) ) {
$result[ $font_family ] = array();
}
// Get files for this font-family and add them to the array.
foreach ( $matched_font_files as $match ) {
// Sanity check.
if ( ! isset( $match[0] ) ) {
continue;
}
// Add the file URL.
$font_family_url = rtrim( ltrim( $match[0], 'url(' ), ')' );
$font_family_url = str_replace( '"', '', $font_family_url );
// Make sure to convert relative URLs to absolute.
$font_family_url = $this->get_absolute_path( $font_family_url );
$result[ $font_family ][] = $font_family_url;
}
// Make sure we have unique items.
// We're using array_flip here instead of array_unique for improved performance.
$result[ $font_family ] = array_flip( array_flip( $result[ $font_family ] ) );
}
return $result;
}
/**
* Write the CSS to the filesystem.
*
* @access protected
* @since 1.1.0
* @return string|false Returns the absolute path of the file on success, or false on fail.
*/
protected function write_stylesheet() {
$file_path = $this->get_local_stylesheet_path();
$filesystem = $this->get_filesystem();
if ( ! defined( 'FS_CHMOD_DIR' ) ) {
define( 'FS_CHMOD_DIR', ( 0755 & ~ umask() ) );
}
// If the folder doesn't exist, create it.
if ( ! file_exists( $this->get_fonts_folder() ) ) {
$this->get_filesystem()->mkdir( $this->get_fonts_folder(), FS_CHMOD_DIR );
}
// If the file doesn't exist, create it. Return false if it can not be created.
if ( ! $filesystem->exists( $file_path ) && ! $filesystem->touch( $file_path ) ) {
return false;
}
// If we got this far, we need to write the file.
// Get the CSS.
if ( ! $this->css ) {
$this->get_styles();
}
// Put the contents in the file. Return false if that fails.
if ( ! $filesystem->put_contents( $file_path, $this->css ) ) {
return false;
}
return $file_path;
}
/**
* Get the stylesheet path.
*
* @access public
* @since 1.1.0
* @return string
*/
public function get_local_stylesheet_path() {
if ( ! $this->local_stylesheet_path ) {
$this->local_stylesheet_path = $this->get_fonts_folder() . '/' . $this->get_local_stylesheet_filename() . '.css';
}
return $this->local_stylesheet_path;
}
/**
* Get the local stylesheet filename.
*
* This is a hash, generated from the site-URL, the wp-content path and the URL.
* This way we can avoid issues with sites changing their URL, or the wp-content path etc.
*
* @access public
* @since 1.1.0
* @return string
*/
public function get_local_stylesheet_filename() {
return md5( $this->get_base_url() . $this->get_base_path() . $this->remote_url . $this->font_format );
}
/**
* Set the font-format to be used.
*
* @access public
* @since 1.0.0
* @param string $format The format to be used. Use "woff" or "woff2".
* @return void
*/
public function set_font_format( $format = 'woff2' ) {
$this->font_format = $format;
}
/**
* Check if the local stylesheet exists.
*
* @access public
* @since 1.1.0
* @return bool
*/
public function local_file_exists() {
return ( ! file_exists( $this->get_local_stylesheet_path() ) );
}
/**
* Get the base path.
*
* @access public
* @since 1.1.0
* @return string
*/
public function get_base_path() {
if ( ! $this->base_path ) {
$this->base_path = apply_filters( 'wptt_get_local_fonts_base_path', $this->get_filesystem()->wp_content_dir() );
}
return $this->base_path;
}
/**
* Get the base URL.
*
* @access public
* @since 1.1.0
* @return string
*/
public function get_base_url() {
if ( ! $this->base_url ) {
$this->base_url = apply_filters( 'wptt_get_local_fonts_base_url', content_url() );
}
return $this->base_url;
}
/**
* Get the subfolder name.
*
* @access public
* @since 1.1.0
* @return string
*/
public function get_subfolder_name() {
if ( ! $this->subfolder_name ) {
$this->subfolder_name = apply_filters( 'wptt_get_local_fonts_subfolder_name', 'fonts' );
}
return $this->subfolder_name;
}
/**
* Get the folder for fonts.
*
* @access public
* @return string
*/
public function get_fonts_folder() {
if ( ! $this->fonts_folder ) {
$this->fonts_folder = $this->get_base_path();
if ( $this->get_subfolder_name() ) {
$this->fonts_folder .= '/' . $this->get_subfolder_name();
}
}
return $this->fonts_folder;
}
/**
* Schedule a cleanup.
*
* Deletes the fonts files on a regular basis.
* This way font files will get updated regularly,
* and we avoid edge cases where unused files remain in the server.
*
* @access public
* @since 1.1.0
* @return void
*/
public function schedule_cleanup() {
if ( ! is_multisite() || ( is_multisite() && is_main_site() ) ) {
if ( ! wp_next_scheduled( 'delete_fonts_folder' ) && ! wp_installing() ) {
wp_schedule_event( time(), self::CLEANUP_FREQUENCY, 'delete_fonts_folder' );
}
}
}
/**
* Delete the fonts folder.
*
* This runs as part of a cleanup routine.
*
* @access public
* @since 1.1.0
* @return bool
*/
public function delete_fonts_folder() {
return $this->get_filesystem()->delete( $this->get_fonts_folder(), true );
}
/**
* Get the filesystem.
*
* @access protected
* @since 1.0.0
* @return \WP_Filesystem_Base
*/
protected function get_filesystem() {
global $wp_filesystem;
// If the filesystem has not been instantiated yet, do it here.
if ( ! $wp_filesystem ) {
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once wp_normalize_path( ABSPATH . '/wp-admin/includes/file.php' );
}
WP_Filesystem();
}
return $wp_filesystem;
}
/**
* Get an absolute URL from a relative URL.
*
* @access protected
*
* @param string $url The URL.
*
* @return string
*/
protected function get_absolute_path( $url ) {
// If dealing with a root-relative URL.
if ( 0 === stripos( $url, '/' ) ) {
$parsed_url = wp_parse_url( $this->remote_url );
return $parsed_url['scheme'] . '://' . $parsed_url['hostname'] . $url;
}
return $url;
}
}
}
if ( ! function_exists( 'wptt_get_webfont_styles' ) ) {
/**
* Get styles for a webfont.
*
* This will get the CSS from the remote API,
* download any fonts it contains,
* replace references to remote URLs with locally-downloaded assets,
* and finally return the resulting CSS.
*
* @since 1.0.0
*
* @param string $url The URL of the remote webfont.
* @param string $format The font-format. If you need to support IE, change this to "woff".
*
* @return string Returns the CSS.
*/
function wptt_get_webfont_styles( $url, $format = 'woff2' ) {
$font = new WPTT_WebFont_Loader( $url );
$font->set_font_format( $format );
return $font->get_styles();
}
}
if ( ! function_exists( 'wptt_get_webfont_url' ) ) {
/**
* Get a stylesheet URL for a webfont.
*
* @since 1.1.0
*
* @param string $url The URL of the remote webfont.
* @param string $format The font-format. If you need to support IE, change this to "woff".
*
* @return string Returns the CSS.
*/
function wptt_get_webfont_url( $url, $format = 'woff2' ) {
$font = new WPTT_WebFont_Loader( $url );
$font->set_font_format( $format );
return $font->get_url();
}
}

View File

@ -0,0 +1,79 @@
<?php
/**
* TGM - Recommended plugins.
*
* @package PressBook
*/
if ( ! function_exists( 'pressbook_register_required_plugins' ) ) {
/**
* Register the required plugins for this theme.
* This function is hooked into `tgmpa_register`, which is fired on the WP `init` action on priority 10.
*/
function pressbook_register_required_plugins() {
/*
* Array of plugin arrays. Required keys are name and slug.
* If the source is NOT from the .org repo, then source is also required.
*/
$plugins = array(
array(
'name' => 'Contact Form Query',
'slug' => 'contact-form-query',
'required' => false,
),
array(
'name' => 'Social Icons Sticky',
'slug' => 'share-social-media',
'required' => false,
),
);
// Don't recommend if pro version already active.
if ( ! defined( 'DARKMODETG_PRO_PLUGIN_VER' ) ) {
array_push(
$plugins,
array(
'name' => 'Dark Mode Toggle',
'slug' => 'dark-mode-toggle',
'required' => false,
)
);
}
// Don't recommend if pro version already active.
if ( ! class_exists( 'STLSP_Login_Security_Pro' ) ) {
array_push(
$plugins,
array(
'name' => 'Login Security Captcha',
'slug' => 'login-security-recaptcha',
'required' => false,
)
);
}
/*
* Array of configuration settings. Amend each line as needed.
*
* TGMPA will start providing localized text strings soon. If you already have translations of our standard
* strings available, please help us make TGMPA even better by giving us access to these translations or by
* sending in a pull-request with .po file(s) with the translations.
*
* Only uncomment the strings in the config array if you want to customize the strings.
*/
$config = array(
'id' => 'pressbook', // Unique ID for hashing notices for multiple instances of TGMPA.
'default_path' => '', // Default absolute path to bundled plugins.
'menu' => 'tgmpa-install-plugins', // Menu slug.
'has_notices' => true, // Show admin notices or not.
'dismissable' => true, // If false, a user cannot dismiss the nag message.
'dismiss_msg' => '', // If 'dismissable' is false, this message will be output at top of nag.
'is_automatic' => false, // Automatically activate plugins after installation or not.
'message' => '', // Message to output right before the plugins table.
);
tgmpa( $plugins, $config );
}
}
add_action( 'tgmpa_register', 'pressbook_register_required_plugins' );

161
inc/theme-page.css Normal file
View File

@ -0,0 +1,161 @@
.pressbook-container {
max-width: 1000px;
margin: 0 auto;
padding: 0 20px;
box-sizing: border-box;
}
.pressbook-container a {
text-decoration: none;
}
.pressbook-title {
font-size: 25px;
font-size: 1.55rem;
font-weight: 600;
line-height: 1.5;
}
.pressbook-title span {
display: inline-block;
margin: 12px 2px;
font-weight: 400;
font-size: 13px;
color: #b4b9be;
vertical-align: middle;
}
.pressbook-panel {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 15px 25px;
margin-bottom: 15px;
background-color: #fff;
}
@media screen and (min-width: 688px) {
.pressbook-panel {
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
}
}
.pressbook-panel--highlight {
border-left: 3px solid #0073aa;
}
.pressbook-panel--highlight .button-primary {
font-size: 15px;
}
.pressbook-panel-title {
display: block;
margin-bottom: 7px;
margin-bottom: .45rem;
font-size: 22px;
font-size: 1.35rem;
line-height: 1.5;
}
.pressbook-panel-actions {
margin-top: 5px;
}
@media screen and (min-width: 688px) {
.pressbook-panel-actions {
margin-top: 0;
margin-left: 15px;
}
}
.pressbook-panel .pressbook-panel-actions a {
margin-top: 5px;
margin-bottom: 5px;
margin-right: 7px;
}
@media screen and (min-width: 688px) {
.pressbook-panel .pressbook-panel-actions a {
margin-right: 0;
}
}
.pressbook-panel .pressbook-review-stars-link {
display: block;
margin-top: 6px;
box-shadow: none;
}
.pressbook-panel-content .description {
font-size: 15px;
font-size: .9375rem;
font-style: normal;
}
.pressbook-check-list-wrap {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
margin: 1rem 0;
}
.pressbook-check-list {
font-size: 15px;
font-size: .9375rem;
line-height: 1.55;
margin-top: 0;
margin-bottom: 0;
margin-right: 2rem;
}
.pressbook-check-list li {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
margin-bottom: 10px;
}
.pressbook-check-list li::before {
content: '';
display: inline-block;
margin-right: 12px;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
height: .63em;
width: .3em;
border-bottom: .25em solid #b4b9be;
border-right: .25em solid #b4b9be;
}
.pressbook-title-wrap {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.pressbook-title {
margin-right: 12px;
}

BIN
inc/transparency-grid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

7
inc/vendor/autoload.php vendored Normal file
View File

@ -0,0 +1,7 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInite840bf700abba19d8b289215efeb8f1e::getLoader();

445
inc/vendor/composer/ClassLoader.php vendored Normal file
View File

@ -0,0 +1,445 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

21
inc/vendor/composer/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,9 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@ -0,0 +1,9 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

10
inc/vendor/composer/autoload_psr4.php vendored Normal file
View File

@ -0,0 +1,10 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'PressBook\\' => array($baseDir . '/core'),
);

52
inc/vendor/composer/autoload_real.php vendored Normal file
View File

@ -0,0 +1,52 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInite840bf700abba19d8b289215efeb8f1e
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInite840bf700abba19d8b289215efeb8f1e', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInite840bf700abba19d8b289215efeb8f1e', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInite840bf700abba19d8b289215efeb8f1e::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
return $loader;
}
}

31
inc/vendor/composer/autoload_static.php vendored Normal file
View File

@ -0,0 +1,31 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInite840bf700abba19d8b289215efeb8f1e
{
public static $prefixLengthsPsr4 = array (
'P' =>
array (
'PressBook\\' => 10,
),
);
public static $prefixDirsPsr4 = array (
'PressBook\\' =>
array (
0 => __DIR__ . '/../..' . '/core',
),
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInite840bf700abba19d8b289215efeb8f1e::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInite840bf700abba19d8b289215efeb8f1e::$prefixDirsPsr4;
}, null, ClassLoader::class);
}
}

259
inc/welcome-page.php Normal file
View File

@ -0,0 +1,259 @@
<?php
/**
* Theme page and welcome notice.
*
* @package PressBook
*/
/**
* Adds a theme menu page.
*/
function pressbook_create_menu() {
$pressbook_page = add_theme_page(
esc_html( apply_filters( 'pressbook_welcome_page_title', _x( 'PressBook', 'page title', 'pressbook' ) ) ),
esc_html( apply_filters( 'pressbook_welcome_menu_title', _x( 'PressBook', 'menu title', 'pressbook' ) ) ),
'edit_theme_options',
'pressbook-options',
'pressbook_page'
);
add_action( 'admin_print_styles-' . $pressbook_page, 'pressbook_options_styles' );
}
add_action( 'admin_menu', 'pressbook_create_menu' );
if ( ! function_exists( 'pressbook_page' ) ) {
/**
* Builds the content of the theme page.
*/
function pressbook_page() {
?>
<div class="wrap">
<div class="metabox-holder">
<div class="pressbook-panel">
<div class="pressbook-container pressbook-title-wrap">
<div class="pressbook-title">
<?php
printf(
wp_kses(
/* translators: 1: theme name, 2: theme version number */
_x( '%1$s <span>Version %2$s</span>', 'menu page heading', 'pressbook' ),
array( 'span' => array() )
),
esc_html( PressBook\Helpers::get_theme_name() ),
esc_html( wp_get_theme()->get( 'Version' ) )
);
?>
</div>
</div>
</div>
<div class="pressbook-container">
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Customize Theme', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can customize the theme using the theme options available in the customizer.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>" class="button"><?php esc_html_e( 'Theme Options', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Top Banner', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can add the top banner image and link from the Customizer > Top Banner.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>?autofocus[section]=sec_top_banner" class="button"><?php esc_html_e( 'Top Banner', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Menus & Social Links', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can create a menu and assign it to a menu location. PressBook comes with three menu locations which include the primary menu, top bar menu, and social links menu. For social links, create a menu item with a custom link, enter the URL of the social page, and assign this menu to the "Social Links Menu" location.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'nav-menus.php' ) ); ?>" class="button"><?php esc_html_e( 'Menus', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel pressbook-panel--highlight">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Premium Version', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'PressBook Premium comes with additional features:', 'pressbook' ); ?>
</p>
<div class="pressbook-check-list-wrap">
<ul class="pressbook-check-list">
<li><?php esc_html_e( 'Dark and Light Color Schemes - Fully Customizable', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Dark and Light Editor Styles - Block Editor', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Alpha Transparency Effect with Background Image', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Sidebar Layout Custom Background Color', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Content Layout Custom Background Color', 'pressbook' ); ?></li>
<li><?php esc_html_e( '4 Header Block Areas with Multiple Options', 'pressbook' ); ?></li>
<li><?php esc_html_e( '3 Footer Block Areas with Multiple Options', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Multiple Posts Carousels with Advanced Options', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Footer Text Color, Link Color & Additional Options', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Standard Grid Layout and Masonry Grid Layout', 'pressbook' ); ?></li>
</ul>
<ul class="pressbook-check-list">
<li><?php esc_html_e( 'Header, Footer, Content, Sidebars - Dark and Light Schemes', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Post Meta, Comment Meta Text Color & Link Color', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Custom Gradient Colors for Buttons', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Custom Accent Colors - Links, Text, Heading, Hover Colors', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Custom Google Fonts for Headings and Body Text', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Typography Settings - Global Font-Size, Font-Family, Line-Height', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Unlimited Color Options & Advanced Theme Options', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Header Posts and Related Posts Grid with Advanced Options', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Multiple Design for Site Branding, Top Navbar, Primary Navbar', 'pressbook' ); ?></li>
<li><?php esc_html_e( 'Multiple Eye-Catching Block Patterns to Quickly Create Sections', 'pressbook' ); ?></li>
</ul>
</div>
<a target="_blank" href="<?php echo esc_url( PressBook\Helpers::get_upsell_buy_url() ); ?>" class="button button-primary"><strong><?php esc_html_e( 'Get Premium', 'pressbook' ); ?></strong></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Top Menu Options & Colors', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can configure the options and change the colors of the top navbar from the Customizer > Top Navbar.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>?autofocus[section]=sec_top_navbar" class="button"><?php esc_html_e( 'Top Navbar', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Primary Menu Options & Colors', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can configure the options and change the colors of the primary navbar from the Customizer > Primary Navbar.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>?autofocus[section]=sec_primary_navbar" class="button"><?php esc_html_e( 'Primary Navbar', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Header / Background Color & Image', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can customize the header image from the Customizer > Header Image and body background image from the Customizer > Background Image. Also, you can change the header and body background color from the Customizer > Colors.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>?autofocus[section]=colors" class="button"><?php esc_html_e( 'Theme Colors', 'pressbook' ); ?></a>
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>?autofocus[section]=header_image" class="button"><?php esc_html_e( 'Header Image', 'pressbook' ); ?></a>
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>?autofocus[section]=background_image" class="button"><?php esc_html_e( 'Background Image', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Header Block Area', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can enable the header block area by creating a block in the pattern block manager. Then select this block in the Customizer > Header Block. PressBook comes with 1 header block area.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>?autofocus[section]=sec_header_block" class="button"><?php esc_html_e( 'Header Blocks', 'pressbook' ); ?></a>
<a target="_blank" href="<?php echo esc_url( admin_url( 'edit.php?post_type=wp_block' ) ); ?>" class="button"><?php esc_html_e( 'Pattern Blocks', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Footer Block Area', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can enable the footer block area by creating a block in the pattern block manager. Then select this block in the Customizer > Footer Block. PressBook comes with 1 footer block area.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'customize.php' ) ); ?>?autofocus[section]=sec_footer_block" class="button"><?php esc_html_e( 'Footer Blocks', 'pressbook' ); ?></a>
<a target="_blank" href="<?php echo esc_url( admin_url( 'edit.php?post_type=wp_block' ) ); ?>" class="button"><?php esc_html_e( 'Pattern Blocks', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Sidebar & Footer Widgets', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'You can drag and drop widgets to the widget area. PressBook comes with 6 widgets area locations which include a left sidebar, right sidebar, and 4 locations for footer widgets.', 'pressbook' ); ?>
</p>
</div>
<div class="pressbook-panel-actions">
<a target="_blank" href="<?php echo esc_url( admin_url( 'widgets.php' ) ); ?>" class="button"><?php esc_html_e( 'Add / Manage Widgets', 'pressbook' ); ?></a>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Page Template & Page Settings', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'When adding or editing a page, there are many page templates to choose from. Also, you can configure the page settings for any specific page. These templates and settings are available on the sidebar area of the page editor screen.', 'pressbook' ); ?>
</p>
</div>
</div>
<div class="pressbook-panel">
<div class="pressbook-panel-content">
<span class="pressbook-panel-title"><?php esc_html_e( 'Page Template with Sidebar', 'pressbook' ); ?></span>
<p class="description">
<?php esc_html_e( 'There are many page templates available to choose from. You can simply edit the page and on the right side of the page editor screen, set the template from "Template" to "Page with sidebar".', 'pressbook' ); ?>
</p>
<p class="description">
<?php esc_html_e( 'Similarly, you can set the page template to full width, large width, medium width, small width, or default template without sidebar.', 'pressbook' ); ?>
</p>
</div>
</div>
</div>
</div>
</div>
<?php
}
}
if ( ! function_exists( 'pressbook_options_styles' ) ) {
/**
* Enqueue styles for the theme page.
*/
function pressbook_options_styles() {
wp_enqueue_style( 'pressbook-options', get_template_directory_uri() . '/inc/theme-page.css', array(), PRESSBOOK_VERSION );
}
}
/**
* Add a notice after theme activation.
*/
function pressbook_welcome_notice() {
global $pagenow;
if ( is_admin() && isset( $_GET['activated'] ) && ( 'themes.php' === $pagenow ) ) { // phpcs:ignore
?>
<div class="updated notice notice-success is-dismissible">
<p>
<?php
echo wp_kses(
sprintf(
/* translators: 1: theme name, 2: welcome page link. */
__( 'Welcome! Thank you for choosing %1$s theme. To get started, visit our <a href="%2$s">welcome page</a>.', 'pressbook' ),
esc_html( PressBook\Helpers::get_theme_name() ),
esc_url( admin_url( 'themes.php?page=pressbook-options' ) )
),
array( 'a' => array( 'href' => array() ) )
);
?>
</p>
<p>
<a class="button" href="<?php echo esc_url( admin_url( 'themes.php?page=pressbook-options' ) ); ?>">
<?php
printf(
/* translators: %s: theme name */
esc_html__( 'Get started with %s', 'pressbook' ),
esc_html( PressBook\Helpers::get_theme_name() )
);
?>
</a>
</p>
</div>
<?php
}
}
add_action( 'admin_notices', 'pressbook_welcome_notice' );

View File

@ -0,0 +1,301 @@
.editor-styles-wrapper,
.editor-styles-wrapper button,
.editor-styles-wrapper input,
.editor-styles-wrapper select,
.editor-styles-wrapper optgroup,
.editor-styles-wrapper textarea,
.editor-styles-wrapper h1,
.editor-styles-wrapper h2,
.editor-styles-wrapper h3,
.editor-styles-wrapper h4,
.editor-styles-wrapper h5,
.editor-styles-wrapper h6 {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
.editor-styles-wrapper {
color: #404040;
font-size: 16px;
font-size: 1rem;
line-height: 1.75;
background: #ffffff !important;
}
@media screen and (min-width: 768px) {
.editor-styles-wrapper {
font-size: 17px;
font-size: 1.0625rem;
}
}
.editor-styles-wrapper h1,
.editor-styles-wrapper h2,
.editor-styles-wrapper h3,
.editor-styles-wrapper h4,
.editor-styles-wrapper h5,
.editor-styles-wrapper h6 {
line-height: 1.5;
}
.editor-styles-wrapper h1 {
margin: .67em 0;
}
.editor-styles-wrapper h2 {
margin: .73em 0;
}
.editor-styles-wrapper h3 {
margin: .8em 0;
}
.editor-styles-wrapper h4 {
margin: .89em 0;
}
.editor-styles-wrapper h5 {
margin: 1em 0;
}
.editor-styles-wrapper h6 {
margin: 1.14em 0;
}
.editor-styles-wrapper p {
margin-bottom: 1.5em;
}
.editor-styles-wrapper a {
text-decoration: underline;
transition: color .2s;
}
.editor-styles-wrapper.editor-styles-wrapper a {
color: #2271b1;
}
.editor-styles-wrapper.editor-styles-wrapper a:hover,
.editor-styles-wrapper.editor-styles-wrapper a:focus,
.editor-styles-wrapper.editor-styles-wrapper a:active {
color: #135e96;
}
.editor-styles-wrapper a:focus {
outline: thin dotted;
}
.editor-styles-wrapper a:focus:not(:focus-visible),
.editor-styles-wrapper a:hover,
.editor-styles-wrapper a:active {
outline: 0;
}
.editor-styles-wrapper p.has-text-color a,
.editor-styles-wrapper p.has-text-color a:hover,
.editor-styles-wrapper p.has-text-color a:focus,
.editor-styles-wrapper p.has-text-color a:active {
color: inherit;
}
.editor-styles-wrapper ul,
.editor-styles-wrapper ol {
margin: 1.5em 0 1.5em 0;
padding-right: 1em;
}
.editor-styles-wrapper ul {
list-style-type: disc;
}
.editor-styles-wrapper ol {
list-style-type: decimal;
}
.editor-styles-wrapper li>ul,
.editor-styles-wrapper li>ol {
margin-top: 0;
margin-bottom: 0;
margin-right: 1.5em;
}
.editor-styles-wrapper li:not(:first-child) {
padding-top: .2em;
}
.editor-styles-wrapper li:not(:last-child) {
padding-bottom: .2em;
}
.editor-styles-wrapper li>ul>li:first-child,
.editor-styles-wrapper li>ol>li:first-child {
padding-top: .4em;
}
.editor-styles-wrapper blockquote {
margin: 0 1.5em;
}
.editor-styles-wrapper .wp-block-quote p {
margin-bottom: .75em;
}
.editor-styles-wrapper .wp-block-quote.is-large p,
.editor-styles-wrapper .wp-block-quote.is-style-large p {
font-size: 1.3em;
}
.editor-styles-wrapper .wp-block-quote__citation,
.editor-styles-wrapper .wp-block-quote cite,
.editor-styles-wrapper .wp-block-quote footer {
font-size: .85em;
}
.editor-styles-wrapper .wp-block-quote.is-large cite,
.editor-styles-wrapper .wp-block-quote.is-large footer,
.editor-styles-wrapper .wp-block-quote.is-style-large cite,
.editor-styles-wrapper .wp-block-quote.is-style-large footer {
font-size: .95em;
}
.editor-styles-wrapper .wp-block-quote,
.editor-styles-wrapper .wp-block-quote.is-large,
.editor-styles-wrapper .wp-block-quote.is-style-large {
margin-bottom: 1.75em;
}
.editor-styles-wrapper .wp-block-pullquote {
padding: 2.4em 0;
}
.editor-styles-wrapper .wp-block-pullquote p {
font-size: 1.75em;
margin-bottom: 0;
}
.editor-styles-wrapper .wp-block-pullquote__citation,
.editor-styles-wrapper .wp-block-pullquote cite,
.editor-styles-wrapper .wp-block-pullquote footer {
display: block;
margin-top: 1.5em;
}
.editor-styles-wrapper .wp-block-pullquote.is-style-solid-color blockquote p {
font-size: 1.9em;
}
.editor-styles-wrapper .wp-block-pullquote.is-style-solid-color blockquote {
max-width: 70%;
}
.editor-styles-wrapper .wp-block-table,
.editor-styles-wrapper .wp-block-video,
.editor-styles-wrapper .wp-block-audio,
.editor-styles-wrapper .wp-block-embed,
.editor-styles-wrapper .wp-block-image,
.editor-styles-wrapper .wp-block-gallery,
.editor-styles-wrapper .wp-block-media-text,
.editor-styles-wrapper .wp-block-calendar {
margin-bottom: 1.5em;
}
.editor-styles-wrapper .wp-block-calendar table:where(:not(.has-text-color)) {
color: inherit;
}
.editor-styles-wrapper .wp-block-table table,
.editor-styles-wrapper .wp-block-calendar .wp-calendar-table {
margin-bottom: 0;
}
.editor-styles-wrapper .wp-block-calendar .wp-calendar-nav {
margin-top: .5em;
}
.editor-styles-wrapper .wp-block-image img {
display: block;
}
.editor-styles-wrapper .wp-block-table figcaption,
.editor-styles-wrapper .wp-block-video figcaption,
.editor-styles-wrapper .wp-block-embed figcaption,
.editor-styles-wrapper .wp-block-image figcaption,
.editor-styles-wrapper .wp-block-gallery figcaption {
font-size: .85em;
}
.editor-styles-wrapper .wp-block-table figcaption,
.editor-styles-wrapper .wp-block-video figcaption,
.editor-styles-wrapper .wp-block-embed figcaption {
margin-top: 1em;
margin-bottom: 0;
}
.editor-styles-wrapper .wp-block-audio figcaption {
margin-top: .75em;
margin-bottom: 0;
font-size: .8em;
}
.editor-styles-wrapper .wp-block-table.is-style-stripes {
border-bottom: 0;
}
.editor-styles-wrapper pre.wp-block-verse {
font-family: 'Courier 10 Pitch', courier, monospace;
}
.editor-styles-wrapper .wp-block-search .wp-block-search__button {
margin-right: 0;
}
.editor-styles-wrapper .wp-block-rss {
padding: 0;
list-style-type: none;
}
.editor-styles-wrapper .wp-block-rss .wp-block-rss__item:not(:last-child) {
margin-bottom: 1em;
}
.editor-styles-wrapper .wp-block-rss .wp-block-rss__item:not(:first-child) {
padding-top: 0;
}
.editor-styles-wrapper .wp-block-latest-comments__comment {
line-height: inherit;
}
.editor-styles-wrapper .wp-block-button__link {
text-decoration: none;
}
.editor-styles-wrapper .wp-block-social-links .wp-block-social-link {
padding: 0;
}
.editor-styles-wrapper .more-link,
.editor-styles-wrapper .wp-block-search .wp-block-search__button,
.editor-styles-wrapper button,
.editor-styles-wrapper input[type="button"],
.editor-styles-wrapper input[type="reset"],
.editor-styles-wrapper input[type="submit"],
.editor-styles-wrapper .more-link:active,
.editor-styles-wrapper .more-link:focus,
.editor-styles-wrapper .more-link:hover,
.editor-styles-wrapper .wp-block-search .wp-block-search__button:active,
.editor-styles-wrapper .wp-block-search .wp-block-search__button:focus,
.editor-styles-wrapper .wp-block-search .wp-block-search__button:hover,
.editor-styles-wrapper button:active,
.editor-styles-wrapper button:focus,
.editor-styles-wrapper button:hover,
.editor-styles-wrapper input[type="button"]:active,
.editor-styles-wrapper input[type="button"]:focus,
.editor-styles-wrapper input[type="button"]:hover,
.editor-styles-wrapper input[type="reset"]:active,
.editor-styles-wrapper input[type="reset"]:focus,
.editor-styles-wrapper input[type="reset"]:hover,
.editor-styles-wrapper input[type="submit"]:active,
.editor-styles-wrapper input[type="submit"]:focus,
.editor-styles-wrapper input[type="submit"]:hover {
color: #ffffff;
}

View File

@ -0,0 +1,301 @@
.editor-styles-wrapper,
.editor-styles-wrapper button,
.editor-styles-wrapper input,
.editor-styles-wrapper select,
.editor-styles-wrapper optgroup,
.editor-styles-wrapper textarea,
.editor-styles-wrapper h1,
.editor-styles-wrapper h2,
.editor-styles-wrapper h3,
.editor-styles-wrapper h4,
.editor-styles-wrapper h5,
.editor-styles-wrapper h6 {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
.editor-styles-wrapper {
color: #404040;
font-size: 16px;
font-size: 1rem;
line-height: 1.75;
background: #ffffff !important;
}
@media screen and (min-width: 768px) {
.editor-styles-wrapper {
font-size: 17px;
font-size: 1.0625rem;
}
}
.editor-styles-wrapper h1,
.editor-styles-wrapper h2,
.editor-styles-wrapper h3,
.editor-styles-wrapper h4,
.editor-styles-wrapper h5,
.editor-styles-wrapper h6 {
line-height: 1.5;
}
.editor-styles-wrapper h1 {
margin: .67em 0;
}
.editor-styles-wrapper h2 {
margin: .73em 0;
}
.editor-styles-wrapper h3 {
margin: .8em 0;
}
.editor-styles-wrapper h4 {
margin: .89em 0;
}
.editor-styles-wrapper h5 {
margin: 1em 0;
}
.editor-styles-wrapper h6 {
margin: 1.14em 0;
}
.editor-styles-wrapper p {
margin-bottom: 1.5em;
}
.editor-styles-wrapper a {
text-decoration: underline;
transition: color .2s;
}
.editor-styles-wrapper.editor-styles-wrapper a {
color: #2271b1;
}
.editor-styles-wrapper.editor-styles-wrapper a:hover,
.editor-styles-wrapper.editor-styles-wrapper a:focus,
.editor-styles-wrapper.editor-styles-wrapper a:active {
color: #135e96;
}
.editor-styles-wrapper a:focus {
outline: thin dotted;
}
.editor-styles-wrapper a:focus:not(:focus-visible),
.editor-styles-wrapper a:hover,
.editor-styles-wrapper a:active {
outline: 0;
}
.editor-styles-wrapper p.has-text-color a,
.editor-styles-wrapper p.has-text-color a:hover,
.editor-styles-wrapper p.has-text-color a:focus,
.editor-styles-wrapper p.has-text-color a:active {
color: inherit;
}
.editor-styles-wrapper ul,
.editor-styles-wrapper ol {
margin: 1.5em 0 1.5em 0;
padding-left: 1em;
}
.editor-styles-wrapper ul {
list-style-type: disc;
}
.editor-styles-wrapper ol {
list-style-type: decimal;
}
.editor-styles-wrapper li>ul,
.editor-styles-wrapper li>ol {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.editor-styles-wrapper li:not(:first-child) {
padding-top: .2em;
}
.editor-styles-wrapper li:not(:last-child) {
padding-bottom: .2em;
}
.editor-styles-wrapper li>ul>li:first-child,
.editor-styles-wrapper li>ol>li:first-child {
padding-top: .4em;
}
.editor-styles-wrapper blockquote {
margin: 0 1.5em;
}
.editor-styles-wrapper .wp-block-quote p {
margin-bottom: .75em;
}
.editor-styles-wrapper .wp-block-quote.is-large p,
.editor-styles-wrapper .wp-block-quote.is-style-large p {
font-size: 1.3em;
}
.editor-styles-wrapper .wp-block-quote__citation,
.editor-styles-wrapper .wp-block-quote cite,
.editor-styles-wrapper .wp-block-quote footer {
font-size: .85em;
}
.editor-styles-wrapper .wp-block-quote.is-large cite,
.editor-styles-wrapper .wp-block-quote.is-large footer,
.editor-styles-wrapper .wp-block-quote.is-style-large cite,
.editor-styles-wrapper .wp-block-quote.is-style-large footer {
font-size: .95em;
}
.editor-styles-wrapper .wp-block-quote,
.editor-styles-wrapper .wp-block-quote.is-large,
.editor-styles-wrapper .wp-block-quote.is-style-large {
margin-bottom: 1.75em;
}
.editor-styles-wrapper .wp-block-pullquote {
padding: 2.4em 0;
}
.editor-styles-wrapper .wp-block-pullquote p {
font-size: 1.75em;
margin-bottom: 0;
}
.editor-styles-wrapper .wp-block-pullquote__citation,
.editor-styles-wrapper .wp-block-pullquote cite,
.editor-styles-wrapper .wp-block-pullquote footer {
display: block;
margin-top: 1.5em;
}
.editor-styles-wrapper .wp-block-pullquote.is-style-solid-color blockquote p {
font-size: 1.9em;
}
.editor-styles-wrapper .wp-block-pullquote.is-style-solid-color blockquote {
max-width: 70%;
}
.editor-styles-wrapper .wp-block-table,
.editor-styles-wrapper .wp-block-video,
.editor-styles-wrapper .wp-block-audio,
.editor-styles-wrapper .wp-block-embed,
.editor-styles-wrapper .wp-block-image,
.editor-styles-wrapper .wp-block-gallery,
.editor-styles-wrapper .wp-block-media-text,
.editor-styles-wrapper .wp-block-calendar {
margin-bottom: 1.5em;
}
.editor-styles-wrapper .wp-block-calendar table:where(:not(.has-text-color)) {
color: inherit;
}
.editor-styles-wrapper .wp-block-table table,
.editor-styles-wrapper .wp-block-calendar .wp-calendar-table {
margin-bottom: 0;
}
.editor-styles-wrapper .wp-block-calendar .wp-calendar-nav {
margin-top: .5em;
}
.editor-styles-wrapper .wp-block-image img {
display: block;
}
.editor-styles-wrapper .wp-block-table figcaption,
.editor-styles-wrapper .wp-block-video figcaption,
.editor-styles-wrapper .wp-block-embed figcaption,
.editor-styles-wrapper .wp-block-image figcaption,
.editor-styles-wrapper .wp-block-gallery figcaption {
font-size: .85em;
}
.editor-styles-wrapper .wp-block-table figcaption,
.editor-styles-wrapper .wp-block-video figcaption,
.editor-styles-wrapper .wp-block-embed figcaption {
margin-top: 1em;
margin-bottom: 0;
}
.editor-styles-wrapper .wp-block-audio figcaption {
margin-top: .75em;
margin-bottom: 0;
font-size: .8em;
}
.editor-styles-wrapper .wp-block-table.is-style-stripes {
border-bottom: 0;
}
.editor-styles-wrapper pre.wp-block-verse {
font-family: 'Courier 10 Pitch', courier, monospace;
}
.editor-styles-wrapper .wp-block-search .wp-block-search__button {
margin-left: 0;
}
.editor-styles-wrapper .wp-block-rss {
padding: 0;
list-style-type: none;
}
.editor-styles-wrapper .wp-block-rss .wp-block-rss__item:not(:last-child) {
margin-bottom: 1em;
}
.editor-styles-wrapper .wp-block-rss .wp-block-rss__item:not(:first-child) {
padding-top: 0;
}
.editor-styles-wrapper .wp-block-latest-comments__comment {
line-height: inherit;
}
.editor-styles-wrapper .wp-block-button__link {
text-decoration: none;
}
.editor-styles-wrapper .wp-block-social-links .wp-block-social-link {
padding: 0;
}
.editor-styles-wrapper .more-link,
.editor-styles-wrapper .wp-block-search .wp-block-search__button,
.editor-styles-wrapper button,
.editor-styles-wrapper input[type="button"],
.editor-styles-wrapper input[type="reset"],
.editor-styles-wrapper input[type="submit"],
.editor-styles-wrapper .more-link:active,
.editor-styles-wrapper .more-link:focus,
.editor-styles-wrapper .more-link:hover,
.editor-styles-wrapper .wp-block-search .wp-block-search__button:active,
.editor-styles-wrapper .wp-block-search .wp-block-search__button:focus,
.editor-styles-wrapper .wp-block-search .wp-block-search__button:hover,
.editor-styles-wrapper button:active,
.editor-styles-wrapper button:focus,
.editor-styles-wrapper button:hover,
.editor-styles-wrapper input[type="button"]:active,
.editor-styles-wrapper input[type="button"]:focus,
.editor-styles-wrapper input[type="button"]:hover,
.editor-styles-wrapper input[type="reset"]:active,
.editor-styles-wrapper input[type="reset"]:focus,
.editor-styles-wrapper input[type="reset"]:hover,
.editor-styles-wrapper input[type="submit"]:active,
.editor-styles-wrapper input[type="submit"]:focus,
.editor-styles-wrapper input[type="submit"]:hover {
color: #ffffff;
}

View File

@ -0,0 +1,20 @@
.wp-block h1,
.wp-block h2 {
font-size: 1.1em;
}
.wp-block h3 {
font-size: 1.08em;
}
.wp-block h4 {
font-size: 1.05em;
}
.wp-block h5 {
font-size: 1.02em;
}
.wp-block h6 {
font-size: 1em;
}

70
index.php Normal file
View File

@ -0,0 +1,70 @@
<?php
/**
* The main template file.
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no home.php file exists.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package PressBook
*/
$pressbook_archv_title = PressBook\Options\Blog::archv_title();
get_header();
?>
<div class="pb-content-sidebar u-wrapper">
<main id="primary" class="site-main">
<?php
if ( have_posts() ) {
if ( is_home() && ! is_front_page() ) {
?>
<header>
<h1 class="page-title screen-reader-text"><?php single_post_title(); ?></h1>
</header>
<?php
} elseif ( is_archive() ) {
?>
<header class="<?php echo esc_attr( $pressbook_archv_title['header'] ); ?>">
<h1 class="<?php echo esc_attr( $pressbook_archv_title['class'] ); ?>"><?php the_archive_title(); ?></h1>
<?php
if ( $pressbook_archv_title['show'] ) {
the_archive_description( '<div class="pb-archv-desc">', '</div>' );
}
?>
</header>
<?php
} elseif ( is_search() ) {
?>
<header class="<?php echo esc_attr( $pressbook_archv_title['header'] ); ?>">
<h1 class="<?php echo esc_attr( $pressbook_archv_title['class'] ); ?>"><?php /* translators: %s: search query */ printf( esc_html__( 'Search Results for: %s', 'pressbook' ), '<span>' . esc_html( get_search_query() ) . '</span>' ); ?></h1>
</header>
<?php
}
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content' );
}
the_posts_pagination();
} else {
get_template_part( 'template-parts/content', 'none' );
}
?>
</main><!-- #primary -->
<?php
get_sidebar( 'left' );
get_sidebar();
?>
</div><!-- .pb-content-sidebar -->
<?php
get_footer();

936
js/ResizeObserver.js Normal file
View File

@ -0,0 +1,936 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.ResizeObserver = factory());
}(this, (function () { 'use strict';
/**
* A collection of shims that provide minimal functionality of the ES6 collections.
*
* These implementations are not meant to be used outside of the ResizeObserver
* modules as they cover only a limited range of use cases.
*/
/* eslint-disable require-jsdoc, valid-jsdoc */
var MapShim = (function () {
if (typeof Map !== 'undefined') {
return Map;
}
/**
* Returns index in provided array that matches the specified key.
*
* @param {Array<Array>} arr
* @param {*} key
* @returns {number}
*/
function getIndex(arr, key) {
var result = -1;
arr.some(function (entry, index) {
if (entry[0] === key) {
result = index;
return true;
}
return false;
});
return result;
}
return /** @class */ (function () {
function class_1() {
this.__entries__ = [];
}
Object.defineProperty(class_1.prototype, "size", {
/**
* @returns {boolean}
*/
get: function () {
return this.__entries__.length;
},
enumerable: true,
configurable: true
});
/**
* @param {*} key
* @returns {*}
*/
class_1.prototype.get = function (key) {
var index = getIndex(this.__entries__, key);
var entry = this.__entries__[index];
return entry && entry[1];
};
/**
* @param {*} key
* @param {*} value
* @returns {void}
*/
class_1.prototype.set = function (key, value) {
var index = getIndex(this.__entries__, key);
if (~index) {
this.__entries__[index][1] = value;
}
else {
this.__entries__.push([key, value]);
}
};
/**
* @param {*} key
* @returns {void}
*/
class_1.prototype.delete = function (key) {
var entries = this.__entries__;
var index = getIndex(entries, key);
if (~index) {
entries.splice(index, 1);
}
};
/**
* @param {*} key
* @returns {void}
*/
class_1.prototype.has = function (key) {
return !!~getIndex(this.__entries__, key);
};
/**
* @returns {void}
*/
class_1.prototype.clear = function () {
this.__entries__.splice(0);
};
/**
* @param {Function} callback
* @param {*} [ctx=null]
* @returns {void}
*/
class_1.prototype.forEach = function (callback, ctx) {
if (ctx === void 0) { ctx = null; }
for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {
var entry = _a[_i];
callback.call(ctx, entry[1], entry[0]);
}
};
return class_1;
}());
})();
/**
* Detects whether window and document objects are available in current environment.
*/
var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;
// Returns global object of a current environment.
var global$1 = (function () {
if (typeof global !== 'undefined' && global.Math === Math) {
return global;
}
if (typeof self !== 'undefined' && self.Math === Math) {
return self;
}
if (typeof window !== 'undefined' && window.Math === Math) {
return window;
}
// eslint-disable-next-line no-new-func
return Function('return this')();
})();
/**
* A shim for the requestAnimationFrame which falls back to the setTimeout if
* first one is not supported.
*
* @returns {number} Requests' identifier.
*/
var requestAnimationFrame$1 = (function () {
if (typeof requestAnimationFrame === 'function') {
// It's required to use a bounded function because IE sometimes throws
// an "Invalid calling object" error if rAF is invoked without the global
// object on the left hand side.
return requestAnimationFrame.bind(global$1);
}
return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };
})();
// Defines minimum timeout before adding a trailing call.
var trailingTimeout = 2;
/**
* Creates a wrapper function which ensures that provided callback will be
* invoked only once during the specified delay period.
*
* @param {Function} callback - Function to be invoked after the delay period.
* @param {number} delay - Delay after which to invoke callback.
* @returns {Function}
*/
function throttle (callback, delay) {
var leadingCall = false, trailingCall = false, lastCallTime = 0;
/**
* Invokes the original callback function and schedules new invocation if
* the "proxy" was called during current request.
*
* @returns {void}
*/
function resolvePending() {
if (leadingCall) {
leadingCall = false;
callback();
}
if (trailingCall) {
proxy();
}
}
/**
* Callback invoked after the specified delay. It will further postpone
* invocation of the original function delegating it to the
* requestAnimationFrame.
*
* @returns {void}
*/
function timeoutCallback() {
requestAnimationFrame$1(resolvePending);
}
/**
* Schedules invocation of the original function.
*
* @returns {void}
*/
function proxy() {
var timeStamp = Date.now();
if (leadingCall) {
// Reject immediately following calls.
if (timeStamp - lastCallTime < trailingTimeout) {
return;
}
// Schedule new call to be in invoked when the pending one is resolved.
// This is important for "transitions" which never actually start
// immediately so there is a chance that we might miss one if change
// happens amids the pending invocation.
trailingCall = true;
}
else {
leadingCall = true;
trailingCall = false;
setTimeout(timeoutCallback, delay);
}
lastCallTime = timeStamp;
}
return proxy;
}
// Minimum delay before invoking the update of observers.
var REFRESH_DELAY = 20;
// A list of substrings of CSS properties used to find transition events that
// might affect dimensions of observed elements.
var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];
// Check if MutationObserver is available.
var mutationObserverSupported = typeof MutationObserver !== 'undefined';
/**
* Singleton controller class which handles updates of ResizeObserver instances.
*/
var ResizeObserverController = /** @class */ (function () {
/**
* Creates a new instance of ResizeObserverController.
*
* @private
*/
function ResizeObserverController() {
/**
* Indicates whether DOM listeners have been added.
*
* @private {boolean}
*/
this.connected_ = false;
/**
* Tells that controller has subscribed for Mutation Events.
*
* @private {boolean}
*/
this.mutationEventsAdded_ = false;
/**
* Keeps reference to the instance of MutationObserver.
*
* @private {MutationObserver}
*/
this.mutationsObserver_ = null;
/**
* A list of connected observers.
*
* @private {Array<ResizeObserverSPI>}
*/
this.observers_ = [];
this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);
this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);
}
/**
* Adds observer to observers list.
*
* @param {ResizeObserverSPI} observer - Observer to be added.
* @returns {void}
*/
ResizeObserverController.prototype.addObserver = function (observer) {
if (!~this.observers_.indexOf(observer)) {
this.observers_.push(observer);
}
// Add listeners if they haven't been added yet.
if (!this.connected_) {
this.connect_();
}
};
/**
* Removes observer from observers list.
*
* @param {ResizeObserverSPI} observer - Observer to be removed.
* @returns {void}
*/
ResizeObserverController.prototype.removeObserver = function (observer) {
var observers = this.observers_;
var index = observers.indexOf(observer);
// Remove observer if it's present in registry.
if (~index) {
observers.splice(index, 1);
}
// Remove listeners if controller has no connected observers.
if (!observers.length && this.connected_) {
this.disconnect_();
}
};
/**
* Invokes the update of observers. It will continue running updates insofar
* it detects changes.
*
* @returns {void}
*/
ResizeObserverController.prototype.refresh = function () {
var changesDetected = this.updateObservers_();
// Continue running updates if changes have been detected as there might
// be future ones caused by CSS transitions.
if (changesDetected) {
this.refresh();
}
};
/**
* Updates every observer from observers list and notifies them of queued
* entries.
*
* @private
* @returns {boolean} Returns "true" if any observer has detected changes in
* dimensions of it's elements.
*/
ResizeObserverController.prototype.updateObservers_ = function () {
// Collect observers that have active observations.
var activeObservers = this.observers_.filter(function (observer) {
return observer.gatherActive(), observer.hasActive();
});
// Deliver notifications in a separate cycle in order to avoid any
// collisions between observers, e.g. when multiple instances of
// ResizeObserver are tracking the same element and the callback of one
// of them changes content dimensions of the observed target. Sometimes
// this may result in notifications being blocked for the rest of observers.
activeObservers.forEach(function (observer) { return observer.broadcastActive(); });
return activeObservers.length > 0;
};
/**
* Initializes DOM listeners.
*
* @private
* @returns {void}
*/
ResizeObserverController.prototype.connect_ = function () {
// Do nothing if running in a non-browser environment or if listeners
// have been already added.
if (!isBrowser || this.connected_) {
return;
}
// Subscription to the "Transitionend" event is used as a workaround for
// delayed transitions. This way it's possible to capture at least the
// final state of an element.
document.addEventListener('transitionend', this.onTransitionEnd_);
window.addEventListener('resize', this.refresh);
if (mutationObserverSupported) {
this.mutationsObserver_ = new MutationObserver(this.refresh);
this.mutationsObserver_.observe(document, {
attributes: true,
childList: true,
characterData: true,
subtree: true
});
}
else {
document.addEventListener('DOMSubtreeModified', this.refresh);
this.mutationEventsAdded_ = true;
}
this.connected_ = true;
};
/**
* Removes DOM listeners.
*
* @private
* @returns {void}
*/
ResizeObserverController.prototype.disconnect_ = function () {
// Do nothing if running in a non-browser environment or if listeners
// have been already removed.
if (!isBrowser || !this.connected_) {
return;
}
document.removeEventListener('transitionend', this.onTransitionEnd_);
window.removeEventListener('resize', this.refresh);
if (this.mutationsObserver_) {
this.mutationsObserver_.disconnect();
}
if (this.mutationEventsAdded_) {
document.removeEventListener('DOMSubtreeModified', this.refresh);
}
this.mutationsObserver_ = null;
this.mutationEventsAdded_ = false;
this.connected_ = false;
};
/**
* "Transitionend" event handler.
*
* @private
* @param {TransitionEvent} event
* @returns {void}
*/
ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {
var _b = _a.propertyName, propertyName = _b === void 0 ? '' : _b;
// Detect whether transition may affect dimensions of an element.
var isReflowProperty = transitionKeys.some(function (key) {
return !!~propertyName.indexOf(key);
});
if (isReflowProperty) {
this.refresh();
}
};
/**
* Returns instance of the ResizeObserverController.
*
* @returns {ResizeObserverController}
*/
ResizeObserverController.getInstance = function () {
if (!this.instance_) {
this.instance_ = new ResizeObserverController();
}
return this.instance_;
};
/**
* Holds reference to the controller's instance.
*
* @private {ResizeObserverController}
*/
ResizeObserverController.instance_ = null;
return ResizeObserverController;
}());
/**
* Defines non-writable/enumerable properties of the provided target object.
*
* @param {Object} target - Object for which to define properties.
* @param {Object} props - Properties to be defined.
* @returns {Object} Target object.
*/
var defineConfigurable = (function (target, props) {
for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {
var key = _a[_i];
Object.defineProperty(target, key, {
value: props[key],
enumerable: false,
writable: false,
configurable: true
});
}
return target;
});
/**
* Returns the global object associated with provided element.
*
* @param {Object} target
* @returns {Object}
*/
var getWindowOf = (function (target) {
// Assume that the element is an instance of Node, which means that it
// has the "ownerDocument" property from which we can retrieve a
// corresponding global object.
var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;
// Return the local global object if it's not possible extract one from
// provided element.
return ownerGlobal || global$1;
});
// Placeholder of an empty content rectangle.
var emptyRect = createRectInit(0, 0, 0, 0);
/**
* Converts provided string to a number.
*
* @param {number|string} value
* @returns {number}
*/
function toFloat(value) {
return parseFloat(value) || 0;
}
/**
* Extracts borders size from provided styles.
*
* @param {CSSStyleDeclaration} styles
* @param {...string} positions - Borders positions (top, right, ...)
* @returns {number}
*/
function getBordersSize(styles) {
var positions = [];
for (var _i = 1; _i < arguments.length; _i++) {
positions[_i - 1] = arguments[_i];
}
return positions.reduce(function (size, position) {
var value = styles['border-' + position + '-width'];
return size + toFloat(value);
}, 0);
}
/**
* Extracts paddings sizes from provided styles.
*
* @param {CSSStyleDeclaration} styles
* @returns {Object} Paddings box.
*/
function getPaddings(styles) {
var positions = ['top', 'right', 'bottom', 'left'];
var paddings = {};
for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {
var position = positions_1[_i];
var value = styles['padding-' + position];
paddings[position] = toFloat(value);
}
return paddings;
}
/**
* Calculates content rectangle of provided SVG element.
*
* @param {SVGGraphicsElement} target - Element content rectangle of which needs
* to be calculated.
* @returns {DOMRectInit}
*/
function getSVGContentRect(target) {
var bbox = target.getBBox();
return createRectInit(0, 0, bbox.width, bbox.height);
}
/**
* Calculates content rectangle of provided HTMLElement.
*
* @param {HTMLElement} target - Element for which to calculate the content rectangle.
* @returns {DOMRectInit}
*/
function getHTMLElementContentRect(target) {
// Client width & height properties can't be
// used exclusively as they provide rounded values.
var clientWidth = target.clientWidth, clientHeight = target.clientHeight;
// By this condition we can catch all non-replaced inline, hidden and
// detached elements. Though elements with width & height properties less
// than 0.5 will be discarded as well.
//
// Without it we would need to implement separate methods for each of
// those cases and it's not possible to perform a precise and performance
// effective test for hidden elements. E.g. even jQuery's ':visible' filter
// gives wrong results for elements with width & height less than 0.5.
if (!clientWidth && !clientHeight) {
return emptyRect;
}
var styles = getWindowOf(target).getComputedStyle(target);
var paddings = getPaddings(styles);
var horizPad = paddings.left + paddings.right;
var vertPad = paddings.top + paddings.bottom;
// Computed styles of width & height are being used because they are the
// only dimensions available to JS that contain non-rounded values. It could
// be possible to utilize the getBoundingClientRect if only it's data wasn't
// affected by CSS transformations let alone paddings, borders and scroll bars.
var width = toFloat(styles.width), height = toFloat(styles.height);
// Width & height include paddings and borders when the 'border-box' box
// model is applied (except for IE).
if (styles.boxSizing === 'border-box') {
// Following conditions are required to handle Internet Explorer which
// doesn't include paddings and borders to computed CSS dimensions.
//
// We can say that if CSS dimensions + paddings are equal to the "client"
// properties then it's either IE, and thus we don't need to subtract
// anything, or an element merely doesn't have paddings/borders styles.
if (Math.round(width + horizPad) !== clientWidth) {
width -= getBordersSize(styles, 'left', 'right') + horizPad;
}
if (Math.round(height + vertPad) !== clientHeight) {
height -= getBordersSize(styles, 'top', 'bottom') + vertPad;
}
}
// Following steps can't be applied to the document's root element as its
// client[Width/Height] properties represent viewport area of the window.
// Besides, it's as well not necessary as the <html> itself neither has
// rendered scroll bars nor it can be clipped.
if (!isDocumentElement(target)) {
// In some browsers (only in Firefox, actually) CSS width & height
// include scroll bars size which can be removed at this step as scroll
// bars are the only difference between rounded dimensions + paddings
// and "client" properties, though that is not always true in Chrome.
var vertScrollbar = Math.round(width + horizPad) - clientWidth;
var horizScrollbar = Math.round(height + vertPad) - clientHeight;
// Chrome has a rather weird rounding of "client" properties.
// E.g. for an element with content width of 314.2px it sometimes gives
// the client width of 315px and for the width of 314.7px it may give
// 314px. And it doesn't happen all the time. So just ignore this delta
// as a non-relevant.
if (Math.abs(vertScrollbar) !== 1) {
width -= vertScrollbar;
}
if (Math.abs(horizScrollbar) !== 1) {
height -= horizScrollbar;
}
}
return createRectInit(paddings.left, paddings.top, width, height);
}
/**
* Checks whether provided element is an instance of the SVGGraphicsElement.
*
* @param {Element} target - Element to be checked.
* @returns {boolean}
*/
var isSVGGraphicsElement = (function () {
// Some browsers, namely IE and Edge, don't have the SVGGraphicsElement
// interface.
if (typeof SVGGraphicsElement !== 'undefined') {
return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };
}
// If it's so, then check that element is at least an instance of the
// SVGElement and that it has the "getBBox" method.
// eslint-disable-next-line no-extra-parens
return function (target) { return (target instanceof getWindowOf(target).SVGElement &&
typeof target.getBBox === 'function'); };
})();
/**
* Checks whether provided element is a document element (<html>).
*
* @param {Element} target - Element to be checked.
* @returns {boolean}
*/
function isDocumentElement(target) {
return target === getWindowOf(target).document.documentElement;
}
/**
* Calculates an appropriate content rectangle for provided html or svg element.
*
* @param {Element} target - Element content rectangle of which needs to be calculated.
* @returns {DOMRectInit}
*/
function getContentRect(target) {
if (!isBrowser) {
return emptyRect;
}
if (isSVGGraphicsElement(target)) {
return getSVGContentRect(target);
}
return getHTMLElementContentRect(target);
}
/**
* Creates rectangle with an interface of the DOMRectReadOnly.
* Spec: https://drafts.fxtf.org/geometry/#domrectreadonly
*
* @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.
* @returns {DOMRectReadOnly}
*/
function createReadOnlyRect(_a) {
var x = _a.x, y = _a.y, width = _a.width, height = _a.height;
// If DOMRectReadOnly is available use it as a prototype for the rectangle.
var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;
var rect = Object.create(Constr.prototype);
// Rectangle's properties are not writable and non-enumerable.
defineConfigurable(rect, {
x: x, y: y, width: width, height: height,
top: y,
right: x + width,
bottom: height + y,
left: x
});
return rect;
}
/**
* Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.
* Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit
*
* @param {number} x - X coordinate.
* @param {number} y - Y coordinate.
* @param {number} width - Rectangle's width.
* @param {number} height - Rectangle's height.
* @returns {DOMRectInit}
*/
function createRectInit(x, y, width, height) {
return { x: x, y: y, width: width, height: height };
}
/**
* Class that is responsible for computations of the content rectangle of
* provided DOM element and for keeping track of it's changes.
*/
var ResizeObservation = /** @class */ (function () {
/**
* Creates an instance of ResizeObservation.
*
* @param {Element} target - Element to be observed.
*/
function ResizeObservation(target) {
/**
* Broadcasted width of content rectangle.
*
* @type {number}
*/
this.broadcastWidth = 0;
/**
* Broadcasted height of content rectangle.
*
* @type {number}
*/
this.broadcastHeight = 0;
/**
* Reference to the last observed content rectangle.
*
* @private {DOMRectInit}
*/
this.contentRect_ = createRectInit(0, 0, 0, 0);
this.target = target;
}
/**
* Updates content rectangle and tells whether it's width or height properties
* have changed since the last broadcast.
*
* @returns {boolean}
*/
ResizeObservation.prototype.isActive = function () {
var rect = getContentRect(this.target);
this.contentRect_ = rect;
return (rect.width !== this.broadcastWidth ||
rect.height !== this.broadcastHeight);
};
/**
* Updates 'broadcastWidth' and 'broadcastHeight' properties with a data
* from the corresponding properties of the last observed content rectangle.
*
* @returns {DOMRectInit} Last observed content rectangle.
*/
ResizeObservation.prototype.broadcastRect = function () {
var rect = this.contentRect_;
this.broadcastWidth = rect.width;
this.broadcastHeight = rect.height;
return rect;
};
return ResizeObservation;
}());
var ResizeObserverEntry = /** @class */ (function () {
/**
* Creates an instance of ResizeObserverEntry.
*
* @param {Element} target - Element that is being observed.
* @param {DOMRectInit} rectInit - Data of the element's content rectangle.
*/
function ResizeObserverEntry(target, rectInit) {
var contentRect = createReadOnlyRect(rectInit);
// According to the specification following properties are not writable
// and are also not enumerable in the native implementation.
//
// Property accessors are not being used as they'd require to define a
// private WeakMap storage which may cause memory leaks in browsers that
// don't support this type of collections.
defineConfigurable(this, { target: target, contentRect: contentRect });
}
return ResizeObserverEntry;
}());
var ResizeObserverSPI = /** @class */ (function () {
/**
* Creates a new instance of ResizeObserver.
*
* @param {ResizeObserverCallback} callback - Callback function that is invoked
* when one of the observed elements changes it's content dimensions.
* @param {ResizeObserverController} controller - Controller instance which
* is responsible for the updates of observer.
* @param {ResizeObserver} callbackCtx - Reference to the public
* ResizeObserver instance which will be passed to callback function.
*/
function ResizeObserverSPI(callback, controller, callbackCtx) {
/**
* Collection of resize observations that have detected changes in dimensions
* of elements.
*
* @private {Array<ResizeObservation>}
*/
this.activeObservations_ = [];
/**
* Registry of the ResizeObservation instances.
*
* @private {Map<Element, ResizeObservation>}
*/
this.observations_ = new MapShim();
if (typeof callback !== 'function') {
throw new TypeError('The callback provided as parameter 1 is not a function.');
}
this.callback_ = callback;
this.controller_ = controller;
this.callbackCtx_ = callbackCtx;
}
/**
* Starts observing provided element.
*
* @param {Element} target - Element to be observed.
* @returns {void}
*/
ResizeObserverSPI.prototype.observe = function (target) {
if (!arguments.length) {
throw new TypeError('1 argument required, but only 0 present.');
}
// Do nothing if current environment doesn't have the Element interface.
if (typeof Element === 'undefined' || !(Element instanceof Object)) {
return;
}
if (!(target instanceof getWindowOf(target).Element)) {
throw new TypeError('parameter 1 is not of type "Element".');
}
var observations = this.observations_;
// Do nothing if element is already being observed.
if (observations.has(target)) {
return;
}
observations.set(target, new ResizeObservation(target));
this.controller_.addObserver(this);
// Force the update of observations.
this.controller_.refresh();
};
/**
* Stops observing provided element.
*
* @param {Element} target - Element to stop observing.
* @returns {void}
*/
ResizeObserverSPI.prototype.unobserve = function (target) {
if (!arguments.length) {
throw new TypeError('1 argument required, but only 0 present.');
}
// Do nothing if current environment doesn't have the Element interface.
if (typeof Element === 'undefined' || !(Element instanceof Object)) {
return;
}
if (!(target instanceof getWindowOf(target).Element)) {
throw new TypeError('parameter 1 is not of type "Element".');
}
var observations = this.observations_;
// Do nothing if element is not being observed.
if (!observations.has(target)) {
return;
}
observations.delete(target);
if (!observations.size) {
this.controller_.removeObserver(this);
}
};
/**
* Stops observing all elements.
*
* @returns {void}
*/
ResizeObserverSPI.prototype.disconnect = function () {
this.clearActive();
this.observations_.clear();
this.controller_.removeObserver(this);
};
/**
* Collects observation instances the associated element of which has changed
* it's content rectangle.
*
* @returns {void}
*/
ResizeObserverSPI.prototype.gatherActive = function () {
var _this = this;
this.clearActive();
this.observations_.forEach(function (observation) {
if (observation.isActive()) {
_this.activeObservations_.push(observation);
}
});
};
/**
* Invokes initial callback function with a list of ResizeObserverEntry
* instances collected from active resize observations.
*
* @returns {void}
*/
ResizeObserverSPI.prototype.broadcastActive = function () {
// Do nothing if observer doesn't have active observations.
if (!this.hasActive()) {
return;
}
var ctx = this.callbackCtx_;
// Create ResizeObserverEntry instance for every active observation.
var entries = this.activeObservations_.map(function (observation) {
return new ResizeObserverEntry(observation.target, observation.broadcastRect());
});
this.callback_.call(ctx, entries, ctx);
this.clearActive();
};
/**
* Clears the collection of active observations.
*
* @returns {void}
*/
ResizeObserverSPI.prototype.clearActive = function () {
this.activeObservations_.splice(0);
};
/**
* Tells whether observer has active observations.
*
* @returns {boolean}
*/
ResizeObserverSPI.prototype.hasActive = function () {
return this.activeObservations_.length > 0;
};
return ResizeObserverSPI;
}());
// Registry of internal observers. If WeakMap is not available use current shim
// for the Map collection as it has all required methods and because WeakMap
// can't be fully polyfilled anyway.
var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();
/**
* ResizeObserver API. Encapsulates the ResizeObserver SPI implementation
* exposing only those methods and properties that are defined in the spec.
*/
var ResizeObserver = /** @class */ (function () {
/**
* Creates a new instance of ResizeObserver.
*
* @param {ResizeObserverCallback} callback - Callback that is invoked when
* dimensions of the observed elements change.
*/
function ResizeObserver(callback) {
if (!(this instanceof ResizeObserver)) {
throw new TypeError('Cannot call a class as a function.');
}
if (!arguments.length) {
throw new TypeError('1 argument required, but only 0 present.');
}
var controller = ResizeObserverController.getInstance();
var observer = new ResizeObserverSPI(callback, controller, this);
observers.set(this, observer);
}
return ResizeObserver;
}());
// Expose public methods of ResizeObserver.
[
'observe',
'unobserve',
'disconnect'
].forEach(function (method) {
ResizeObserver.prototype[method] = function () {
var _a;
return (_a = observers.get(this))[method].apply(_a, arguments);
};
});
var index = (function () {
// Export existing implementation if available.
if (typeof global$1.ResizeObserver !== 'undefined') {
return global$1.ResizeObserver;
}
return ResizeObserver;
})();
return index;
})));

1
js/ResizeObserver.min.js vendored Normal file

File diff suppressed because one or more lines are too long

269
js/alpha-color-picker.js Normal file
View File

@ -0,0 +1,269 @@
/**
* Alpha Color Picker JS
*
* This file includes several helper functions and the core control JS.
*/
/**
* Override the stock color.js toString() method to add support for
* outputting RGBa or Hex.
*/
Color.prototype.toString = function ( flag ) {
// If our no-alpha flag has been passed in, output RGBa value with 100% opacity.
// This is used to set the background color on the opacity slider during color changes.
if ( 'no-alpha' == flag ) {
return this.toCSS( 'rgba', '1' ).replace( /\s+/g, '' );
}
// If we have a proper opacity value, output RGBa.
if ( 1 > this._alpha ) {
return this.toCSS( 'rgba', this._alpha ).replace( /\s+/g, '' );
}
// Proceed with stock color.js hex output.
var hex = parseInt( this._color, 10 ).toString( 16 );
if ( this.error ) {
return '';
}
if ( hex.length < 6 ) {
for ( var i = 6 - hex.length - 1; i >= 0; i-- ) {
hex = '0' + hex;
}
}
return '#' + hex;
};
/**
* Given an RGBa, RGB, or hex color value, return the alpha channel value.
*/
function acp_get_alpha_value_from_color( value ) {
var alphaVal;
// Remove all spaces from the passed in value to help our RGBa regex.
value = value.replace( / /g, '' );
if ( value.match( /rgba\(\d+\,\d+\,\d+\,([^\)]+)\)/ ) ) {
alphaVal = parseFloat( value.match( /rgba\(\d+\,\d+\,\d+\,([^\)]+)\)/)[1] ).toFixed( 2 ) * 100;
alphaVal = parseInt( alphaVal );
} else {
alphaVal = 100;
}
return alphaVal;
}
/**
* Force update the alpha value of the color picker object and maybe the alpha slider.
*/
function acp_update_alpha_value_on_color_control( alpha, $control, $alphaSlider, update_slider ) {
var iris, colorPicker, color;
iris = $control.data( 'a8cIris' );
colorPicker = $control.data( 'wpWpColorPicker' );
// Set the alpha value on the Iris object.
iris._color._alpha = alpha;
// Store the new color value.
color = iris._color.toString();
// Set the value of the input.
$control.val( color );
// Update the background color of the color picker.
colorPicker.toggler.css( {
'background-color': color
} );
// Maybe update the alpha slider itself.
if ( update_slider ) {
acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider );
}
// Update the color value of the color picker object.
$control.wpColorPicker( 'color', color );
}
/**
* Update the slider handle position and label.
*/
function acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider ) {
$alphaSlider.slider( 'value', alpha );
$alphaSlider.find( '.ui-slider-handle' ).text( alpha.toString() );
}
/**
* Initialization trigger.
*/
jQuery( document ).ready( function ( $ ) {
// Loop over each control and transform it into our color picker.
$( '.alpha-color-control' ).each( function () {
// Scope the vars.
var $control, startingColor, paletteInput, showOpacity, defaultColor, palette,
colorPickerOptions, $container, $alphaSlider, alphaVal, sliderOptions;
// Store the control instance.
$control = $( this );
// Get a clean starting value for the option.
startingColor = $control.val().replace( /\s+/g, '' );
// Get some data off the control.
paletteInput = $control.attr( 'data-palette' );
showOpacity = $control.attr( 'data-show-opacity' );
defaultColor = $control.attr( 'data-default-color' );
// Process the palette.
if ( -1 !== paletteInput.indexOf( '|' ) ) {
palette = paletteInput.split( '|' );
} else if ( 'false' == paletteInput ) {
palette = false;
} else {
palette = true;
}
// Set up the options that we'll pass to wpColorPicker().
colorPickerOptions = {
change: function ( event, ui ) {
var key, value, alpha, $transparency;
key = $control.attr( 'data-customize-setting-link' );
value = $control.wpColorPicker( 'color' );
// Set the opacity value on the slider handle when the default color button is clicked.
if ( defaultColor == value ) {
alpha = acp_get_alpha_value_from_color( value );
$alphaSlider.find( '.ui-slider-handle' ).text( alpha );
}
// Send ajax request to wp.customize to trigger the Save action.
wp.customize(key, function ( obj ) {
obj.set( value );
});
$transparency = $container.find( '.transparency' );
// Always show the background color of the opacity slider at 100% opacity.
$transparency.css( 'background-color', ui.color.toString( 'no-alpha' ) );
},
palettes: palette // Use the passed in palette.
};
// Create the colorpicker.
$control.wpColorPicker( colorPickerOptions );
$container = $control.parents( '.wp-picker-container:first' );
// Insert our opacity slider.
$('<div class="alpha-color-picker-container">' +
'<div class="min-click-zone click-zone"></div>' +
'<div class="max-click-zone click-zone"></div>' +
'<div class="alpha-slider"></div>' +
'<div class="transparency"></div>' +
'</div>').appendTo($container.find( '.wp-picker-holder' ) );
$alphaSlider = $container.find( '.alpha-slider' );
// If starting value is in format RGBa, grab the alpha channel.
alphaVal = acp_get_alpha_value_from_color( startingColor );
// Set up jQuery UI slider() options.
sliderOptions = {
create: function ( event, ui ) {
var value = $(this).slider( 'value' );
// Set up initial values.
$( this ).find( '.ui-slider-handle' ).text( value );
$( this ).siblings( '.transparency' ).css( 'background-color', startingColor );
},
value: alphaVal,
range: 'max',
step: 1,
min: 0,
max: 100,
animate: 300
};
// Initialize jQuery UI slider with our options.
$alphaSlider.slider( sliderOptions );
// Maybe show the opacity on the handle.
if ( 'true' === showOpacity ) {
$alphaSlider.find( '.ui-slider-handle' ).addClass( 'show-opacity' );
}
// Bind event handlers for the click zones.
$container.find( '.min-click-zone' ).on( 'click', function () {
acp_update_alpha_value_on_color_control( 0, $control, $alphaSlider, true );
} );
$container.find( '.max-click-zone').on( 'click', function () {
acp_update_alpha_value_on_color_control( 100, $control, $alphaSlider, true );
} );
// Bind event handler for clicking on a palette color.
$container.find( '.iris-palette' ).on( 'click', function () {
var color, alpha;
color = $( this ).css( 'background-color' );
alpha = acp_get_alpha_value_from_color( color );
acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider );
// Sometimes Iris doesn't set a perfect background-color on the palette,
// for example rgba(20, 80, 100, 0.3) becomes rgba(20, 80, 100, 0.298039).
// To compensante for this we round the opacity value on RGBa colors here
// and save it a second time to the color picker object.
if ( alpha != 100 ) {
color = color.replace( /[^,]+(?=\))/, ( alpha / 100 ).toFixed( 2 ) );
}
$control.wpColorPicker( 'color', color );
});
// Bind event handler for clicking on the 'Clear' button.
$container.find( '.button.wp-picker-clear' ).on( 'click', function () {
var key = $control.attr( 'data-customize-setting-link' );
// The #fff color is delibrate here. This sets the color picker to white instead of the
// defult black, which puts the color picker in a better place to visually represent empty.
$control.wpColorPicker('color', '#ffffff');
// Set the actual option value to empty string.
wp.customize( key, function ( obj ) {
obj.set( '' );
} );
acp_update_alpha_value_on_alpha_slider( 100, $alphaSlider );
} );
// Bind event handler for clicking on the 'Default' button.
$container.find( '.button.wp-picker-default' ).on( 'click', function () {
var alpha = acp_get_alpha_value_from_color( defaultColor );
acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider );
} );
// Bind event handler for typing or pasting into the input.
$control.on( 'input', function () {
var value = $( this ).val();
var alpha = acp_get_alpha_value_from_color( value );
acp_update_alpha_value_on_alpha_slider( alpha, $alphaSlider );
} );
// Update all the things when the slider is interacted with.
$alphaSlider.slider().on( 'slide', function ( event, ui ) {
var alpha = parseFloat( ui.value ) / 100.0;
acp_update_alpha_value_on_color_control( alpha, $control, $alphaSlider, false );
// Change value shown on slider handle.
$( this ).find( '.ui-slider-handle').text( ui.value );
});
} );
} );

7
js/customize-controls.js Normal file
View File

@ -0,0 +1,7 @@
wp.customize.sectionConstructor['pressbook-button'] = wp.customize.Section.extend( {
// No events for this type of section.
attachEvents: function() {},
// Always make the section active.
isContextuallyActive: function() { return true; }
} );

77
js/customizer.js Normal file
View File

@ -0,0 +1,77 @@
/* global wp, jQuery */
/**
* File customizer.js.
*
* Theme Customizer enhancements for a better user experience.
*
* Contains handlers to make Theme Customizer preview reload changes asynchronously.
*/
( function( $ ) {
// Site title.
wp.customize( 'blogname', function( value ) {
value.bind( function( to ) {
$( '.site-title > a' ).text( to );
} );
} );
// Site tagline.
wp.customize( 'blogdescription', function( value ) {
value.bind( function( to ) {
$( '.site-tagline' ).text( to );
} );
} );
// Theme CSS output.
var pressbook_css_output, pressbook_prop_value;
$.each( pressbook.styles, function( key, rules ) {
wp.customize( 'set_styles[' + key + ']', function( value ) {
value.bind( function( to ) {
if ( ! $( 'style#pressbook-styles-' + key ).length ) {
$( '<style id="pressbook-styles-' + key + '"></style>' ).insertAfter( '#' + pressbook.handle_id );
}
pressbook_css_output = '';
$.each( rules, function( selector, values ) {
$.each( values, function( prop_key, prop_value ) {
if ( prop_value.remove && prop_value.remove.length ) {
$.each( prop_value.remove, function( remove_style_key, remove_style_id ) {
$( 'style#pressbook-styles-' + remove_style_id ).remove();
} );
}
if ( 'header_bg_position' === key ) {
to = to.replaceAll( '-', ' ' );
}
pressbook_prop_value = prop_value.place.replaceAll( '_PLACE', to );
if ( prop_value.extra && ! $.isEmptyObject( prop_value.extra ) ) {
$.each( prop_value.extra, function( extra_place_key, extra_place ) {
pressbook_prop_value = pressbook_prop_value.replaceAll( extra_place, wp.customize( 'set_styles[' + extra_place_key + ']' ).get() );
} );
}
pressbook_css_output += ( selector + '{' );
pressbook_css_output += ( prop_key + ':' + pressbook_prop_value + ';' );
pressbook_css_output += '}';
} );
} );
$( 'style#pressbook-styles-' + key ).html( pressbook_css_output );
} );
} );
} );
}( jQuery ) );

528
js/script.js Normal file
View File

@ -0,0 +1,528 @@
// Namespace.
var pressbook = pressbook || {};
/**
* Is the DOM ready?
*
* This implementation is coming from https://gomakethings.com/a-native-javascript-equivalent-of-jquerys-ready-method/
*
* @param {Function} fn Callback function to run.
*/
function pressbookDomReady( fn ) {
if ( typeof fn !== 'function' ) {
return;
}
if ( 'interactive' === document.readyState || 'complete' === document.readyState ) {
return fn();
}
document.addEventListener( 'DOMContentLoaded', fn, false );
}
// Animation curves.
Math.easeInOutQuad = function ( t, b, c, d ) {
t /= d / 2;
if ( t < 1 ) return c / 2 * t * t + b;
t--;
return - c / 2 * ( t* ( t-2 ) - 1 ) + b;
};
// Setup main menu.
pressbook.setupMainMenu = {
init: function() {
const mainNav = document.getElementById( 'site-navigation' );
if ( mainNav ) {
const menu = mainNav.getElementsByTagName( 'ul' )[ 0 ]
const toggle = mainNav.querySelector( '.primary-menu-toggle' );
// Hide menu toggle button if menu is empty and return early.
if ( 'undefined' === typeof menu ) {
if ( toggle ) {
toggle.style.display = 'none';
}
return;
}
// Add class 'nav-menu' to the menu.
menu.classList.add( 'nav-menu' );
const arrows = mainNav.querySelectorAll( '.main-navigation-arrow-btn' );
const links = mainNav.querySelectorAll( 'li > a' );
const linksWithoutChildren = mainNav.querySelectorAll( 'li:not(.menu-item-has-children) > a' );
const lastLinksWithoutChildren = mainNav.querySelectorAll( 'li:last-child:not(.menu-item-has-children) > a' );
const searchMenu = mainNav.querySelector( '.primary-menu-search' );
const searchToggle = mainNav.querySelector( '.primary-menu-search-toggle' );
// Add class if touch screen device.
this.toggleTouchClass( mainNav );
// Toggle navigation when the user clicks the menu toggle button.
this.toggleNavigation( toggle, mainNav );
// Collapse menu when the user clicks outside the navigation.
this.collapseIfClickOutside( toggle, mainNav );
// Collapse menu when the user presses the escape key.
this.collapseIfEscapeKeyPress( toggle, mainNav );
// Collapse menu when the user resizes the window.
this.collapseOnResize( toggle, mainNav );
// Toggle sub-menu.
this.toggleSubmenu( arrows, links, linksWithoutChildren, lastLinksWithoutChildren );
// Trap focus in modal.
this.trapFocusInModal( mainNav );
// Toggle search form.
this.toggleSearch( searchToggle, searchMenu );
// Trap focus in search.
this.trapFocusInSearch( searchMenu );
}
},
toggleTouchClass: function( nav ) {
const touchClass = 'main-navigation--touch';
if ( isTouchDevice() ) {
nav.classList.add( touchClass );
}
window.addEventListener( 'resize', function() {
if ( isTouchDevice() ) {
nav.classList.add( touchClass );
} else {
nav.classList.remove( touchClass );
}
} );
function isTouchDevice() {
return ( ( 'ontouchstart' in window ) || ( navigator.maxTouchPoints > 0 ) || ( navigator.msMaxTouchPoints > 0 ) );
}
},
toggleNavigation: function( button, nav ) {
if ( ! button ) {
return;
}
button.addEventListener( 'click', function( event ) {
event.preventDefault();
nav.classList.toggle( 'toggled' );
if ( button ) {
if ( 'true' === button.getAttribute( 'aria-expanded' ) ) {
button.setAttribute( 'aria-expanded', 'false' );
} else {
button.setAttribute( 'aria-expanded', 'true' );
}
}
} );
},
collapseIfClickOutside: function( button, nav ) {
const that = this;
document.addEventListener( 'click', function( event ) {
const isClickInside = nav.contains( event.target );
if ( ! isClickInside ) {
nav.classList.remove( 'toggled' );
if ( button ) {
button.setAttribute( 'aria-expanded', 'false' );
}
// Remove all the focus classes in the ul.
[].forEach.call( nav.querySelectorAll( '.focus' ), function( li ) {
li.classList.remove( 'focus' );
} );
// Set aria-expanded to false.
[].forEach.call( nav.querySelectorAll( '.main-navigation-arrow-btn' ), function( button ) {
button.setAttribute( 'aria-expanded', 'false' );
} );
// Collapse search form.
that.collapseSearchForm( nav );
}
} );
},
collapseIfEscapeKeyPress: function( button, nav ) {
const that = this;
document.addEventListener( 'keyup', function( event ) {
if ( 'Escape' === event.key ) {
nav.classList.remove( 'toggled' );
if ( button ) {
button.setAttribute( 'aria-expanded', 'false' );
}
// Collapse search form.
that.collapseSearchForm( nav );
}
} );
},
collapseOnResize: function( button, nav ) {
window.addEventListener( 'resize', function() {
if ( window.matchMedia( 'screen and (min-width: 768px)' ).matches ) {
nav.classList.remove( 'toggled' );
if ( button ) {
button.setAttribute( 'aria-expanded', 'false' );
}
}
} );
},
toggleSubmenu: function( arrows, links, linksWithoutChildren, lastLinksWithoutChildren ) {
[].forEach.call( arrows, function( arrow ) {
arrow.addEventListener( 'click', toggleFocus );
arrow.addEventListener( 'keydown', toggleSubmenuWithArrow );
} );
[].forEach.call( links, function( link ) {
link.addEventListener( 'focus', closeSubmenuWithLink );
} );
[].forEach.call( linksWithoutChildren, function( link ) {
link.addEventListener( 'focus', openSubmenuWithLink );
} );
[].forEach.call( lastLinksWithoutChildren, function( link ) {
link.addEventListener( 'keydown', closePreviousWithLink );
} );
function toggleFocus() {
var self = this,
addFocusEl = false; // Add focus class to this element.
// Move up through the ancestors of the current arrow button until we hit ul.
while ( 'ul' !== self.tagName.toLowerCase() ) {
// If we hit the first li, then save it in addFocusEl if it does not contain the focus class.
if ( 'li' === self.tagName.toLowerCase() && ! addFocusEl ) {
if ( ! self.classList.contains( 'focus' ) ) {
addFocusEl = self;
}
}
self = self.parentElement;
}
// Remove all the focus classes in the ul.
[].forEach.call( self.querySelectorAll( '.focus' ), function( li ) {
li.classList.remove( 'focus' );
} );
// Set aria-expanded to false.
[].forEach.call( self.querySelectorAll( '.main-navigation-arrow-btn' ), function( button ) {
button.setAttribute( 'aria-expanded', 'false' );
} );
if ( addFocusEl ) {
// Add focus class to addFocusEl.
addFocusEl.classList.add( 'focus' );
// Set aria-expanded to true.
this.setAttribute( 'aria-expanded', 'true' );
}
}
function toggleSubmenuWithArrow( event ) {
const parentEl = this.parentElement,
tabKey = ( 'Tab' === event.key ),
shiftKey = event.shiftKey;
if ( tabKey && shiftKey && parentEl.classList.contains( 'focus' ) ) {
parentEl.classList.remove( 'focus' );
this.setAttribute( 'aria-expanded', 'false' );
} else if ( tabKey && ! shiftKey && ! parentEl.classList.contains( 'focus' ) ) {
parentEl.classList.add( 'focus' );
this.setAttribute( 'aria-expanded', 'true' );
}
}
function closeSubmenuWithLink() {
var self = this,
previousClosed = false;
// Move up through the ancestors of the current link until we hit .nav-menu.
while ( ! self.classList.contains( 'nav-menu' ) ) {
// Close previous sub-menus before opening next.
if ( ! previousClosed && ( 'ul' === self.tagName.toLowerCase() ) ) {
// Remove all the focus classes in the ul.
[].forEach.call( self.querySelectorAll( '.focus' ), function( li ) {
li.classList.remove( 'focus' );
} );
// Set aria-expanded to false.
[].forEach.call( self.querySelectorAll( '.main-navigation-arrow-btn' ), function( button ) {
button.setAttribute( 'aria-expanded', 'false' );
} );
previousClosed = true;
}
self = self.parentElement;
}
}
function openSubmenuWithLink() {
var self = this,
arrow;
// Move up through the ancestors of the current link until we hit .nav-menu.
while ( ! self.classList.contains( 'nav-menu' ) ) {
// On li elements add the class .focus and set aria-expanded to true.
if ( 'li' === self.tagName.toLowerCase() && ! self.classList.contains( 'focus' ) ) {
self.classList.add( 'focus' );
arrow = self.querySelector( '.main-navigation-arrow-btn' );
if ( arrow ) {
this.setAttribute( 'aria-expanded', 'true' );
}
}
self = self.parentElement;
}
}
function closePreviousWithLink( event ) {
var self = this,
nextEl = false,
tabKey = ( 'Tab' === event.key ),
shiftKey = event.shiftKey;
if ( tabKey && ! shiftKey ) {
// Move up through the ancestors of the current link until there is sibling li.
do {
nextEl = ( function( element ) {
do {
element = element.nextSibling;
} while ( element && ( 1 !== element.nodeType ) );
return element;
} ) ( self );
self = self.parentElement;
} while ( ! nextEl );
// Remove all the focus classes in the li.
[].forEach.call( self.querySelectorAll( '.focus' ), function( li ) {
li.classList.remove( 'focus' );
} );
// Set aria-expanded to false.
[].forEach.call( self.querySelectorAll( '.main-navigation-arrow-btn' ), function( button ) {
button.setAttribute( 'aria-expanded', 'false' );
} );
}
}
},
trapFocusInModal: function( nav ) {
document.addEventListener( 'keydown', function( event ) {
if ( ! nav.classList.contains( 'toggled' ) ) {
return;
}
const elements = nav.querySelectorAll( 'input, a, button' );
if ( elements.length < 1 ) {
return;
}
const firstEl = elements[ 0 ],
lastEl = elements[ elements.length - 1 ],
activeEl = document.activeElement,
tabKey = ( 'Tab' === event.key ),
shiftKey = event.shiftKey;
if ( tabKey && ! shiftKey && lastEl === activeEl ) {
event.preventDefault();
firstEl.focus();
}
if ( tabKey && shiftKey && firstEl === activeEl ) {
event.preventDefault();
lastEl.focus();
}
} );
},
toggleSearch: function( toggle, search ) {
if ( ! toggle || ! search ) {
return;
}
toggle.addEventListener( 'click', function( event ) {
event.preventDefault();
search.classList.toggle( 'toggled' );
if ( 'true' === toggle.getAttribute( 'aria-expanded' ) ) {
toggle.setAttribute( 'aria-expanded', 'false' );
} else {
toggle.setAttribute( 'aria-expanded', 'true' );
}
} );
},
collapseSearchForm: function( nav ) {
const search = nav.querySelector( '.primary-menu-search' );
const toggle = nav.querySelector( '.primary-menu-search-toggle' );
if ( search ) {
search.classList.remove( 'toggled' );
}
if ( toggle ) {
toggle.setAttribute( 'aria-expanded', 'false' );
}
},
trapFocusInSearch: function( search ) {
document.addEventListener( 'keydown', function( event ) {
if ( ! search || ! search.classList.contains( 'toggled' ) ) {
return;
}
const toggle = search.querySelector( '.primary-menu-search-toggle' );
if ( 'none' === window.getComputedStyle( toggle, null ).display ) {
return;
}
const elements = search.querySelectorAll( 'input, a, button' );
if ( elements.length < 1 ) {
return;
}
const firstEl = elements[ 0 ],
lastEl = elements[ elements.length - 1 ],
activeEl = document.activeElement,
tabKey = ( 'Tab' === event.key ),
shiftKey = event.shiftKey;
if ( tabKey && ! shiftKey && lastEl === activeEl ) {
event.preventDefault();
firstEl.focus();
}
if ( tabKey && shiftKey && firstEl === activeEl ) {
event.preventDefault();
lastEl.focus();
}
} );
},
}; // pressbook.setupMainMenu
// Go to top.
pressbook.goToTop = {
offset: 300,
offsetOpacity: 1200,
scrollDuration: 700,
init: function() {
const goToTop = document.querySelector( '.go-to-top' );
if ( goToTop ) {
this.handleScroll( goToTop );
this.handleClick( goToTop );
}
},
handleScroll: function( goToTop ) {
var offset = this.offset,
offsetOpacity = this.offsetOpacity,
scrolling = false;
window.addEventListener( 'scroll', function() {
if ( ! scrolling ) {
scrolling = true;
if ( ! window.requestAnimationFrame ) {
setTimeout( toggleOnChangeOffset, 250 );
} else {
window.requestAnimationFrame( toggleOnChangeOffset );
}
}
} );
function toggleOnChangeOffset() {
var windowTop = window.scrollY || document.documentElement.scrollTop;
if ( windowTop > offset ) {
goToTop.classList.add( 'go-to-top--show' )
} else {
goToTop.classList.remove( 'go-to-top--show' );
goToTop.classList.remove( 'go-to-top--fade-out' );
}
if ( windowTop > offsetOpacity ) {
goToTop.classList.add( 'go-to-top--fade-out' );
}
scrolling = false;
};
},
handleClick: function( goToTop ) {
goToTop.addEventListener( 'click', function( event ) {
event.preventDefault();
if ( ! window.requestAnimationFrame ) {
window.scrollTo( 0, 0 )
} else {
scrollTo( 0, this.scrollDuration );
}
goToTop.blur();
}.bind( this ) );
// Smooth scroll.
function scrollTo( final, duration, cb ) {
var start = window.scrollY || document.documentElement.scrollTop,
currentTime = null;
var animateScroll = function( timestamp ) {
if ( ! currentTime ) {
currentTime = timestamp;
}
var progress = timestamp - currentTime;
if ( progress > duration ) {
progress = duration;
}
var val = Math.easeInOutQuad( progress, start, final - start, duration );
window.scrollTo( 0, val );
if ( progress < duration ) {
window.requestAnimationFrame( animateScroll );
} else {
cb && cb();
}
};
window.requestAnimationFrame( animateScroll );
};
}
}; // pressbook.goToTop
pressbookDomReady( function() {
pressbook.setupMainMenu.init(); // Setup main menu.
pressbook.goToTop.init(); // Setup go to top.
} );

1
js/script.min.js vendored Normal file

File diff suppressed because one or more lines are too long

707
js/sticky-sidebar.js Normal file
View File

@ -0,0 +1,707 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.StickySidebar = {})));
}(this, (function (exports) { 'use strict';
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function unwrapExports (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var stickySidebar = createCommonjsModule(function (module, exports) {
(function (global, factory) {
if (typeof undefined === "function" && undefined.amd) {
undefined(['exports'], factory);
} else {
factory(exports);
}
})(commonjsGlobal, function (exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
/**
* Sticky Sidebar v2 JavaScript Plugin.
* @version 1.0.1
* @author Øystein Blixhavn <oystein@blixhavn.no>
* @license The MIT License (MIT)
*/
var StickySidebar = function () {
// ---------------------------------
// # Define Constants
// ---------------------------------
//
var EVENT_KEY = '.stickySidebar';
var DEFAULTS = {
/**
* Additional top spacing of the element when it becomes sticky.
* @type {Numeric|Function}
*/
topSpacing: 0,
/**
* Additional bottom spacing of the element when it becomes sticky.
* @type {Numeric|Function}
*/
bottomSpacing: 0,
/**
* Container sidebar selector to know what the beginning and end of sticky element.
* @type {String|False}
*/
containerSelector: false,
/**
* Parent element where the scrolling happens.
*/
scrollContainer: false,
/**
* Inner wrapper selector.
* @type {String}
*/
innerWrapperSelector: '.inner-wrapper-sticky',
/**
* The name of CSS class to apply to elements when they have become stuck.
* @type {String|False}
*/
stickyClass: 'is-affixed',
/**
* Detect when sidebar and its container change height so re-calculate their dimensions.
* @type {Boolean}
*/
resizeSensor: true,
/**
* The sidebar returns to its normal position if its width below this value.
* @type {Numeric}
*/
minWidth: false
};
// ---------------------------------
// # Class Definition
// ---------------------------------
//
/**
* Sticky Sidebar Class.
* @public
*/
var StickySidebar = function () {
/**
* Sticky Sidebar Constructor.
* @constructor
* @param {HTMLElement|String} sidebar - The sidebar element or sidebar selector.
* @param {Object} options - The options of sticky sidebar.
*/
function StickySidebar(sidebar) {
var _this = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, StickySidebar);
this.options = StickySidebar.extend(DEFAULTS, options);
// Sidebar element query if there's no one, throw error.
this.sidebar = 'string' === typeof sidebar ? document.querySelector(sidebar) : sidebar;
if ('undefined' === typeof this.sidebar) throw new Error("There is no specific sidebar element.");
this.sidebarInner = false;
this.container = this.sidebar.parentElement;
// Current Affix Type of sidebar element.
this.affixedType = 'STATIC';
this.direction = 'down';
this.support = {
transform: false,
transform3d: false
};
this._initialized = false;
this._reStyle = false;
this._breakpoint = false;
// Dimensions of sidebar, container and screen viewport.
this.dimensions = {
translateY: 0,
maxTranslateY: 0,
topSpacing: 0,
lastTopSpacing: 0,
bottomSpacing: 0,
lastBottomSpacing: 0,
sidebarHeight: 0,
sidebarWidth: 0,
containerTop: 0,
containerHeight: 0,
viewportHeight: 0,
viewportTop: 0,
lastViewportTop: 0
};
// Bind event handlers for referencability.
['handleEvent'].forEach(function (method) {
_this[method] = _this[method].bind(_this);
});
// Initialize sticky sidebar for first time.
this.initialize();
}
/**
* Initializes the sticky sidebar by adding inner wrapper, define its container,
* min-width breakpoint, calculating dimensions, adding helper classes and inline style.
* @private
*/
_createClass(StickySidebar, [{
key: 'initialize',
value: function initialize() {
var _this2 = this;
this._setSupportFeatures();
// Get sticky sidebar inner wrapper, if not found, will create one.
if (this.options.innerWrapperSelector) {
this.sidebarInner = this.sidebar.querySelector(this.options.innerWrapperSelector);
if (null === this.sidebarInner) this.sidebarInner = false;
}
if (!this.sidebarInner) {
var wrapper = document.createElement('div');
wrapper.setAttribute('class', 'inner-wrapper-sticky');
this.sidebar.appendChild(wrapper);
while (this.sidebar.firstChild != wrapper) {
wrapper.appendChild(this.sidebar.firstChild);
}this.sidebarInner = this.sidebar.querySelector('.inner-wrapper-sticky');
}
// Container wrapper of the sidebar.
if (this.options.containerSelector) {
var containers = document.querySelectorAll(this.options.containerSelector);
containers = Array.prototype.slice.call(containers);
containers.forEach(function (container, item) {
if (!container.contains(_this2.sidebar)) return;
_this2.container = container;
});
if (!containers.length) throw new Error("The container does not contains on the sidebar.");
}
// Get scroll container, if provided
this.scrollContainer = this.options.scrollContainer ? document.querySelector(this.options.scrollContainer) : undefined;
// If top/bottom spacing is not function parse value to integer.
if ('function' !== typeof this.options.topSpacing) this.options.topSpacing = parseInt(this.options.topSpacing) || 0;
if ('function' !== typeof this.options.bottomSpacing) this.options.bottomSpacing = parseInt(this.options.bottomSpacing) || 0;
// Breakdown sticky sidebar if screen width below `options.minWidth`.
this._widthBreakpoint();
// Calculate dimensions of sidebar, container and viewport.
this.calcDimensions();
// Affix sidebar in proper position.
this.stickyPosition();
// Bind all events.
this.bindEvents();
// Inform other properties the sticky sidebar is initialized.
this._initialized = true;
}
}, {
key: 'bindEvents',
value: function bindEvents() {
this.eventTarget = this.scrollContainer ? this.scrollContainer : window;
this.eventTarget.addEventListener('resize', this, { passive: true, capture: false });
this.eventTarget.addEventListener('scroll', this, { passive: true, capture: false });
this.sidebar.addEventListener('update' + EVENT_KEY, this);
if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) {
new ResizeSensor(this.sidebarInner, this.handleEvent);
new ResizeSensor(this.container, this.handleEvent);
}
}
}, {
key: 'handleEvent',
value: function handleEvent(event) {
this.updateSticky(event);
}
}, {
key: 'calcDimensions',
value: function calcDimensions() {
if (this._breakpoint) return;
var dims = this.dimensions;
// Container of sticky sidebar dimensions.
dims.containerTop = StickySidebar.offsetRelative(this.container).top;
dims.containerHeight = this.container.clientHeight;
dims.containerBottom = dims.containerTop + dims.containerHeight;
// Sidebar dimensions.
dims.sidebarHeight = this.sidebarInner.offsetHeight;
dims.sidebarWidth = this.sidebarInner.offsetWidth;
// Screen viewport dimensions.
dims.viewportHeight = window.innerHeight;
// Maximum sidebar translate Y.
dims.maxTranslateY = dims.containerHeight - dims.sidebarHeight;
this._calcDimensionsWithScroll();
}
}, {
key: '_calcDimensionsWithScroll',
value: function _calcDimensionsWithScroll() {
var dims = this.dimensions;
dims.sidebarLeft = StickySidebar.offsetRelative(this.sidebar).left;
if (this.scrollContainer) {
dims.viewportTop = this.scrollContainer.scrollTop;
dims.viewportLeft = this.scrollContainer.scrollLeft;
} else {
dims.viewportTop = document.documentElement.scrollTop || document.body.scrollTop;
dims.viewportLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
}
dims.viewportBottom = dims.viewportTop + dims.viewportHeight;
dims.topSpacing = this.options.topSpacing;
dims.bottomSpacing = this.options.bottomSpacing;
if ('function' === typeof dims.topSpacing) dims.topSpacing = parseInt(dims.topSpacing(this.sidebar)) || 0;
if ('function' === typeof dims.bottomSpacing) dims.bottomSpacing = parseInt(dims.bottomSpacing(this.sidebar)) || 0;
if ('VIEWPORT-TOP' === this.affixedType) {
// Adjust translate Y in the case decrease top spacing value.
if (dims.topSpacing < dims.lastTopSpacing) {
dims.translateY += dims.lastTopSpacing - dims.topSpacing;
this._reStyle = true;
}
} else if ('VIEWPORT-BOTTOM' === this.affixedType) {
// Adjust translate Y in the case decrease bottom spacing value.
if (dims.bottomSpacing < dims.lastBottomSpacing) {
dims.translateY += dims.lastBottomSpacing - dims.bottomSpacing;
this._reStyle = true;
}
}
dims.lastTopSpacing = dims.topSpacing;
dims.lastBottomSpacing = dims.bottomSpacing;
}
}, {
key: 'isSidebarFitsViewport',
value: function isSidebarFitsViewport() {
var dims = this.dimensions;
var offset = this.scrollDirection === 'down' ? dims.lastBottomSpacing : dims.lastTopSpacing;
return this.dimensions.sidebarHeight + offset < this.dimensions.viewportHeight;
}
}, {
key: 'observeScrollDir',
value: function observeScrollDir() {
var dims = this.dimensions;
if (dims.lastViewportTop === dims.viewportTop) return;
var furthest = 'down' === this.direction ? Math.min : Math.max;
// If the browser is scrolling not in the same direction.
if (dims.viewportTop === furthest(dims.viewportTop, dims.lastViewportTop)) this.direction = 'down' === this.direction ? 'up' : 'down';
}
}, {
key: 'getAffixType',
value: function getAffixType() {
this._calcDimensionsWithScroll();
var dims = this.dimensions;
var colliderTop = dims.viewportTop + dims.topSpacing;
var affixType = this.affixedType;
if (colliderTop <= dims.containerTop || dims.containerHeight <= dims.sidebarHeight) {
dims.translateY = 0;
affixType = 'STATIC';
} else {
affixType = 'up' === this.direction ? this._getAffixTypeScrollingUp() : this._getAffixTypeScrollingDown();
}
// Make sure the translate Y is not bigger than container height.
dims.translateY = Math.max(0, dims.translateY);
dims.translateY = Math.min(dims.containerHeight, dims.translateY);
dims.translateY = Math.round(dims.translateY);
dims.lastViewportTop = dims.viewportTop;
return affixType;
}
}, {
key: '_getAffixTypeScrollingDown',
value: function _getAffixTypeScrollingDown() {
var dims = this.dimensions;
var sidebarBottom = dims.sidebarHeight + dims.containerTop;
var colliderTop = dims.viewportTop + dims.topSpacing;
var colliderBottom = dims.viewportBottom - dims.bottomSpacing;
var affixType = this.affixedType;
if (this.isSidebarFitsViewport()) {
if (dims.sidebarHeight + colliderTop >= dims.containerBottom) {
dims.translateY = dims.containerBottom - sidebarBottom;
affixType = 'CONTAINER-BOTTOM';
} else if (colliderTop >= dims.containerTop) {
dims.translateY = colliderTop - dims.containerTop;
affixType = 'VIEWPORT-TOP';
}
} else {
if (dims.containerBottom <= colliderBottom) {
dims.translateY = dims.containerBottom - sidebarBottom;
affixType = 'CONTAINER-BOTTOM';
} else if (sidebarBottom + dims.translateY <= colliderBottom) {
dims.translateY = colliderBottom - sidebarBottom;
affixType = 'VIEWPORT-BOTTOM';
} else if (dims.containerTop + dims.translateY <= colliderTop && 0 !== dims.translateY && dims.maxTranslateY !== dims.translateY) {
affixType = 'VIEWPORT-UNBOTTOM';
}
}
return affixType;
}
}, {
key: '_getAffixTypeScrollingUp',
value: function _getAffixTypeScrollingUp() {
var dims = this.dimensions;
var sidebarBottom = dims.sidebarHeight + dims.containerTop;
var colliderTop = dims.viewportTop + dims.topSpacing;
var colliderBottom = dims.viewportBottom - dims.bottomSpacing;
var affixType = this.affixedType;
if (colliderTop <= dims.translateY + dims.containerTop) {
dims.translateY = colliderTop - dims.containerTop;
affixType = 'VIEWPORT-TOP';
} else if (dims.containerBottom <= colliderBottom) {
dims.translateY = dims.containerBottom - sidebarBottom;
affixType = 'CONTAINER-BOTTOM';
} else if (!this.isSidebarFitsViewport()) {
if (dims.containerTop <= colliderTop && 0 !== dims.translateY && dims.maxTranslateY !== dims.translateY) {
affixType = 'VIEWPORT-UNBOTTOM';
}
}
return affixType;
}
}, {
key: '_getStyle',
value: function _getStyle(affixType) {
if ('undefined' === typeof affixType) return;
var style = { inner: {}, outer: {} };
var dims = this.dimensions;
switch (affixType) {
case 'VIEWPORT-TOP':
style.inner = { position: 'fixed', top: dims.topSpacing,
left: dims.sidebarLeft - dims.viewportLeft, width: dims.sidebarWidth };
break;
case 'VIEWPORT-BOTTOM':
style.inner = { position: 'fixed', top: 'auto', left: dims.sidebarLeft,
bottom: dims.bottomSpacing, width: dims.sidebarWidth };
break;
case 'CONTAINER-BOTTOM':
case 'VIEWPORT-UNBOTTOM':
var translate = this._getTranslate(0, dims.translateY + 'px');
if (translate) style.inner = { transform: translate };else style.inner = { position: 'absolute', top: dims.translateY, width: dims.sidebarWidth };
break;
}
switch (affixType) {
case 'VIEWPORT-TOP':
case 'VIEWPORT-BOTTOM':
case 'VIEWPORT-UNBOTTOM':
case 'CONTAINER-BOTTOM':
style.outer = { height: dims.sidebarHeight, position: 'relative' };
break;
}
style.outer = StickySidebar.extend({ height: '', position: '' }, style.outer);
style.inner = StickySidebar.extend({ position: 'relative', top: '', left: '',
bottom: '', width: '', transform: '' }, style.inner);
return style;
}
}, {
key: 'stickyPosition',
value: function stickyPosition(force) {
if (this._breakpoint) return;
force = this._reStyle || force || false;
var offsetTop = this.options.topSpacing;
var offsetBottom = this.options.bottomSpacing;
var affixType = this.getAffixType();
var style = this._getStyle(affixType);
if ((this.affixedType != affixType || force) && affixType) {
var affixEvent = 'affix.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY;
StickySidebar.eventTrigger(this.sidebar, affixEvent);
if ('STATIC' === affixType) StickySidebar.removeClass(this.sidebar, this.options.stickyClass);else StickySidebar.addClass(this.sidebar, this.options.stickyClass);
for (var key in style.outer) {
var unit = 'number' === typeof style.outer[key] ? 'px' : '';
this.sidebar.style[key] = style.outer[key] + unit;
}
for (var _key in style.inner) {
var _unit = 'number' === typeof style.inner[_key] ? 'px' : '';
this.sidebarInner.style[_key] = style.inner[_key] + _unit;
}
var affixedEvent = 'affixed.' + affixType.toLowerCase().replace('viewport-', '') + EVENT_KEY;
StickySidebar.eventTrigger(this.sidebar, affixedEvent);
} else {
if (this._initialized) this.sidebarInner.style.left = style.inner.left;
}
this.affixedType = affixType;
}
}, {
key: '_widthBreakpoint',
value: function _widthBreakpoint() {
if (window.innerWidth <= this.options.minWidth) {
this._breakpoint = true;
this.affixedType = 'STATIC';
this.sidebar.removeAttribute('style');
StickySidebar.removeClass(this.sidebar, this.options.stickyClass);
this.sidebarInner.removeAttribute('style');
} else {
this._breakpoint = false;
}
}
}, {
key: 'updateSticky',
value: function updateSticky() {
var _this3 = this;
var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (this._running) return;
this._running = true;
(function (eventType) {
requestAnimationFrame(function () {
switch (eventType) {
// When browser is scrolling and re-calculate just dimensions
// within scroll.
case 'scroll':
_this3._calcDimensionsWithScroll();
_this3.observeScrollDir();
_this3.stickyPosition();
break;
// When browser is resizing or there's no event, observe width
// breakpoint and re-calculate dimensions.
case 'resize':
default:
_this3._widthBreakpoint();
_this3.calcDimensions();
_this3.stickyPosition(true);
break;
}
_this3._running = false;
});
})(event.type);
}
}, {
key: '_setSupportFeatures',
value: function _setSupportFeatures() {
var support = this.support;
support.transform = StickySidebar.supportTransform();
support.transform3d = StickySidebar.supportTransform(true);
}
}, {
key: '_getTranslate',
value: function _getTranslate() {
var y = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
if (this.support.transform3d) return 'translate3d(' + y + ', ' + x + ', ' + z + ')';else if (this.support.translate) return 'translate(' + y + ', ' + x + ')';else return false;
}
}, {
key: 'destroy',
value: function destroy() {
window.removeEventListener('resize', this, { capture: false });
window.removeEventListener('scroll', this, { capture: false });
this.sidebar.classList.remove(this.options.stickyClass);
this.sidebar.style.minHeight = '';
this.sidebar.removeEventListener('update' + EVENT_KEY, this);
var styleReset = { inner: {}, outer: {} };
styleReset.inner = { position: '', top: '', left: '', bottom: '', width: '', transform: '' };
styleReset.outer = { height: '', position: '' };
for (var key in styleReset.outer) {
this.sidebar.style[key] = styleReset.outer[key];
}for (var _key2 in styleReset.inner) {
this.sidebarInner.style[_key2] = styleReset.inner[_key2];
}if (this.options.resizeSensor && 'undefined' !== typeof ResizeSensor) {
ResizeSensor.detach(this.sidebarInner, this.handleEvent);
ResizeSensor.detach(this.container, this.handleEvent);
}
}
}], [{
key: 'supportTransform',
value: function supportTransform(transform3d) {
var result = false,
property = transform3d ? 'perspective' : 'transform',
upper = property.charAt(0).toUpperCase() + property.slice(1),
prefixes = ['Webkit', 'Moz', 'O', 'ms'],
support = document.createElement('support'),
style = support.style;
(property + ' ' + prefixes.join(upper + ' ') + upper).split(' ').forEach(function (property, i) {
if (style[property] !== undefined) {
result = property;
return false;
}
});
return result;
}
}, {
key: 'eventTrigger',
value: function eventTrigger(element, eventName, data) {
try {
var event = new CustomEvent(eventName, { detail: data });
} catch (e) {
var event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName, true, true, data);
}
element.dispatchEvent(event);
}
}, {
key: 'extend',
value: function extend(defaults, options) {
var results = {};
for (var key in defaults) {
if ('undefined' !== typeof options[key]) results[key] = options[key];else results[key] = defaults[key];
}
return results;
}
}, {
key: 'offsetRelative',
value: function offsetRelative(element) {
var result = { left: 0, top: 0 };
do {
var offsetTop = element.offsetTop;
var offsetLeft = element.offsetLeft;
if (!isNaN(offsetTop)) result.top += offsetTop;
if (!isNaN(offsetLeft)) result.left += offsetLeft;
element = 'BODY' === element.tagName ? element.parentElement : element.offsetParent;
} while (element);
return result;
}
}, {
key: 'addClass',
value: function addClass(element, className) {
if (!StickySidebar.hasClass(element, className)) {
if (element.classList) element.classList.add(className);else element.className += ' ' + className;
}
}
}, {
key: 'removeClass',
value: function removeClass(element, className) {
if (StickySidebar.hasClass(element, className)) {
if (element.classList) element.classList.remove(className);else element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
}
}
}, {
key: 'hasClass',
value: function hasClass(element, className) {
if (element.classList) return element.classList.contains(className);else return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className);
}
}, {
key: 'defaults',
get: function () {
return DEFAULTS;
}
}]);
return StickySidebar;
}();
return StickySidebar;
}();
exports.default = StickySidebar;
// Global
// -------------------------
window.StickySidebar = StickySidebar;
});
});
var stickySidebar$1 = unwrapExports(stickySidebar);
exports['default'] = stickySidebar$1;
exports.__moduleExports = stickySidebar;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=sticky-sidebar.js.map

1
js/sticky-sidebar.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,21 @@
#How to use the pot file#
The pot file included in this folder is ready to use.
1. Start up Poedit.
2. In Poedit goto File -> New from POT/PO file...
3. Select and Open the pot file from the languages folder.
4. Enter your name, email address, your language and country (i.e. French fr_FR, German de_DE) to the setting form.
5. Click the Update button in the main Poedit UI.
6. Save the file:
- For a plugin like filename-xx_XX.po with xx_XX for your language and country.
- For a theme xx_XX.po
7. That's it, go to your WordPress blog and see your translation in action. N'joy your blogging!!!
Thank you for your contribution.

BIN
languages/hi_IN.mo Normal file

Binary file not shown.

1808
languages/hi_IN.po Normal file

File diff suppressed because it is too large Load Diff

1690
languages/pressbook.pot Normal file

File diff suppressed because it is too large Load Diff

339
license.txt Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

34
page-templates/full.php Normal file
View File

@ -0,0 +1,34 @@
<?php
/**
* Template Name: Full width template
*
* @package PressBook
*/
$pressbook_settings = PressBook\PageSettings::get_meta_config( get_the_ID() );
get_header();
?>
<div class="pb-content-sidebar<?php echo esc_attr( $pressbook_settings['wrapper_class'] ); ?>">
<main id="primary" class="site-main<?php echo esc_attr( $pressbook_settings['site_main_class'] ); ?>">
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', $pressbook_settings['page_content'] );
}
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
}
?>
</main><!-- #primary -->
</div><!-- .pb-content-sidebar -->
<?php
get_footer();

34
page-templates/large.php Normal file
View File

@ -0,0 +1,34 @@
<?php
/**
* Template Name: Large width template
*
* @package PressBook
*/
$pressbook_settings = PressBook\PageSettings::get_meta_config( get_the_ID() );
get_header();
?>
<div class="pb-content-sidebar u-wrapper<?php echo esc_attr( $pressbook_settings['wrapper_class'] ); ?>">
<main id="primary" class="site-main<?php echo esc_attr( $pressbook_settings['site_main_class'] ); ?>">
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', $pressbook_settings['page_content'] );
}
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
}
?>
</main><!-- #primary -->
</div><!-- .pb-content-sidebar -->
<?php
get_footer();

34
page-templates/medium.php Normal file
View File

@ -0,0 +1,34 @@
<?php
/**
* Template Name: Medium width template
*
* @package PressBook
*/
$pressbook_settings = PressBook\PageSettings::get_meta_config( get_the_ID() );
get_header();
?>
<div class="pb-content-sidebar u-wrapper<?php echo esc_attr( $pressbook_settings['wrapper_class'] ); ?>">
<main id="primary" class="site-main<?php echo esc_attr( $pressbook_settings['site_main_class'] ); ?>">
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', $pressbook_settings['page_content'] );
}
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
}
?>
</main><!-- #primary -->
</div><!-- .pb-content-sidebar -->
<?php
get_footer();

View File

@ -0,0 +1,39 @@
<?php
/**
* Template Name: Page with sidebar
*
* @package PressBook
*/
$pressbook_settings = PressBook\PageSettings::get_meta_config( get_the_ID() );
get_header();
?>
<div class="pb-content-sidebar u-wrapper<?php echo esc_attr( $pressbook_settings['wrapper_class'] ); ?>">
<main id="primary" class="site-main<?php echo esc_attr( $pressbook_settings['site_main_class'] ); ?>">
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', $pressbook_settings['page_content'] );
}
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
}
?>
</main><!-- #primary -->
<?php
get_sidebar( 'left' );
get_sidebar();
?>
</div><!-- .pb-content-sidebar -->
<?php
get_footer();

34
page-templates/small.php Normal file
View File

@ -0,0 +1,34 @@
<?php
/**
* Template Name: Small width template
*
* @package PressBook
*/
$pressbook_settings = PressBook\PageSettings::get_meta_config( get_the_ID() );
get_header();
?>
<div class="pb-content-sidebar u-wrapper<?php echo esc_attr( $pressbook_settings['wrapper_class'] ); ?>">
<main id="primary" class="site-main<?php echo esc_attr( $pressbook_settings['site_main_class'] ); ?>">
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', $pressbook_settings['page_content'] );
}
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
}
?>
</main><!-- #primary -->
</div><!-- .pb-content-sidebar -->
<?php
get_footer();

41
page.php Normal file
View File

@ -0,0 +1,41 @@
<?php
/**
* The template for displaying all pages.
*
* This is the template that displays all pages by default.
* Please note that this is the WordPress construct of pages
* and that other 'pages' on your WordPress site may use a
* different template.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package PressBook
*/
$pressbook_settings = PressBook\PageSettings::get_meta_config( get_the_ID() );
get_header();
?>
<div class="pb-content-sidebar u-wrapper<?php echo esc_attr( $pressbook_settings['wrapper_class'] ); ?>">
<main id="primary" class="site-main<?php echo esc_attr( $pressbook_settings['site_main_class'] ); ?>">
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', $pressbook_settings['page_content'] );
}
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
}
?>
</main><!-- #primary -->
</div><!-- .pb-content-sidebar -->
<?php
get_footer();

397
readme.txt Normal file
View File

@ -0,0 +1,397 @@
=== CookTheBooks ===
Contributors: Sophia Atkinson
Tags: blog, education, news, one-column, two-columns, three-columns, left-sidebar, right-sidebar, block-styles, custom-background, custom-colors, custom-header, custom-logo, custom-menu, editor-style, featured-images, flexible-header, footer-widgets, full-width-template, rtl-language-support, sticky-post, theme-options, threaded-comments, translation-ready, wide-blocks
Donate link: https://sophia.wtf/
Requires at least: 5.3
Tested up to: 6.3
Requires PHP: 7.0
Stable tag: 1.0B
License: CC BY-SA 4.0
License URI: https://creativecommons.org/licenses/by-sa/4.0/
CookTheBooks is a multi-purpose WordPress theme suitable for blogs, news, marketing, and educational websites.
== Description ==
CookTheBooks is a multi-purpose WordPress theme suitable for blogs, news, marketing, and educational websites. The theme offers a fully responsive, clean, modern, and pixel-perfect design that can adjust automatically to fit the content elements in the best possible manner for any screen-size device. It has a minimal dependency, an SEO-friendly layout, and offers high performance with a quick loading time. It supports double sidebars, a single sidebar, footer widgets, an eye-catching gradient colors scheme for buttons and the top bar, a top advertisement banner area with a custom header background, and customizable options. Both the sidebars can be configured to be shown on the left or on the right. This theme is great to publish documentation, tutorials, events, status updates, story updates, technology blogs, reviews, newsfeeds, etc. It comes with sticky sidebars that float with scrolling. The theme supports multiple page templates with page-level layout settings, blog layouts, conditional block areas, page builders, different color settings, footer options, and much more. Also, the theme comes with three menu locations which include a fully accessible multi-level primary menu with a search form, a top bar navigation menu, and social links menu. It is also great for building schools, university, institutes, and academic, or educational websites.
== Installation ==
1. In your admin panel, go to Appearance > Themes and click the Add New button.
2. Click Upload Theme and Choose File, then select the theme's .zip file. Click Install Now.
3. Click Activate to use your new theme right away.
== Frequently Asked Questions ==
= Does this theme support any plugins? =
CookTheBooks includes support for WooCommerce and for Infinite Scroll in Jetpack.
= Where to find the theme options? =
All of the options can be found in the Customizer in 'Appearance > Customize'.
= How to configure the theme widgets? =
The theme widgets can be found in 'Appearance > Widgets'. You can drag and drop widgets to the widget area. CookTheBooks comes with 6 widgets area locations which include a left sidebar, right sidebar widgets area and 4 locations for footer widgets.
= How to add the menus or social links? =
The menus can be found in 'Appearance > Menus'. First, create the menu and then assign it to a menu location. CookTheBooks comes with three menu locations which include the primary menu, top bar menu, and social links menu. For social links, create a menu item with a custom link, enter the URL of the social page, and assign this menu to the 'Social Links Menu' location.
== Copyright ==
CookTheBooks is distributed under the terms of the GNU GPL.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
== Changelog ==
= 1.0B =
* Added: New SVG social icons.
= 1.9.0 =
* Improvement: Editor styles fixes.
= 1.8.9 =
* Added: New SVG social icons.
= 1.8.8 =
* Fixed issues related to version 1.8.6.
= 1.8.7 =
* Reverted changes of version 1.8.6.
= 1.8.6 =
* Updated webfonts loader library.
* Renamed reusable blocks to patterns.
* Improvement: Minor CSS fixes.
* Tested up to 6.3.
= 1.8.5 =
* Added: New SVG social icons.
= 1.8.4 =
* Improvement: Minor CSS fixes.
= 1.8.3 =
* Improvement: Removed JS deprecations.
= 1.8.2 =
* Improvement: Minor CSS fixes.
* Readme updated.
= 1.8.1 =
* Improvement: Minor CSS fixes.
= 1.8.0 =
* Readme updated.
= 1.7.9 =
* Improvement: SVG icons.
= 1.7.8 =
* Readme updated.
* Updated plugins recommendation list.
= 1.7.7 =
* Improvement: Added label to primary menu toggle button.
= 1.7.6 =
* Added: Support for custom line height controls.
= 1.7.5 =
* Added: Support for more social link SVG icons.
= 1.7.4 =
* Tested up to 6.1.
= 1.7.3 =
* Improvement: Editor CSS fixes.
= 1.7.2 =
* Improvement: Minor CSS fixes.
= 1.7.1 =
* New: Option to show or hide archive page title.
= 1.7.0 =
* New: Added option to use any custom blocks in the top banner section.
= 1.6.8 =
* Readme updated.
= 1.6.7 =
* Improvement: Minor CSS fixes.
* Improvement: Readme updated.
= 1.6.6 =
* Bug fix: Locally load fonts in the editor.
= 1.6.5 =
* Locally host Google fonts.
= 1.6.4 =
* Improvement: Minor CSS fixes.
= 1.6.3 =
* Changed "Requires PHP" tag to 7.0.
* Updated plugins recommendation list.
= 1.6.2 =
* Tested up to 6.0.
= 1.6.1 =
* Improvement: Minor CSS fixes.
= 1.6.0 =
* Improvement: Added theme support for padding controls.
= 1.5.9 =
* Updated plugins recommendation list.
= 1.5.8 =
* Improvement: Welcome page FAQ link removed.
= 1.5.7 =
* Improvement: Check for Jetpack before adding theme support.
= 1.5.6 =
* Improvement: Welcome page styles.
* Improvement: Fixed typos in welcome page.
= 1.5.5 =
* Improvement: Welcome page updated.
= 1.5.4 =
* Improvement: Reduced z-index of submenu for compatibility with "Dark Mode Toggle" plugin.
= 1.5.3 =
* New: "Dark Mode Toggle" added to plugin recommendation list.
= 1.5.2 =
* Improvement: Added more utility CSS classes.
= 1.5.1 =
* Improvement: Minor CSS fixes.
= 1.5.0 =
* Removed unused CSS.
= 1.4.6 =
* Tested up to 5.9.
= 1.4.5 =
* Improvement: Minor CSS fixes.
= 1.4.4 =
* Improvement: Minor CSS fixes.
* Improvement: Block styles.
= 1.4.3 =
* Improvement: Minor CSS fixes.
= 1.4.2 =
* Added: Styles for default colors and font sizes.
= 1.4.1 =
* Theme version incremented to 1.4.1.
= 1.4.0 =
* Improvement: Minor CSS fixes.
= 1.3.9 =
* Improvement: Added h1 title in archive and search pages for screen readers.
= 1.3.8 =
* Theme version incremented to 1.3.8.
= 1.3.7 =
* Improvement: Block social links style in widget areas.
= 1.3.6 =
* Improvement: Removed 100% height for input fields.
= 1.3.5 =
* Added: Option to hide the go to top button.
= 1.3.4 =
* Improvement: Welcome page updated.
= 1.3.3 =
* Added: Featured label text option for the sticky posts.
* Added: Double Sidebars layout options.
= 1.3.2 =
* Improvement: Widgets editor style.
= 1.3.1 =
* Added: Widgets editor style.
= 1.3.0 =
* Improvement: Removed editor styles from block widgets screen.
= 1.2.8 =
* Tested up to 5.8.
= 1.2.7 =
* Bug fix: Widget search form max width.
= 1.2.6 =
* Bug fix: Make anchor link inherit color of paragraph text color.
= 1.2.5 =
* Improvement: Styling of widget block title.
* Improvement: Styling of widget search block.
= 1.2.4 =
* Improvement: Fixed menu dropdown arrow alignment to center.
* Improvement: Welcome page updated.
= 1.2.3 =
* New: Options to show/hide the post categories and tags.
= 1.2.2 =
* Improvement: Added context to translation functions.
* Improvement: Minor fixes.
= 1.2.1 =
* Improvement: Description on the usage of block sections.
* Improvement: Minor CSS fixes.
* Improvement: Fixed typos.
= 1.2.0 =
* Improvement: Easily override CSSRules class in child theme with late static binding.
* Improvement: Minor CSS fixes.
* New: Footer credit link color option.
= 1.1.9 =
* Improvement: Fixed typos.
= 1.1.8 =
* Improvement: Menu search form minimum and maximum width.
= 1.1.7 =
* New: Added new option to change the "Read More" text.
= 1.1.6 =
* New: Added new option to hide post meta data.
* New: Added new option to show post excerpt or full content.
= 1.1.5 =
* Improvement: Minor CSS adjustments.
* New: Added button gradient color options.
= 1.1.4 =
* New: Added "Getwid Gutenberg Blocks" in the list of recommended plugins.
= 1.1.3 =
* Improvement: Removed block width in the editor.
= 1.1.2 =
* Bug fix: Compatibility with page builder plugins.
= 1.1.1 =
* New: Added option to change the search form button text.
= 1.1.0 =
* Improvement: Welcome page updated.
* Improvement: Push footer to the bottom when there is less content.
= 1.0.6 =
* Theme screenshot updated.
= 1.0.5 =
* Better accessibility for widgets with lists of links.
* Tested up to 5.7.
= 1.0.4 =
* New release.
== Credits ==
CookTheBooks bundles the following third-party resources:
* Image 1 for theme screenshot, Copyright Helloquence
* License: Creative Commons CC0 license
* License URI: https://stocksnap.io/license
* Source: https://stocksnap.io/photo/Y01VDYAX63
* Image 2 for theme screenshot, Copyright Dan Gold
* License: Creative Commons CC0 license
* License URI: https://stocksnap.io/license
* Source: https://stocksnap.io/photo/PQBKOX33PD
* Image 3 for theme screenshot, Copyright Denis Linine
* License: Creative Commons CC0 license
* License URI: https://stocksnap.io/license
* Source: https://stocksnap.io/photo/RSJHQZIRHO
* Social Icons
* License: GNU General Public License v2 or later
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
* Source: WordPress Social Link Block (See wp-includes\blocks\social-link.php)
Code from Twenty Nineteen, Copyright WordPress.org
License: GPLv2
Source: https://wordpress.org/themes/twentynineteen/
Included as part of the following classes and functions:
- CookTheBooks\Icons
- CookTheBooks\IconsHelper::get_icon_svg()
- CookTheBooks\IconsHelper::get_social_icon_svg()
- CookTheBooks\IconsHelper::get_social_link_svg()
- CookTheBooks\IconsHelper::nav_menu_social_icons()
Code from Twenty Twenty, Copyright WordPress.org
License: GPLv2
Source: https://wordpress.org/themes/twentytwenty/
Included as part of the following classes and functions:
- CookTheBooks\IconsHelper::get_theme_svg()
- CookTheBooks\IconsHelper::the_theme_svg()
- JavaScript code in script.js
- CookTheBooksDomReady()
- CookTheBooks.setupMainMenu.trapFocusInModal()
- CookTheBooks.setupMainMenu.collapseIfEscapeKeyPress()
* SVG UI Icons
* License: SIL Open Font License (OFL)
* Source: https://www.iconfinder.com/iconsets/font-awesome
* Alpha Color Picker Customizer Control (c) Cristian-Ungureanu
* License: MIT License, https://github.com/Codeinwp/customizer-controls/blob/master/LICENSE
* Source: https://github.com/Codeinwp/customizer-controls/tree/master/customizer-alpha-color-picker
* Customizer Upsell Section
* License: GPLv2, https://github.com/WPTT/customize-section-button/blob/master/license.md
* Source: https://github.com/WPTT/customize-section-button
Included as part of the following class:
- CookTheBooks_Upsell_Section
* Sticky Sidebar
* License: MIT License, https://github.com/blixhavn/sticky-sidebar-v2/blob/master/LICENSE.md
* Source: https://github.com/blixhavn/sticky-sidebar-v2
* ResizeObserver Polyfill
* License: MIT License, https://github.com/que-etc/resize-observer-polyfill/blob/master/LICENSE
* Source: https://github.com/que-etc/resize-observer-polyfill
* Composer Autoloader
* License: MIT License, https://github.com/composer/composer/blob/master/LICENSE
* Source: https://getcomposer.org/
* Webfonts Loader
* License: MIT License, https://github.com/WPTT/webfont-loader/blob/master/LICENSE
* Source: https://github.com/WPTT/webfont-loader
* TGM Plugin Activation - v2.6.1, http://tgmpluginactivation.com/, By Thomas Griffin, Gary Jones, Juliette Reinders Folmer, License: GPL-2.0+
* Underscores https://underscores.me/, By Automattic, Inc., [GPLv2 or later](https://www.gnu.org/licenses/gpl-2.0.html)
* normalize.css https://necolas.github.io/normalize.css/, By Nicolas Gallagher and Jonathan Neal, [MIT](https://opensource.org/licenses/MIT)

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

22
sidebar-left.php Normal file
View File

@ -0,0 +1,22 @@
<?php
/**
* The sidebar containing the left widget area.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package PressBook
*/
if ( ! is_active_sidebar( 'sidebar-2' ) ) {
return;
}
do_action( 'pressbook_before_left_sidebar' );
?>
<aside id="secondary-left" class="widget-area c-sidebar c-sidebar-left">
<?php dynamic_sidebar( 'sidebar-2' ); ?>
</aside><!-- #secondary-left -->
<?php
do_action( 'pressbook_after_left_sidebar' );

22
sidebar-shop.php Normal file
View File

@ -0,0 +1,22 @@
<?php
/**
* The sidebar containing the shop widget area.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package PressBook
*/
if ( ! is_active_sidebar( 'sidebar-shop' ) ) {
return;
}
do_action( 'pressbook_before_shop_sidebar' );
?>
<aside id="secondary" class="widget-area c-sidebar c-sidebar-shop">
<?php dynamic_sidebar( 'sidebar-shop' ); ?>
</aside><!-- #secondary -->
<?php
do_action( 'pressbook_after_shop_sidebar' );

22
sidebar.php Normal file
View File

@ -0,0 +1,22 @@
<?php
/**
* The sidebar containing the right widget area.
*
* @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
*
* @package PressBook
*/
if ( ! is_active_sidebar( 'sidebar-1' ) ) {
return;
}
do_action( 'pressbook_before_right_sidebar' );
?>
<aside id="secondary" class="widget-area c-sidebar c-sidebar-right">
<?php dynamic_sidebar( 'sidebar-1' ); ?>
</aside><!-- #secondary -->
<?php
do_action( 'pressbook_after_right_sidebar' );

51
single.php Normal file
View File

@ -0,0 +1,51 @@
<?php
/**
* The template for displaying all single posts.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/#single-post
*
* @package PressBook
*/
get_header();
?>
<div class="pb-content-sidebar u-wrapper">
<main id="primary" class="site-main">
<?php
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( 'template-parts/content', 'single' );
}
if ( is_singular( 'post' ) ) {
// Previous/next post navigation.
the_post_navigation(
array(
'prev_text' => '<span class="nav-title"><span class="screen-reader-text">' .
esc_html__( 'Previous Post:', 'pressbook' ) . '</span> %title</span>',
'next_text' => '<span class="nav-title"><span class="screen-reader-text">' .
esc_html__( 'Next Post:', 'pressbook' ) . '</span> %title</span>',
)
);
}
// If comments are open or we have at least one comment, load up the comment template.
if ( comments_open() || get_comments_number() ) {
comments_template();
}
}
?>
</main><!-- #primary -->
<?php
get_sidebar( 'left' );
get_sidebar();
?>
</div><!-- .pb-content-sidebar -->
<?php
get_footer();

3525
style-rtl.css Normal file

File diff suppressed because it is too large Load Diff

3531
style.css Normal file

File diff suppressed because it is too large Load Diff

1
style.min-rtl.css Normal file

File diff suppressed because one or more lines are too long

1
style.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,51 @@
<?php
/**
* Template part for displaying a message that posts cannot be found.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package PressBook
*/
?>
<section class="no-results not-found">
<header class="page-header">
<h1 class="page-title"><?php esc_html_e( 'Nothing Found', 'pressbook' ); ?></h1>
</header><!-- .page-header -->
<div class="page-content">
<?php
if ( is_home() && current_user_can( 'publish_posts' ) ) {
printf(
'<p>' . wp_kses(
/* translators: 1: link to WP admin new post page */
__( 'Ready to publish your first post? <a href="%1$s">Get started here</a>.', 'pressbook' ),
array(
'a' => array(
'href' => array(),
),
)
) . '</p>',
esc_url( admin_url( 'post-new.php' ) )
);
} elseif ( is_search() ) {
?>
<p><?php esc_html_e( 'Sorry, but nothing matched your search terms. Please try again with some different keywords.', 'pressbook' ); ?></p>
<?php
get_search_form();
} else {
?>
<p><?php esc_html_e( 'It seems we can&rsquo;t find what you&rsquo;re looking for. Perhaps searching can help.', 'pressbook' ); ?></p>
<?php
get_search_form();
}
?>
</div><!-- .page-content -->
</section><!-- .no-results -->

View File

@ -0,0 +1,30 @@
<?php
/**
* Template part for displaying page content without title in page.php.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package PressBook
*/
?>
<article id="post-<?php the_ID(); ?>" <?php post_class( 'pb-article pb-singular' ); ?>>
<?php PressBook\TemplateTags::post_thumbnail(); ?>
<div class="pb-content">
<div class="entry-content">
<?php
the_content();
wp_link_pages(
array(
'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'pressbook' ),
'after' => '</div>',
)
);
?>
</div><!-- .entry-content -->
</div><!-- .pb-content -->
<?php PressBook\TemplateTags::edit_post_link(); ?>
</article><!-- #post-<?php the_ID(); ?> -->

View File

@ -0,0 +1,34 @@
<?php
/**
* Template part for displaying page content in page.php.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package PressBook
*/
?>
<article id="post-<?php the_ID(); ?>" <?php post_class( 'pb-article pb-singular' ); ?>>
<?php PressBook\TemplateTags::post_thumbnail(); ?>
<header class="entry-header">
<?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
</header><!-- .entry-header -->
<div class="pb-content">
<div class="entry-content">
<?php
the_content();
wp_link_pages(
array(
'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'pressbook' ),
'after' => '</div>',
)
);
?>
</div><!-- .entry-content -->
</div><!-- .pb-content -->
<?php PressBook\TemplateTags::edit_post_link(); ?>
</article><!-- #post-<?php the_ID(); ?> -->

View File

@ -0,0 +1,52 @@
<?php
/**
* Template part for displaying single post content in single.php.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package PressBook
*/
?>
<article id="post-<?php the_ID(); ?>" <?php post_class( 'pb-article pb-singular' ); ?>>
<?php PressBook\TemplateTags::post_thumbnail(); ?>
<header class="entry-header">
<?php
the_title( '<h1 class="entry-title">', '</h1>' );
if ( 'post' === get_post_type() ) {
?>
<div class="<?php echo esc_attr( PressBook\Options\Blog::entry_meta_class() ); ?>">
<?php
PressBook\TemplateTags::posted_on();
PressBook\TemplateTags::posted_by();
PressBook\TemplateTags::comments();
?>
</div><!-- .entry-meta -->
<?php
}
?>
</header><!-- .entry-header -->
<div class="pb-content">
<div class="entry-content">
<?php
the_content();
wp_link_pages(
array(
'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'pressbook' ),
'after' => '</div>',
)
);
?>
</div><!-- .entry-content -->
</div><!-- .pb-content -->
<?php
PressBook\TemplateTags::post_categories();
PressBook\TemplateTags::post_tags();
PressBook\TemplateTags::edit_post_link();
?>
</article><!-- #post-<?php the_ID(); ?> -->

View File

@ -0,0 +1,74 @@
<?php
/**
* Template part for displaying posts.
*
* @link https://developer.wordpress.org/themes/basics/template-hierarchy/
*
* @package PressBook
*/
$pressbook_has_content = ( ( '' !== get_the_excerpt() ) || has_post_thumbnail() || ( '' !== get_the_content() ) );
?>
<article id="post-<?php the_ID(); ?>" <?php post_class( 'pb-article pb-archive' . ( $pressbook_has_content ? '' : ' pb-no-content' ) ); ?>>
<header class="entry-header">
<?php
the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' );
if ( 'post' === get_post_type() ) {
?>
<div class="<?php echo esc_attr( PressBook\Options\Blog::entry_meta_class() ); ?>">
<?php
PressBook\TemplateTags::posted_on();
PressBook\TemplateTags::posted_by();
PressBook\TemplateTags::comments();
if ( is_home() && is_sticky() ) {
echo '<span class="pb-sticky">';
PressBook\IconsHelper::the_theme_svg( 'bookmark' );
echo ( '<span class="pb-sticky-label">' . esc_html( PressBook\Options\Blog::featured_label_text() ) . '</span>' );
echo '</span>';
}
?>
</div><!-- .entry-meta -->
<?php
}
?>
</header><!-- .entry-header -->
<?php
if ( $pressbook_has_content ) {
?>
<div class="pb-content">
<?php
PressBook\TemplateTags::post_thumbnail();
if ( ( '' !== get_the_excerpt() ) && PressBook\Helpers::show_excerpt() ) {
?>
<div class="entry-summary">
<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
<?php
} else {
?>
<div class="entry-content">
<?php
the_content();
wp_link_pages(
array(
'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'pressbook' ),
'after' => '</div>',
)
);
?>
</div><!-- .entry-content -->
<?php
}
?>
</div><!-- .pb-content -->
<?php
}
PressBook\TemplateTags::post_categories();
?>
</article><!-- #post-<?php the_ID(); ?> -->

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