summaryrefslogtreecommitdiff
path: root/inc
diff options
context:
space:
mode:
Diffstat (limited to 'inc')
-rw-r--r--inc/class-wp-bootstrap-navwalker.php559
-rw-r--r--inc/custom-comments.php71
-rw-r--r--inc/custom-header.php49
-rw-r--r--inc/customizer.php135
-rw-r--r--inc/editor.php78
-rw-r--r--inc/enqueue.php34
-rw-r--r--inc/extras.php114
-rw-r--r--inc/hooks.php49
-rw-r--r--inc/jetpack.php67
-rw-r--r--inc/pagination.php56
-rw-r--r--inc/setup.php132
-rw-r--r--inc/style-wpcom.css7
-rw-r--r--inc/template-tags.php137
-rwxr-xr-xinc/theme-settings.php36
-rw-r--r--inc/widgets.php119
-rw-r--r--inc/woocommerce.php140
-rw-r--r--inc/wpcom.php51
17 files changed, 1834 insertions, 0 deletions
diff --git a/inc/class-wp-bootstrap-navwalker.php b/inc/class-wp-bootstrap-navwalker.php
new file mode 100644
index 0000000..a343fcc
--- /dev/null
+++ b/inc/class-wp-bootstrap-navwalker.php
@@ -0,0 +1,559 @@
+<?php
+/**
+ * WP Bootstrap Navwalker
+ *
+ * @package WP-Bootstrap-Navwalker
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+/*
+ * Class Name: WP_Bootstrap_Navwalker
+ * Plugin Name: WP Bootstrap Navwalker
+ * Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker
+ * Description: A custom WordPress nav walker class to implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager.
+ * Author: Edward McIntyre - @twittem, WP Bootstrap, William Patton - @pattonwebz
+ * Version: 4.1.0
+ * Author URI: https://github.com/wp-bootstrap
+ * GitHub Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker
+ * GitHub Branch: master
+ * License: GPL-3.0+
+ * License URI: http://www.gnu.org/licenses/gpl-3.0.txt
+*/
+
+/* Check if Class Exists. */
+if ( ! class_exists( 'Understrap_WP_Bootstrap_Navwalker' ) ) {
+ /**
+ * WP_Bootstrap_Navwalker class.
+ *
+ * @extends Walker_Nav_Menu
+ */
+ class Understrap_WP_Bootstrap_Navwalker extends Walker_Nav_Menu {
+
+ /**
+ * Starts the list before the elements are added.
+ *
+ * @since WP 3.0.0
+ *
+ * @see Walker_Nav_Menu::start_lvl()
+ *
+ * @param string $output Used to append additional content (passed by reference).
+ * @param int $depth Depth of menu item. Used for padding.
+ * @param stdClass $args An object of wp_nav_menu() arguments.
+ */
+ public function start_lvl( &$output, $depth = 0, $args = array() ) {
+ if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
+ $t = '';
+ $n = '';
+ } else {
+ $t = "\t";
+ $n = "\n";
+ }
+ $indent = str_repeat( $t, $depth );
+ // Default class to add to the file.
+ $classes = array( 'dropdown-menu' );
+ /**
+ * Filters the CSS class(es) applied to a menu list element.
+ *
+ * @since WP 4.8.0
+ *
+ * @param array $classes The CSS classes that are applied to the menu `<ul>` element.
+ * @param stdClass $args An object of `wp_nav_menu()` arguments.
+ * @param int $depth Depth of menu item. Used for padding.
+ */
+ $class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
+ $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
+ /**
+ * The `.dropdown-menu` container needs to have a labelledby
+ * attribute which points to it's trigger link.
+ *
+ * Form a string for the labelledby attribute from the the latest
+ * link with an id that was added to the $output.
+ */
+ $labelledby = '';
+ // find all links with an id in the output.
+ preg_match_all( '/(<a.*?id=\"|\')(.*?)\"|\'.*?>/im', $output, $matches );
+ // with pointer at end of array check if we got an ID match.
+ if ( end( $matches[2] ) ) {
+ // build a string to use as aria-labelledby.
+ $labelledby = 'aria-labelledby="' . end( $matches[2] ) . '"';
+ }
+ $output .= "{$n}{$indent}<ul$class_names $labelledby role=\"menu\">{$n}";
+ }
+
+ /**
+ * Starts the element output.
+ *
+ * @since WP 3.0.0
+ * @since WP 4.4.0 The {@see 'nav_menu_item_args'} filter was added.
+ *
+ * @see Walker_Nav_Menu::start_el()
+ *
+ * @param string $output Used to append additional content (passed by reference).
+ * @param WP_Post $item Menu item data object.
+ * @param int $depth Depth of menu item. Used for padding.
+ * @param stdClass $args An object of wp_nav_menu() arguments.
+ * @param int $id Current item ID.
+ */
+ public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
+ if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
+ $t = '';
+ $n = '';
+ } else {
+ $t = "\t";
+ $n = "\n";
+ }
+ $indent = ( $depth ) ? str_repeat( $t, $depth ) : '';
+
+ $classes = empty( $item->classes ) ? array() : (array) $item->classes;
+
+ // Initialize some holder variables to store specially handled item
+ // wrappers and icons.
+ $linkmod_classes = array();
+ $icon_classes = array();
+
+ /**
+ * Get an updated $classes array without linkmod or icon classes.
+ *
+ * NOTE: linkmod and icon class arrays are passed by reference and
+ * are maybe modified before being used later in this function.
+ */
+ $classes = self::seporate_linkmods_and_icons_from_classes( $classes, $linkmod_classes, $icon_classes, $depth );
+
+ // Join any icon classes plucked from $classes into a string.
+ $icon_class_string = join( ' ', $icon_classes );
+
+ /**
+ * Filters the arguments for a single nav menu item.
+ *
+ * WP 4.4.0
+ *
+ * @param stdClass $args An object of wp_nav_menu() arguments.
+ * @param WP_Post $item Menu item data object.
+ * @param int $depth Depth of menu item. Used for padding.
+ */
+ $args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );
+
+ // Add .dropdown or .active classes where they are needed.
+ if ( isset( $args->has_children ) && $args->has_children ) {
+ $classes[] = 'dropdown';
+ }
+ if ( in_array( 'current-menu-item', $classes, true ) || in_array( 'current-menu-parent', $classes, true ) ) {
+ $classes[] = 'active';
+ }
+
+ // Add some additional default classes to the item.
+ $classes[] = 'menu-item-' . $item->ID;
+ $classes[] = 'nav-item';
+
+ // Allow filtering the classes.
+ $classes = apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth );
+
+ // Form a string of classes in format: class="class_names".
+ $class_names = join( ' ', $classes );
+ $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
+
+ /**
+ * Filters the ID applied to a menu item's list item element.
+ *
+ * @since WP 3.0.1
+ * @since WP 4.1.0 The `$depth` parameter was added.
+ *
+ * @param string $menu_id The ID that is applied to the menu item's `<li>` element.
+ * @param WP_Post $item The current menu item.
+ * @param stdClass $args An object of wp_nav_menu() arguments.
+ * @param int $depth Depth of menu item. Used for padding.
+ */
+ $id = apply_filters( 'nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args, $depth );
+ $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
+
+ $output .= $indent . '<li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement"' . $id . $class_names . '>';
+
+ // initialize array for holding the $atts for the link item.
+ $atts = array();
+
+ // Set title from item to the $atts array - if title is empty then
+ // default to item title.
+ if ( empty( $item->attr_title ) ) {
+ $atts['title'] = ! empty( $item->title ) ? strip_tags( $item->title ) : '';
+ } else {
+ $atts['title'] = $item->attr_title;
+ }
+
+ $atts['target'] = ! empty( $item->target ) ? $item->target : '';
+ $atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
+ // If item has_children add atts to <a>.
+ if ( isset( $args->has_children ) && $args->has_children && 0 === $depth && $args->depth > 1 ) {
+ $atts['href'] = '#';
+ $atts['data-toggle'] = 'dropdown';
+ $atts['aria-haspopup'] = 'true';
+ $atts['aria-expanded'] = 'false';
+ $atts['class'] = 'dropdown-toggle nav-link';
+ $atts['id'] = 'menu-item-dropdown-' . $item->ID;
+ } else {
+ $atts['href'] = ! empty( $item->url ) ? $item->url : '#';
+ // Items in dropdowns use .dropdown-item instead of .nav-link.
+ if ( $depth > 0 ) {
+ $atts['class'] = 'dropdown-item';
+ } else {
+ $atts['class'] = 'nav-link';
+ }
+ }
+
+ // update atts of this item based on any custom linkmod classes.
+ $atts = self::update_atts_for_linkmod_type( $atts, $linkmod_classes );
+ // Allow filtering of the $atts array before using it.
+ $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );
+
+ // Build a string of html containing all the atts for the item.
+ $attributes = '';
+ foreach ( $atts as $attr => $value ) {
+ if ( ! empty( $value ) ) {
+ $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
+ $attributes .= ' ' . $attr . '="' . $value . '"';
+ }
+ }
+
+ /**
+ * Set a typeflag to easily test if this is a linkmod or not.
+ */
+ $linkmod_type = self::get_linkmod_type( $linkmod_classes );
+
+ /**
+ * START appending the internal item contents to the output.
+ */
+ $item_output = isset( $args->before ) ? $args->before : '';
+ /**
+ * This is the start of the internal nav item. Depending on what
+ * kind of linkmod we have we may need different wrapper elements.
+ */
+ if ( '' !== $linkmod_type ) {
+ // is linkmod, output the required element opener.
+ $item_output .= self::linkmod_element_open( $linkmod_type, $attributes );
+ } else {
+ // With no link mod type set this must be a standard <a> tag.
+ $item_output .= '<a' . $attributes . '>';
+ }
+
+ /**
+ * Initiate empty icon var, then if we have a string containing any
+ * icon classes form the icon markup with an <i> element. This is
+ * output inside of the item before the $title (the link text).
+ */
+ $icon_html = '';
+ if ( ! empty( $icon_class_string ) ) {
+ // append an <i> with the icon classes to what is output before links.
+ $icon_html = '<i class="' . esc_attr( $icon_class_string ) . '" aria-hidden="true"></i> ';
+ }
+
+ /** This filter is documented in wp-includes/post-template.php */
+ $title = apply_filters( 'the_title', $item->title, $item->ID );
+
+ /**
+ * Filters a menu item's title.
+ *
+ * @since WP 4.4.0
+ *
+ * @param string $title The menu item's title.
+ * @param WP_Post $item The current menu item.
+ * @param stdClass $args An object of wp_nav_menu() arguments.
+ * @param int $depth Depth of menu item. Used for padding.
+ */
+ $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );
+
+ /**
+ * If the .sr-only class was set apply to the nav items text only.
+ */
+ if ( in_array( 'sr-only', $linkmod_classes, true ) ) {
+ $title = self::wrap_for_screen_reader( $title );
+ $keys_to_unset = array_keys( $linkmod_classes, 'sr-only' );
+ foreach ( $keys_to_unset as $k ) {
+ unset( $linkmod_classes[ $k ] );
+ }
+ }
+
+ // Put the item contents into $output.
+ $item_output .= isset( $args->link_before ) ? $args->link_before . $icon_html . $title . $args->link_after : '';
+ /**
+ * This is the end of the internal nav item. We need to close the
+ * correct element depending on the type of link or link mod.
+ */
+ if ( '' !== $linkmod_type ) {
+ // is linkmod, output the required element opener.
+ $item_output .= self::linkmod_element_close( $linkmod_type, $attributes );
+ } else {
+ // With no link mod type set this must be a standard <a> tag.
+ $item_output .= '</a>';
+ }
+
+ $item_output .= isset( $args->after ) ? $args->after : '';
+
+ /**
+ * END appending the internal item contents to the output.
+ */
+ $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
+
+ }
+
+ /**
+ * Traverse elements to create list from elements.
+ *
+ * Display one element if the element doesn't have any children otherwise,
+ * display the element and its children. Will only traverse up to the max
+ * depth and no ignore elements under that depth. It is possible to set the
+ * max depth to include all depths, see walk() method.
+ *
+ * This method should not be called directly, use the walk() method instead.
+ *
+ * @since WP 2.5.0
+ *
+ * @see Walker::start_lvl()
+ *
+ * @param object $element Data object.
+ * @param array $children_elements List of elements to continue traversing (passed by reference).
+ * @param int $max_depth Max depth to traverse.
+ * @param int $depth Depth of current element.
+ * @param array $args An array of arguments.
+ * @param string $output Used to append additional content (passed by reference).
+ */
+ public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
+ if ( ! $element ) {
+ return; }
+ $id_field = $this->db_fields['id'];
+ // Display this element.
+ if ( is_object( $args[0] ) ) {
+ $args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] ); }
+ parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
+ }
+
+ /**
+ * Menu Fallback
+ * =============
+ * If this function is assigned to the wp_nav_menu's fallback_cb variable
+ * and a menu has not been assigned to the theme location in the WordPress
+ * menu manager the function with display nothing to a non-logged in user,
+ * and will add a link to the WordPress menu manager if logged in as an admin.
+ *
+ * @param array $args passed from the wp_nav_menu function.
+ */
+ public static function fallback( $args ) {
+ if ( current_user_can( 'edit_theme_options' ) ) {
+
+ /* Get Arguments. */
+ $container = $args['container'];
+ $container_id = $args['container_id'];
+ $container_class = $args['container_class'];
+ $menu_class = $args['menu_class'];
+ $menu_id = $args['menu_id'];
+
+ // initialize var to store fallback html.
+ $fallback_output = '';
+
+ if ( $container ) {
+ $fallback_output .= '<' . esc_attr( $container );
+ if ( $container_id ) {
+ $fallback_output .= ' id="' . esc_attr( $container_id ) . '"';
+ }
+ if ( $container_class ) {
+ $fallback_output .= ' class="' . esc_attr( $container_class ) . '"';
+ }
+ $fallback_output .= '>';
+ }
+ $fallback_output .= '<ul';
+ if ( $menu_id ) {
+ $fallback_output .= ' id="' . esc_attr( $menu_id ) . '"'; }
+ if ( $menu_class ) {
+ $fallback_output .= ' class="' . esc_attr( $menu_class ) . '"'; }
+ $fallback_output .= '>';
+ $fallback_output .= '<li><a href="' . esc_url( admin_url( 'nav-menus.php' ) ) . '" title="' . esc_attr__( 'Add a menu', 'understrap' ) . '">' . esc_html__( 'Add a menu', 'understrap' ) . '</a></li>';
+ $fallback_output .= '</ul>';
+ if ( $container ) {
+ $fallback_output .= '</' . esc_attr( $container ) . '>';
+ }
+
+ // if $args has 'echo' key and it's true echo, otherwise return.
+ if ( array_key_exists( 'echo', $args ) && $args['echo'] ) {
+ echo $fallback_output; // WPCS: XSS OK.
+ } else {
+ return $fallback_output;
+ }
+ }
+ }
+
+ /**
+ * Find any custom linkmod or icon classes and store in their holder
+ * arrays then remove them from the main classes array.
+ *
+ * Supported linkmods: .disabled, .dropdown-header, .dropdown-divider, .sr-only
+ * Supported iconsets: Font Awesome 4/5, Glypicons
+ *
+ * NOTE: This accepts the linkmod and icon arrays by reference.
+ *
+ * @since 4.0.0
+ *
+ * @param array $classes an array of classes currently assigned to the item.
+ * @param array $linkmod_classes an array to hold linkmod classes.
+ * @param array $icon_classes an array to hold icon classes.
+ * @param integer $depth an integer holding current depth level.
+ *
+ * @return array $classes a maybe modified array of classnames.
+ */
+ private function seporate_linkmods_and_icons_from_classes( $classes, &$linkmod_classes, &$icon_classes, $depth ) {
+ // Loop through $classes array to find linkmod or icon classes.
+ foreach ( $classes as $key => $class ) {
+ // If any special classes are found, store the class in it's
+ // holder array and and unset the item from $classes.
+ if ( preg_match( '/^disabled|^sr-only/i', $class ) ) {
+ // Test for .disabled or .sr-only classes.
+ $linkmod_classes[] = $class;
+ unset( $classes[ $key ] );
+ } elseif ( preg_match( '/^dropdown-header|^dropdown-divider|^dropdown-item-text/i', $class ) && $depth > 0 ) {
+ // Test for .dropdown-header or .dropdown-divider and a
+ // depth greater than 0 - IE inside a dropdown.
+ $linkmod_classes[] = $class;
+ unset( $classes[ $key ] );
+ } elseif ( preg_match( '/^fa-(\S*)?|^fa(s|r|l|b)?(\s?)?$/i', $class ) ) {
+ // Font Awesome.
+ $icon_classes[] = $class;
+ unset( $classes[ $key ] );
+ } elseif ( preg_match( '/^glyphicon-(\S*)?|^glyphicon(\s?)$/i', $class ) ) {
+ // Glyphicons.
+ $icon_classes[] = $class;
+ unset( $classes[ $key ] );
+ }
+ }
+
+ return $classes;
+ }
+
+ /**
+ * Return a string containing a linkmod type and update $atts array
+ * accordingly depending on the decided.
+ *
+ * @since 4.0.0
+ *
+ * @param array $linkmod_classes array of any link modifier classes.
+ *
+ * @return string empty for default, a linkmod type string otherwise.
+ */
+ private function get_linkmod_type( $linkmod_classes = array() ) {
+ $linkmod_type = '';
+ // Loop through array of linkmod classes to handle their $atts.
+ if ( ! empty( $linkmod_classes ) ) {
+ foreach ( $linkmod_classes as $link_class ) {
+ if ( ! empty( $link_class ) ) {
+
+ // check for special class types and set a flag for them.
+ if ( 'dropdown-header' === $link_class ) {
+ $linkmod_type = 'dropdown-header';
+ } elseif ( 'dropdown-divider' === $link_class ) {
+ $linkmod_type = 'dropdown-divider';
+ } elseif ( 'dropdown-item-text' === $link_class ) {
+ $linkmod_type = 'dropdown-item-text';
+ }
+ }
+ }
+ }
+ return $linkmod_type;
+ }
+
+ /**
+ * Update the attributes of a nav item depending on the limkmod classes.
+ *
+ * @since 4.0.0
+ *
+ * @param array $atts array of atts for the current link in nav item.
+ * @param array $linkmod_classes an array of classes that modify link or nav item behaviors or displays.
+ *
+ * @return array maybe updated array of attributes for item.
+ */
+ private function update_atts_for_linkmod_type( $atts = array(), $linkmod_classes = array() ) {
+ if ( ! empty( $linkmod_classes ) ) {
+ foreach ( $linkmod_classes as $link_class ) {
+ if ( ! empty( $link_class ) ) {
+ // update $atts with a space and the extra classname...
+ // so long as it's not a sr-only class.
+ if ( 'sr-only' !== $link_class ) {
+ $atts['class'] .= ' ' . esc_attr( $link_class );
+ }
+ // check for special class types we need additional handling for.
+ if ( 'disabled' === $link_class ) {
+ // Convert link to '#' and unset open targets.
+ $atts['href'] = '#';
+ unset( $atts['target'] );
+ } elseif ( 'dropdown-header' === $link_class || 'dropdown-divider' === $link_class || 'dropdown-item-text' === $link_class ) {
+ // Store a type flag and unset href and target.
+ unset( $atts['href'] );
+ unset( $atts['target'] );
+ }
+ }
+ }
+ }
+ return $atts;
+ }
+
+ /**
+ * Wraps the passed text in a screen reader only class.
+ *
+ * @since 4.0.0
+ *
+ * @param string $text the string of text to be wrapped in a screen reader class.
+ * @return string the string wrapped in a span with the class.
+ */
+ private function wrap_for_screen_reader( $text = '' ) {
+ if ( $text ) {
+ $text = '<span class="sr-only">' . $text . '</span>';
+ }
+ return $text;
+ }
+
+ /**
+ * Returns the correct opening element and attributes for a linkmod.
+ *
+ * @since 4.0.0
+ *
+ * @param string $linkmod_type a sting containing a linkmod type flag.
+ * @param string $attributes a string of attributes to add to the element.
+ *
+ * @return string a string with the openign tag for the element with attribibutes added.
+ */
+ private function linkmod_element_open( $linkmod_type, $attributes = '' ) {
+ $output = '';
+ if ( 'dropdown-item-text' === $linkmod_type ) {
+ $output .= '<span class="dropdown-item-text"' . $attributes . '>';
+ } elseif ( 'dropdown-header' === $linkmod_type ) {
+ // For a header use a span with the .h6 class instead of a real
+ // header tag so that it doesn't confuse screen readers.
+ $output .= '<span class="dropdown-header h6"' . $attributes . '>';
+ } elseif ( 'dropdown-divider' === $linkmod_type ) {
+ // this is a divider.
+ $output .= '<div class="dropdown-divider"' . $attributes . '>';
+ }
+ return $output;
+ }
+
+ /**
+ * Return the correct closing tag for the linkmod element.
+ *
+ * @since 4.0.0
+ *
+ * @param string $linkmod_type a string containing a special linkmod type.
+ *
+ * @return string a string with the closing tag for this linkmod type.
+ */
+ private function linkmod_element_close( $linkmod_type ) {
+ $output = '';
+ if ( 'dropdown-header' === $linkmod_type || 'dropdown-item-text' === $linkmod_type ) {
+ // For a header use a span with the .h6 class instead of a real
+ // header tag so that it doesn't confuse screen readers.
+ $output .= '</span>';
+ } elseif ( 'dropdown-divider' === $linkmod_type ) {
+ // this is a divider.
+ $output .= '</div>';
+ }
+ return $output;
+ }
+ }
+}
diff --git a/inc/custom-comments.php b/inc/custom-comments.php
new file mode 100644
index 0000000..c4aa7c7
--- /dev/null
+++ b/inc/custom-comments.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Comment layout.
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+// Comments form.
+add_filter( 'comment_form_default_fields', 'understrap_bootstrap_comment_form_fields' );
+
+/**
+ * Creates the comments form.
+ *
+ * @param string $fields Form fields.
+ *
+ * @return array
+ */
+
+if ( ! function_exists( 'understrap_bootstrap_comment_form_fields' ) ) {
+
+ function understrap_bootstrap_comment_form_fields( $fields ) {
+ $commenter = wp_get_current_commenter();
+ $req = get_option( 'require_name_email' );
+ $aria_req = ( $req ? " aria-required='true'" : '' );
+ $html5 = current_theme_supports( 'html5', 'comment-form' ) ? 1 : 0;
+ $consent = empty( $commenter['comment_author_email'] ) ? '' : ' checked="checked"';
+ $fields = array(
+ 'author' => '<div class="form-group comment-form-author textfield-box"><label for="author">' . __( 'Name',
+ 'understrap' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label> ' .
+ '<input class="form-control" id="author" name="author" type="text" value="' . esc_attr( $commenter['comment_author'] ) . '" size="30"' . $aria_req . '></div>',
+ 'email' => '<div class="form-group comment-form-email textfield-box"><label for="email">' . __( 'E-Mail',
+ 'understrap' ) . ( $req ? ' <span class="required">*</span>' : '' ) . '</label> ' .
+ '<input class="form-control" id="email" name="email" ' . ( $html5 ? 'type="email"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_email'] ) . '" size="30"' . $aria_req . '></div>',
+ 'url' => '<div class="form-group comment-form-url textfield-box"><label for="url">' . __( 'Webseite',
+ 'understrap' ) . '</label> ' .
+ '<input class="form-control" id="url" name="url" ' . ( $html5 ? 'type="url"' : 'type="text"' ) . ' value="' . esc_attr( $commenter['comment_author_url'] ) . '" size="30"></div>',
+ 'cookies' => '<div class="form-group form-check comment-form-cookies-consent"><input class="form-check-input" id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"' . $consent . ' /> ' .
+ '<label class="form-check-label" for="wp-comment-cookies-consent">' . __( 'Save my name, email, and website in this browser for the next time I comment', 'understrap' ) . '</label></div>',
+ );
+
+ return $fields;
+ }
+} // endif function_exists( 'understrap_bootstrap_comment_form_fields' )
+
+add_filter( 'comment_form_defaults', 'understrap_bootstrap_comment_form' );
+
+/**
+ * Builds the form.
+ *
+ * @param string $args Arguments for form's fields.
+ *
+ * @return mixed
+ */
+
+if ( ! function_exists( 'understrap_bootstrap_comment_form' ) ) {
+
+ function understrap_bootstrap_comment_form( $args ) {
+ $args['comment_field'] = '<div class="form-group comment-form-comment">
+ <div class="textfield-box">
+ <label for="comment">' . _x( 'Kommentar', 'noun', 'understrap' ) . ( ' <span class="required">*</span>' ) . '</label>
+ <textarea class="form-control" id="comment" name="comment" aria-required="true" cols="45" rows="8"></textarea>
+ </div>
+ </div>';
+ $args['class_submit'] = 'btn btn-secondary'; // since WP 4.1.
+ return $args;
+ }
+} // endif function_exists( 'understrap_bootstrap_comment_form' )
diff --git a/inc/custom-header.php b/inc/custom-header.php
new file mode 100644
index 0000000..b66a416
--- /dev/null
+++ b/inc/custom-header.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Custom header setup.
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+add_action( 'after_setup_theme', 'understrap_custom_header_setup' );
+
+if ( ! function_exists ( 'understrap_custom_header_setup' ) ) {
+ function understrap_custom_header_setup() {
+
+ /**
+ * Filter UnderStrap custom-header support arguments.
+ *
+ * @since UnderStrap 0.5.2
+ *
+ * @param array $args {
+ * An array of custom-header support arguments.
+ *
+ * @type string $default-image Default image of the header.
+ * @type string $default_text_color Default color of the header text.
+ * @type int $width Width in pixels of the custom header image. Default 954.
+ * @type int $height Height in pixels of the custom header image. Default 1300.
+ * @type string $wp-head-callback Callback function used to styles the header image and text
+ * displayed on the blog.
+ * @type string $flex-height Flex support for height of header.
+ * }
+ */
+ add_theme_support( 'custom-header', apply_filters( 'understrap_custom_header_args', array(
+ 'default-image' => get_parent_theme_file_uri( '/img/header.jpg' ),
+ 'width' => 2000,
+ 'height' => 1200,
+ 'flex-height' => true,
+ ) ) );
+
+ register_default_headers( array(
+ 'default-image' => array(
+ 'url' => '%s/img/header.jpg',
+ 'thumbnail_url' => '%s/img/header.jpg',
+ 'description' => __( 'Default Header Image', 'understrap' ),
+ ),
+ ) );
+ }
+} \ No newline at end of file
diff --git a/inc/customizer.php b/inc/customizer.php
new file mode 100644
index 0000000..6729d77
--- /dev/null
+++ b/inc/customizer.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Understrap Theme Customizer
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+/**
+ * Add postMessage support for site title and description for the Theme Customizer.
+ *
+ * @param WP_Customize_Manager $wp_customize Theme Customizer object.
+ */
+if ( ! function_exists( 'understrap_customize_register' ) ) {
+ /**
+ * Register basic customizer support.
+ *
+ * @param object $wp_customize Customizer reference.
+ */
+ function understrap_customize_register( $wp_customize ) {
+ $wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
+ $wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
+ $wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
+ }
+}
+add_action( 'customize_register', 'understrap_customize_register' );
+
+if ( ! function_exists( 'understrap_theme_customize_register' ) ) {
+ /**
+ * Register individual settings through customizer's API.
+ *
+ * @param WP_Customize_Manager $wp_customize Customizer reference.
+ */
+ function understrap_theme_customize_register( $wp_customize ) {
+
+ // Theme layout settings.
+ $wp_customize->add_section( 'understrap_theme_layout_options', array(
+ 'title' => __( 'Theme Layout Settings', 'understrap' ),
+ 'capability' => 'edit_theme_options',
+ 'description' => __( 'Container width and sidebar defaults', 'understrap' ),
+ 'priority' => 160,
+ ) );
+
+ /**
+ * Select sanitization function
+ *
+ * @param string $input Slug to sanitize.
+ * @param WP_Customize_Setting $setting Setting instance.
+ * @return string Sanitized slug if it is a valid choice; otherwise, the setting default.
+ */
+ function understrap_theme_slug_sanitize_select( $input, $setting ){
+
+ // Ensure input is a slug (lowercase alphanumeric characters, dashes and underscores are allowed only).
+ $input = sanitize_key( $input );
+
+ // Get the list of possible select options.
+ $choices = $setting->manager->get_control( $setting->id )->choices;
+
+ // If the input is a valid key, return it; otherwise, return the default.
+ return ( array_key_exists( $input, $choices ) ? $input : $setting->default );
+
+ }
+
+ $wp_customize->add_setting( 'understrap_container_type', array(
+ 'default' => 'container',
+ 'type' => 'theme_mod',
+ 'sanitize_callback' => 'understrap_theme_slug_sanitize_select',
+ 'capability' => 'edit_theme_options',
+ ) );
+
+ $wp_customize->add_control(
+ new WP_Customize_Control(
+ $wp_customize,
+ 'understrap_container_type', array(
+ 'label' => __( 'Container Width', 'understrap' ),
+ 'description' => __( 'Choose between Bootstrap\'s container and container-fluid', 'understrap' ),
+ 'section' => 'understrap_theme_layout_options',
+ 'settings' => 'understrap_container_type',
+ 'type' => 'select',
+ 'choices' => array(
+ 'container' => __( 'Fixed width container', 'understrap' ),
+ 'container-fluid' => __( 'Full width container', 'understrap' ),
+ ),
+ 'priority' => '10',
+ )
+ ) );
+
+ $wp_customize->add_setting( 'understrap_sidebar_position', array(
+ 'default' => 'right',
+ 'type' => 'theme_mod',
+ 'sanitize_callback' => 'sanitize_text_field',
+ 'capability' => 'edit_theme_options',
+ ) );
+
+ $wp_customize->add_control(
+ new WP_Customize_Control(
+ $wp_customize,
+ 'understrap_sidebar_position', array(
+ 'label' => __( 'Sidebar Positioning', 'understrap' ),
+ 'description' => __( 'Set sidebar\'s default position. Can either be: right, left, both or none. Note: this can be overridden on individual pages.',
+ 'understrap' ),
+ 'section' => 'understrap_theme_layout_options',
+ 'settings' => 'understrap_sidebar_position',
+ 'type' => 'select',
+ 'sanitize_callback' => 'understrap_theme_slug_sanitize_select',
+ 'choices' => array(
+ 'right' => __( 'Right sidebar', 'understrap' ),
+ 'left' => __( 'Left sidebar', 'understrap' ),
+ 'both' => __( 'Left & Right sidebars', 'understrap' ),
+ 'none' => __( 'No sidebar', 'understrap' ),
+ ),
+ 'priority' => '20',
+ )
+ ) );
+ }
+} // endif function_exists( 'understrap_theme_customize_register' ).
+add_action( 'customize_register', 'understrap_theme_customize_register' );
+
+/**
+ * Binds JS handlers to make Theme Customizer preview reload changes asynchronously.
+ */
+if ( ! function_exists( 'understrap_customize_preview_js' ) ) {
+ /**
+ * Setup JS integration for live previewing.
+ */
+ function understrap_customize_preview_js() {
+ wp_enqueue_script( 'understrap_customizer', get_template_directory_uri() . '/js/customizer.js',
+ array( 'customize-preview' ), '20130508', true
+ );
+ }
+}
+add_action( 'customize_preview_init', 'understrap_customize_preview_js' );
diff --git a/inc/editor.php b/inc/editor.php
new file mode 100644
index 0000000..4b71ee9
--- /dev/null
+++ b/inc/editor.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Understrap modify editor
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+/**
+ * Registers an editor stylesheet for the theme.
+ */
+
+add_action( 'admin_init', 'understrap_wpdocs_theme_add_editor_styles' );
+
+if ( ! function_exists ( 'understrap_wpdocs_theme_add_editor_styles' ) ) {
+ function understrap_wpdocs_theme_add_editor_styles() {
+ add_editor_style( 'css/custom-editor-style.min.css' );
+ }
+}
+
+// Add TinyMCE style formats.
+add_filter( 'mce_buttons_2', 'understrap_tiny_mce_style_formats' );
+
+if ( ! function_exists ( 'understrap_tiny_mce_style_formats' ) ) {
+ function understrap_tiny_mce_style_formats( $styles ) {
+
+ array_unshift( $styles, 'styleselect' );
+ return $styles;
+ }
+}
+
+
+add_filter( 'tiny_mce_before_init', 'understrap_tiny_mce_before_init' );
+
+if ( ! function_exists ( 'understrap_tiny_mce_before_init' ) ) {
+ function understrap_tiny_mce_before_init( $settings ) {
+
+ $style_formats = array(
+ array(
+ 'title' => 'Lead Paragraph',
+ 'selector' => 'p',
+ 'classes' => 'lead',
+ 'wrapper' => true
+ ),
+ array(
+ 'title' => 'Small',
+ 'inline' => 'small'
+ ),
+ array(
+ 'title' => 'Blockquote',
+ 'block' => 'blockquote',
+ 'classes' => 'blockquote',
+ 'wrapper' => true
+ ),
+ array(
+ 'title' => 'Blockquote Footer',
+ 'block' => 'footer',
+ 'classes' => 'blockquote-footer',
+ 'wrapper' => true
+ ),
+ array(
+ 'title' => 'Cite',
+ 'inline' => 'cite'
+ )
+ );
+
+ if ( isset( $settings['style_formats'] ) ) {
+ $orig_style_formats = json_decode($settings['style_formats'],true);
+ $style_formats = array_merge($orig_style_formats,$style_formats);
+ }
+
+ $settings['style_formats'] = json_encode( $style_formats );
+ return $settings;
+ }
+}
diff --git a/inc/enqueue.php b/inc/enqueue.php
new file mode 100644
index 0000000..a51937f
--- /dev/null
+++ b/inc/enqueue.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Understrap enqueue scripts
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+if ( ! function_exists( 'understrap_scripts' ) ) {
+ /**
+ * Load theme's JavaScript and CSS sources.
+ */
+ function understrap_scripts() {
+ // Get the theme data.
+ $the_theme = wp_get_theme();
+ $theme_version = $the_theme->get( 'Version' );
+
+ $css_version = $theme_version . '.' . filemtime(get_template_directory() . '/css/theme.css');
+ wp_enqueue_style( 'theme-styles', get_stylesheet_directory_uri() . '/css/theme.css', array(), $css_version );
+
+ wp_enqueue_script( 'jquery');
+
+ $js_version = $theme_version . '.' . filemtime(get_template_directory() . '/js/theme.min.js');
+ wp_enqueue_script( 'theme-scripts', get_template_directory_uri() . '/js/theme.min.js', array(), $js_version, true );
+ if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
+ wp_enqueue_script( 'comment-reply' );
+ }
+ }
+} // endif function_exists( 'understrap_scripts' ).
+
+add_action( 'wp_enqueue_scripts', 'understrap_scripts' );
diff --git a/inc/extras.php b/inc/extras.php
new file mode 100644
index 0000000..94f7485
--- /dev/null
+++ b/inc/extras.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Custom functions that act independently of the theme templates.
+ *
+ * Eventually, some of the functionality here could be replaced by core features.
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+add_filter( 'body_class', 'understrap_body_classes' );
+
+if ( ! function_exists( 'understrap_body_classes' ) ) {
+ /**
+ * Adds custom classes to the array of body classes.
+ *
+ * @param array $classes Classes for the body element.
+ *
+ * @return array
+ */
+ function understrap_body_classes( $classes ) {
+ // Adds a class of group-blog to blogs with more than 1 published author.
+ if ( is_multi_author() ) {
+ $classes[] = 'group-blog';
+ }
+ // Adds a class of hfeed to non-singular pages.
+ if ( ! is_singular() ) {
+ $classes[] = 'hfeed';
+ }
+
+ return $classes;
+ }
+}
+
+// Removes tag class from the body_class array to avoid Bootstrap markup styling issues.
+add_filter( 'body_class', 'understrap_adjust_body_class' );
+
+if ( ! function_exists( 'understrap_adjust_body_class' ) ) {
+ /**
+ * Setup body classes.
+ *
+ * @param string $classes CSS classes.
+ *
+ * @return mixed
+ */
+ function understrap_adjust_body_class( $classes ) {
+
+ foreach ( $classes as $key => $value ) {
+ if ( 'tag' == $value ) {
+ unset( $classes[ $key ] );
+ }
+ }
+
+ return $classes;
+
+ }
+}
+
+// Filter custom logo with correct classes.
+add_filter( 'get_custom_logo', 'understrap_change_logo_class' );
+
+if ( ! function_exists( 'understrap_change_logo_class' ) ) {
+ /**
+ * Replaces logo CSS class.
+ *
+ * @param string $html Markup.
+ *
+ * @return mixed
+ */
+ function understrap_change_logo_class( $html ) {
+
+ $html = str_replace( 'class="custom-logo"', 'class="img-fluid"', $html );
+ $html = str_replace( 'class="custom-logo-link"', 'class="navbar-brand custom-logo-link"', $html );
+ $html = str_replace( 'alt=""', 'title="Home" alt="logo"' , $html );
+
+ return $html;
+ }
+}
+
+/**
+ * Display navigation to next/previous post when applicable.
+ */
+
+if ( ! function_exists ( 'understrap_post_nav' ) ) {
+ function understrap_post_nav() {
+ // Don't print empty markup if there's nowhere to navigate.
+ $previous = ( is_attachment() ) ? get_post( get_post()->post_parent ) : get_adjacent_post( false, '', true );
+ $next = get_adjacent_post( false, '', false );
+
+ if ( ! $next && ! $previous ) {
+ return;
+ }
+ ?>
+ <nav class="container navigation post-navigation">
+ <h2 class="sr-only"><?php _e( 'Post navigation', 'understrap' ); ?></h2>
+ <div class="row nav-links justify-content-between">
+ <?php
+
+ if ( get_previous_post_link() ) {
+ previous_post_link( '<span class="col nav-previous text-left">%link</span>', _x( '<i class="fa fa-angle-left"></i>&nbsp;%title', 'Previous post link', 'understrap' ) );
+ }
+ if ( get_next_post_link() ) {
+ next_post_link( '<span class="col nav-next text-right">%link</span>', _x( '%title&nbsp;<i class="fa fa-angle-right"></i>', 'Next post link', 'understrap' ) );
+ }
+ ?>
+ </div><!-- .nav-links -->
+ </nav><!-- .navigation -->
+
+ <?php
+ }
+}
diff --git a/inc/hooks.php b/inc/hooks.php
new file mode 100644
index 0000000..8cd0b8d
--- /dev/null
+++ b/inc/hooks.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Custom hooks.
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+if ( ! function_exists( 'understrap_site_info' ) ) {
+ /**
+ * Add site info hook to WP hook library.
+ */
+ function understrap_site_info() {
+ #do_action( 'understrap_site_info' );
+ }
+}
+
+if ( ! function_exists( 'understrap_add_site_info' ) ) {
+ add_action( 'understrap_site_info', 'understrap_add_site_info' );
+
+ /**
+ * Add site info content.
+ */
+ function understrap_add_site_info() {
+ $the_theme = wp_get_theme();
+
+ $site_info = sprintf(
+ '<a href="%1$s">%2$s</a><span class="sep"> | </span>%3$s(%4$s)',
+ esc_url( __( 'http://wordpress.org/', 'understrap' ) ),
+ sprintf(
+ /* translators:*/
+ esc_html__( 'Proudly powered by %s', 'understrap' ), 'WordPress'
+ ),
+ sprintf( // WPCS: XSS ok.
+ /* translators:*/
+ esc_html__( 'Theme: %1$s by %2$s.', 'understrap' ), $the_theme->get( 'Name' ), '<a href="' . esc_url( __( 'http://understrap.com', 'understrap' ) ) . '">understrap.com</a>'
+ ),
+ sprintf( // WPCS: XSS ok.
+ /* translators:*/
+ esc_html__( 'Version: %1$s', 'understrap' ), $the_theme->get( 'Version' )
+ )
+ );
+
+ echo apply_filters( 'understrap_site_info_content', $site_info ); // WPCS: XSS ok.
+ }
+}
diff --git a/inc/jetpack.php b/inc/jetpack.php
new file mode 100644
index 0000000..1c2579c
--- /dev/null
+++ b/inc/jetpack.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Jetpack Compatibility File
+ *
+ * @link https://jetpack.me/
+ *
+ * @package UnderStrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+/**
+ * Jetpack setup function.
+ *
+ * See: https://jetpack.me/support/infinite-scroll/
+ * See: https://jetpack.me/support/responsive-videos/
+ */
+
+add_action( 'after_setup_theme', 'understrap_components_jetpack_setup' );
+
+if ( ! function_exists ( 'understrap_components_jetpack_setup' ) ) {
+ function understrap_components_jetpack_setup() {
+ // Add theme support for Infinite Scroll.
+ add_theme_support( 'infinite-scroll', array(
+ 'container' => 'main',
+ 'render' => 'understrap_components_infinite_scroll_render',
+ 'footer' => 'page',
+ ) );
+
+ // Add theme support for Responsive Videos.
+ add_theme_support( 'jetpack-responsive-videos' );
+
+ // Add theme support for Social Menus
+ add_theme_support( 'jetpack-social-menu' );
+
+ }
+}
+
+
+/**
+ * Custom render function for Infinite Scroll.
+ */
+
+if ( ! function_exists ( 'understrap_components_infinite_scroll_render' ) ) {
+ function understrap_components_infinite_scroll_render() {
+ while ( have_posts() ) {
+ the_post();
+ if ( is_search() ) :
+ get_template_part( 'loop-templates/content', 'search' );
+ else :
+ get_template_part( 'loop-templates/content', get_post_format() );
+ endif;
+ }
+ }
+}
+
+if ( ! function_exists ( 'understrap_components_social_menu' ) ) {
+ function understrap_components_social_menu() {
+ if ( ! function_exists( 'jetpack_social_menu' ) ) {
+ return;
+ } else {
+ jetpack_social_menu();
+ }
+ }
+} \ No newline at end of file
diff --git a/inc/pagination.php b/inc/pagination.php
new file mode 100644
index 0000000..9a6ff79
--- /dev/null
+++ b/inc/pagination.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Pagination layout.
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+if ( ! function_exists ( 'understrap_pagination' ) ) {
+
+ function understrap_pagination( $args = array(), $class = 'pagination' ) {
+
+ if ($GLOBALS['wp_query']->max_num_pages <= 1) return;
+
+ $args = wp_parse_args( $args, array(
+ 'mid_size' => 2,
+ 'prev_next' => true,
+ 'prev_text' => __('&laquo;', 'understrap'),
+ 'next_text' => __('&raquo;', 'understrap'),
+ 'screen_reader_text' => __('Posts navigation', 'understrap'),
+ 'type' => 'array',
+ 'current' => max( 1, get_query_var('paged') ),
+ ) );
+
+ $links = paginate_links($args);
+
+ ?>
+
+ <nav aria-label="<?php echo $args['screen_reader_text']; ?>">
+
+ <ul class="pagination">
+
+ <?php
+
+ foreach ( $links as $key => $link ) { ?>
+
+ <li class="page-item <?php echo strpos( $link, 'current' ) ? 'active' : '' ?>">
+
+ <?php echo str_replace( 'page-numbers', 'page-link', $link ); ?>
+
+ </li>
+
+ <?php } ?>
+
+ </ul>
+
+ </nav>
+
+ <?php
+ }
+}
+
+?>
diff --git a/inc/setup.php b/inc/setup.php
new file mode 100644
index 0000000..5118851
--- /dev/null
+++ b/inc/setup.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ * Theme basic setup.
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+// Set the content width based on the theme's design and stylesheet.
+if ( ! isset( $content_width ) ) {
+ $content_width = 640; /* pixels */
+}
+
+add_action( 'after_setup_theme', 'understrap_setup' );
+
+if ( ! function_exists ( 'understrap_setup' ) ) {
+ /**
+ * Sets up theme defaults and registers support for various WordPress features.
+ *
+ * Note that this function is hooked into the after_setup_theme hook, which
+ * runs before the init hook. The init hook is too late for some features, such
+ * as indicating support for post thumbnails.
+ */
+ function understrap_setup() {
+ /*
+ * Make theme available for translation.
+ * Translations can be filed in the /languages/ directory.
+ * If you're building a theme based on understrap, use a find and replace
+ * to change 'understrap' to the name of your theme in all the template files
+ */
+ load_theme_textdomain( 'understrap', 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' );
+
+ // This theme uses wp_nav_menu() in one location.
+ register_nav_menus( array(
+ 'primary' => __( 'Primary Menu', 'understrap' ),
+ ) );
+
+ /*
+ * Switch default core markup for search form, comment form, and comments
+ * to output valid HTML5.
+ */
+ add_theme_support( 'html5', array(
+ 'search-form',
+ 'comment-form',
+ 'comment-list',
+ 'gallery',
+ 'caption',
+ ) );
+
+ /*
+ * Adding Thumbnail basic support
+ */
+ add_theme_support( 'post-thumbnails' );
+
+ /*
+ * Adding support for Widget edit icons in customizer
+ */
+ add_theme_support( 'customize-selective-refresh-widgets' );
+
+ /*
+ * Enable support for Post Formats.
+ * See http://codex.wordpress.org/Post_Formats
+ */
+ add_theme_support( 'post-formats', array(
+ 'aside',
+ 'image',
+ 'video',
+ 'quote',
+ 'link',
+ ) );
+
+ // Set up the WordPress core custom background feature.
+ add_theme_support( 'custom-background', apply_filters( 'understrap_custom_background_args', array(
+ 'default-color' => 'ffffff',
+ 'default-image' => '',
+ ) ) );
+
+ // Set up the WordPress Theme logo feature.
+ add_theme_support( 'custom-logo' );
+
+ // Check and setup theme default settings.
+ understrap_setup_theme_default_settings();
+
+ }
+}
+
+
+add_filter( 'excerpt_more', 'understrap_custom_excerpt_more' );
+
+if ( ! function_exists( 'understrap_custom_excerpt_more' ) ) {
+ /**
+ * Removes the ... from the excerpt read more link
+ *
+ * @param string $more The excerpt.
+ *
+ * @return string
+ */
+ function understrap_custom_excerpt_more( $more ) {
+ return '';
+ }
+}
+
+add_filter( 'wp_trim_excerpt', 'understrap_all_excerpts_get_more_link' );
+
+if ( ! function_exists( 'understrap_all_excerpts_get_more_link' ) ) {
+ /**
+ * Adds a custom read more link to all excerpts, manually or automatically generated
+ *
+ * @param string $post_excerpt Posts's excerpt.
+ *
+ * @return string
+ */
+ function understrap_all_excerpts_get_more_link( $post_excerpt ) {
+
+ return $post_excerpt . ' <p><a class="btn btn-secondary understrap-read-more-link" href="' . esc_url( get_permalink( get_the_ID() )) . '#verkostung">' . __( 'Mehr lesen...',
+ 'understrap' ) . '</a></p>';
+ }
+}
diff --git a/inc/style-wpcom.css b/inc/style-wpcom.css
new file mode 100644
index 0000000..0b6da17
--- /dev/null
+++ b/inc/style-wpcom.css
@@ -0,0 +1,7 @@
+/*
+ * Theme Name: Components
+ *
+ * Add any WordPress.com-specific CSS here
+ *
+ * This file is enqueued in /inc/wpcom.php
+ */ \ No newline at end of file
diff --git a/inc/template-tags.php b/inc/template-tags.php
new file mode 100644
index 0000000..8ef2eb6
--- /dev/null
+++ b/inc/template-tags.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * Custom template tags for this theme.
+ *
+ * Eventually, some of the functionality here could be replaced by core features.
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+/**
+ * Prints HTML with meta information for the current post-date/time and author.
+ */
+if ( ! function_exists ( 'understrap_posted_on' ) ) {
+ function understrap_posted_on() {
+ $time_string = '<time class="entry-date published updated" datetime="%1$s">%2$s</time>';
+ $time_string = sprintf( $time_string,
+ esc_attr( get_the_date( 'c' ) ),
+ esc_html( get_the_date() )
+ );
+ /*
+ $time_string = '<time class="entry-date published updated" datetime="%1$s">%2$s</time>';
+ if ( get_the_time( 'U' ) !== get_the_modified_time( 'U' ) ) {
+ $time_string = '<time class="entry-date published" datetime="%1$s">%2$s</time><time class="updated" datetime="%3$s"> (%4$s) </time>';
+ }
+ $time_string = sprintf( $time_string,
+ esc_attr( get_the_date( 'c' ) ),
+ esc_html( get_the_date() ),
+ esc_attr( get_the_modified_date( 'c' ) ),
+ esc_html( get_the_modified_date() )
+ );
+ */
+ /*
+ $posted_on = sprintf(
+ //esc_html_x( 'Posted on %s', 'post date', 'understrap' ),
+ esc_html_x( 'Autor:', 'post date', 'understrap' ),
+ '<a class="text-muted" href="' . esc_url( get_permalink() ) . '" rel="bookmark">' . $time_string . '</a>'
+ );
+ */
+ $posted_on = '<a class="text-muted" href="' . esc_url( get_permalink() ) . '" rel="bookmark">' . $time_string . '</a>';
+ $byline = sprintf(
+ esc_html_x( 'Autor: %s', 'post author', 'understrap' ),
+ '<span class="author vcard"><a class="text-muted url fn n" href="' . esc_url( get_author_posts_url( get_the_author_meta( 'ID' ) ) ) . '">' . esc_html( get_the_author() ) . '</a></span>'
+ );
+ echo '<span class="text-muted"><span class="byline"> ' . $byline . '</span> | <span class="posted-on">' . $posted_on . '</span> | <a class="text-muted" href="' . esc_url( get_permalink() ) . '#comments">'; comments_number("0 Kommentare", "1 Kommentar", "% Kommentare"); echo '</a></span>'; // WPCS: XSS OK.
+ }
+}
+
+
+/**
+ * Prints HTML with meta information for the categories, tags and comments.
+ */
+if ( ! function_exists ( 'understrap_entry_footer' ) ) {
+ function understrap_entry_footer() {
+ // Hide category and tag text for pages.
+ if ( 'post' === get_post_type() ) {
+ /* translators: used between list items, there is a space after the comma */
+ $categories_list = get_the_category_list( esc_html__( ', ', 'understrap' ) );
+ if ( $categories_list && understrap_categorized_blog() ) {
+ printf( '<span class="cat-links text-muted col-sm col-xl-6"><i class="material-icons text-muted tag-category-icon">folder</i> ' . esc_html__( '%1$s', 'understrap' ) . '</span>', $categories_list ); // WPCS: XSS OK.
+ }
+ /* translators: used between list items, there is a space after the comma */
+ $tags_list = get_the_tag_list( '', esc_html__( ', ', 'understrap' ) );
+ if ( $tags_list ) {
+ printf( '<span class="tags-links text-right-xs col-sm col-xl-6"><i class="material-icons text-muted tag-category-icon">label</i>' . esc_html__( '%1$s', 'understrap' ) . '</span>', $tags_list ); // WPCS: XSS OK.
+ }
+ }
+ /*
+ if ( ! is_single() && ! post_password_required() && ( comments_open() || get_comments_number() ) ) {
+ echo '<span class="comments-link">';
+ comments_popup_link( esc_html__( 'Leave a comment', 'understrap' ), esc_html__( '1 Comment', 'understrap' ), esc_html__( '% Comments', 'understrap' ) );
+ echo '</span>';
+ }
+ */
+ # /* translators: %s: Name of current post */
+ /*
+ edit_post_link(
+ sprintf(
+ esc_html__( 'Edit %s', 'understrap' ),
+ the_title( '<span class="screen-reader-text">"', '"</span>', false )
+ ),
+ '<span class="edit-link">',
+ '</span>'
+ );
+ */
+ }
+}
+
+
+/**
+ * Returns true if a blog has more than 1 category.
+ *
+ * @return bool
+ */
+if ( ! function_exists ( 'understrap_categorized_blog' ) ) {
+ function understrap_categorized_blog() {
+ if ( false === ( $all_the_cool_cats = get_transient( 'understrap_categories' ) ) ) {
+ // Create an array of all the categories that are attached to posts.
+ $all_the_cool_cats = get_categories( array(
+ 'fields' => 'ids',
+ 'hide_empty' => 1,
+ // We only need to know if there is more than one category.
+ 'number' => 2,
+ ) );
+ // Count the number of categories that are attached to the posts.
+ $all_the_cool_cats = count( $all_the_cool_cats );
+ set_transient( 'understrap_categories', $all_the_cool_cats );
+ }
+ if ( $all_the_cool_cats > 1 ) {
+ // This blog has more than 1 category so components_categorized_blog should return true.
+ return true;
+ } else {
+ // This blog has only 1 category so components_categorized_blog should return false.
+ return false;
+ }
+ }
+}
+
+
+/**
+ * Flush out the transients used in understrap_categorized_blog.
+ */
+add_action( 'edit_category', 'understrap_category_transient_flusher' );
+add_action( 'save_post', 'understrap_category_transient_flusher' );
+
+if ( ! function_exists ( 'understrap_category_transient_flusher' ) ) {
+ function understrap_category_transient_flusher() {
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
+ return;
+ }
+ // Like, beat it. Dig?
+ delete_transient( 'understrap_categories' );
+ }
+}
diff --git a/inc/theme-settings.php b/inc/theme-settings.php
new file mode 100755
index 0000000..9bee616
--- /dev/null
+++ b/inc/theme-settings.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Check and setup theme's default settings
+ *
+ * @package understrap
+ *
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+if ( ! function_exists ( 'understrap_setup_theme_default_settings' ) ) {
+ function understrap_setup_theme_default_settings() {
+
+ // check if settings are set, if not set defaults.
+ // Caution: DO NOT check existence using === always check with == .
+ // Latest blog posts style.
+ $understrap_posts_index_style = get_theme_mod( 'understrap_posts_index_style' );
+ if ( '' == $understrap_posts_index_style ) {
+ set_theme_mod( 'understrap_posts_index_style', 'default' );
+ }
+
+ // Sidebar position.
+ $understrap_sidebar_position = get_theme_mod( 'understrap_sidebar_position' );
+ if ( '' == $understrap_sidebar_position ) {
+ set_theme_mod( 'understrap_sidebar_position', 'right' );
+ }
+
+ // Container width.
+ $understrap_container_type = get_theme_mod( 'understrap_container_type' );
+ if ( '' == $understrap_container_type ) {
+ set_theme_mod( 'understrap_container_type', 'container' );
+ }
+ }
+} \ No newline at end of file
diff --git a/inc/widgets.php b/inc/widgets.php
new file mode 100644
index 0000000..fdd6611
--- /dev/null
+++ b/inc/widgets.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Declaring widgets
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+/**
+ * Count number of widgets in a sidebar
+ * Used to add classes to widget areas so widgets can be displayed one, two, three or four per row
+ */
+if ( ! function_exists( 'understrap_slbd_count_widgets' ) ) {
+ function understrap_slbd_count_widgets( $sidebar_id ) {
+ // If loading from front page, consult $_wp_sidebars_widgets rather than options
+ // to see if wp_convert_widget_settings() has made manipulations in memory.
+ global $_wp_sidebars_widgets;
+ if ( empty( $_wp_sidebars_widgets ) ) :
+ $_wp_sidebars_widgets = get_option( 'sidebars_widgets', array() );
+ endif;
+
+ $sidebars_widgets_count = $_wp_sidebars_widgets;
+
+ if ( isset( $sidebars_widgets_count[ $sidebar_id ] ) ) :
+ $widget_count = count( $sidebars_widgets_count[ $sidebar_id ] );
+ $widget_classes = 'widget-count-' . count( $sidebars_widgets_count[ $sidebar_id ] );
+ if ( $widget_count % 4 == 0 || $widget_count > 6 ) :
+ // Four widgets per row if there are exactly four or more than six
+ $widget_classes .= ' col-md-3';
+ elseif ( 6 == $widget_count ) :
+ // If two widgets are published
+ $widget_classes .= ' col-md-2';
+ elseif ( $widget_count >= 3 ) :
+ // Three widgets per row if there's three or more widgets
+ $widget_classes .= ' col-md-4';
+ elseif ( 2 == $widget_count ) :
+ // If two widgets are published
+ $widget_classes .= ' col-md-6';
+ elseif ( 1 == $widget_count ) :
+ // If just on widget is active
+ $widget_classes .= ' col-md-12';
+ endif;
+ return $widget_classes;
+ endif;
+ }
+}
+
+add_action( 'widgets_init', 'understrap_widgets_init' );
+
+if ( ! function_exists( 'understrap_widgets_init' ) ) {
+ /**
+ * Initializes themes widgets.
+ */
+ function understrap_widgets_init() {
+ register_sidebar( array(
+ 'name' => __( 'Right Sidebar', 'understrap' ),
+ 'id' => 'right-sidebar',
+ 'description' => __( 'Right sidebar widget area', 'understrap' ),
+ 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
+ 'after_widget' => '</aside>',
+ 'before_title' => '<h3 class="widget-title">',
+ 'after_title' => '</h3>',
+ ) );
+
+ register_sidebar( array(
+ 'name' => __( 'Left Sidebar', 'understrap' ),
+ 'id' => 'left-sidebar',
+ 'description' => __( 'Left sidebar widget area', 'understrap' ),
+ 'before_widget' => '<aside id="%1$s" class="widget %2$s">',
+ 'after_widget' => '</aside>',
+ 'before_title' => '<h3 class="widget-title">',
+ 'after_title' => '</h3>',
+ ) );
+
+ register_sidebar( array(
+ 'name' => __( 'Hero Slider', 'understrap' ),
+ 'id' => 'hero',
+ 'description' => __( 'Hero slider area. Place two or more widgets here and they will slide!', 'understrap' ),
+ 'before_widget' => '<div class="carousel-item">',
+ 'after_widget' => '</div>',
+ 'before_title' => '',
+ 'after_title' => '',
+ ) );
+
+ register_sidebar( array(
+ 'name' => __( 'Hero Canvas', 'understrap' ),
+ 'id' => 'herocanvas',
+ 'description' => __( 'Full size canvas hero area for Bootstrap and other custom HTML markup', 'understrap' ),
+ 'before_widget' => '',
+ 'after_widget' => '',
+ 'before_title' => '',
+ 'after_title' => '',
+ ) );
+
+ register_sidebar( array(
+ 'name' => __( 'Top Full', 'understrap' ),
+ 'id' => 'statichero',
+ 'description' => __( 'Full top widget with dynamic grid', 'understrap' ),
+ 'before_widget' => '<div id="%1$s" class="static-hero-widget %2$s '. understrap_slbd_count_widgets( 'statichero' ) .'">',
+ 'after_widget' => '</div><!-- .static-hero-widget -->',
+ 'before_title' => '<h3 class="widget-title">',
+ 'after_title' => '</h3>',
+ ) );
+
+ register_sidebar( array(
+ 'name' => __( 'Footer Full', 'understrap' ),
+ 'id' => 'footerfull',
+ 'description' => __( 'Full sized footer widget with dynamic grid', 'understrap' ),
+ 'before_widget' => '<div id="%1$s" class="footer-widget %2$s '. understrap_slbd_count_widgets( 'footerfull' ) .'">',
+ 'after_widget' => '</div><!-- .footer-widget -->',
+ 'before_title' => '<h3 class="widget-title">',
+ 'after_title' => '</h3>',
+ ) );
+
+ }
+} // endif function_exists( 'understrap_widgets_init' ).
diff --git a/inc/woocommerce.php b/inc/woocommerce.php
new file mode 100644
index 0000000..3cd8e9b
--- /dev/null
+++ b/inc/woocommerce.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Add WooCommerce support
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+add_action( 'after_setup_theme', 'understrap_woocommerce_support' );
+if ( ! function_exists( 'understrap_woocommerce_support' ) ) {
+ /**
+ * Declares WooCommerce theme support.
+ */
+ function understrap_woocommerce_support() {
+ add_theme_support( 'woocommerce' );
+
+ // Add New Woocommerce 3.0.0 Product Gallery support
+ add_theme_support( 'wc-product-gallery-lightbox' );
+ add_theme_support( 'wc-product-gallery-zoom' );
+ add_theme_support( 'wc-product-gallery-slider' );
+
+ // hook in and customizer form fields.
+ add_filter( 'woocommerce_form_field_args', 'understrap_wc_form_field_args', 10, 3 );
+ }
+}
+
+/**
+* First unhook the 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);
+
+/**
+* Then hook in your own functions to display the wrappers your theme requires
+*/
+add_action('woocommerce_before_main_content', 'understrap_woocommerce_wrapper_start', 10);
+add_action('woocommerce_after_main_content', 'understrap_woocommerce_wrapper_end', 10);
+if ( ! function_exists( 'understrap_woocommerce_wrapper_start' ) ) {
+ function understrap_woocommerce_wrapper_start() {
+ $container = get_theme_mod( 'understrap_container_type' );
+ echo '<div class="wrapper" id="woocommerce-wrapper">';
+ echo '<div class="' . esc_attr( $container ) . '" id="content" tabindex="-1">';
+ echo '<div class="row">';
+ get_template_part( 'global-templates/left-sidebar-check' );
+ echo '<main class="site-main" id="main">';
+ }
+}
+if ( ! function_exists( 'understrap_woocommerce_wrapper_end' ) ) {
+function understrap_woocommerce_wrapper_end() {
+ echo '</main><!-- #main -->';
+ get_template_part( 'global-templates/right-sidebar-check' );
+ echo '</div><!-- .row -->';
+ echo '</div><!-- Container end -->';
+ echo '</div><!-- Wrapper end -->';
+ }
+}
+
+
+/**
+ * Filter hook function monkey patching form classes
+ * Author: Adriano Monecchi http://stackoverflow.com/a/36724593/307826
+ *
+ * @param string $args Form attributes.
+ * @param string $key Not in use.
+ * @param null $value Not in use.
+ *
+ * @return mixed
+ */
+if ( ! function_exists ( 'understrap_wc_form_field_args' ) ) {
+ function understrap_wc_form_field_args( $args, $key, $value = null ) {
+ // Start field type switch case.
+ switch ( $args['type'] ) {
+ /* Targets all select input type elements, except the country and state select input types */
+ case 'select' :
+ // Add a class to the field's html element wrapper - woocommerce
+ // input types (fields) are often wrapped within a <p></p> tag.
+ $args['class'][] = 'form-group';
+ // Add a class to the form input itself.
+ $args['input_class'] = array( 'form-control', 'input-lg' );
+ $args['label_class'] = array( 'control-label' );
+ $args['custom_attributes'] = array(
+ 'data-plugin' => 'select2',
+ 'data-allow-clear' => 'true',
+ 'aria-hidden' => 'true',
+ // Add custom data attributes to the form input itself.
+ );
+ break;
+ // By default WooCommerce will populate a select with the country names - $args
+ // defined for this specific input type targets only the country select element.
+ case 'country' :
+ $args['class'][] = 'form-group single-country';
+ $args['label_class'] = array( 'control-label' );
+ break;
+ // By default WooCommerce will populate a select with state names - $args defined
+ // for this specific input type targets only the country select element.
+ case 'state' :
+ // Add class to the field's html element wrapper.
+ $args['class'][] = 'form-group';
+ // add class to the form input itself.
+ $args['input_class'] = array( '', 'input-lg' );
+ $args['label_class'] = array( 'control-label' );
+ $args['custom_attributes'] = array(
+ 'data-plugin' => 'select2',
+ 'data-allow-clear' => 'true',
+ 'aria-hidden' => 'true',
+ );
+ break;
+ case 'password' :
+ case 'text' :
+ case 'email' :
+ case 'tel' :
+ case 'number' :
+ $args['class'][] = 'form-group';
+ $args['input_class'] = array( 'form-control', 'input-lg' );
+ $args['label_class'] = array( 'control-label' );
+ break;
+ case 'textarea' :
+ $args['input_class'] = array( 'form-control', 'input-lg' );
+ $args['label_class'] = array( 'control-label' );
+ break;
+ case 'checkbox' :
+ $args['label_class'] = array( 'custom-control custom-checkbox' );
+ $args['input_class'] = array( 'custom-control-input', 'input-lg' );
+ break;
+ case 'radio' :
+ $args['label_class'] = array( 'custom-control custom-radio' );
+ $args['input_class'] = array( 'custom-control-input', 'input-lg' );
+ break;
+ default :
+ $args['class'][] = 'form-group';
+ $args['input_class'] = array( 'form-control', 'input-lg' );
+ $args['label_class'] = array( 'control-label' );
+ break;
+ } // end switch ($args).
+ return $args;
+ }
+} \ No newline at end of file
diff --git a/inc/wpcom.php b/inc/wpcom.php
new file mode 100644
index 0000000..ca42c38
--- /dev/null
+++ b/inc/wpcom.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * WordPress.com-specific functions and definitions
+ *
+ * This file is centrally included from `wp-content/mu-plugins/wpcom-theme-compat.php`.
+ *
+ * @package understrap
+ */
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
+}
+
+/**
+ * Adds support for wp.com-specific theme functions.
+ *
+ * @global array $themecolors
+ */
+add_action( 'after_setup_theme', 'understrap_wpcom_setup' );
+
+if ( ! function_exists ( 'understrap_wpcom_setup' ) ) {
+ function understrap_wpcom_setup() {
+ global $themecolors;
+
+ // Set theme colors for third party services.
+ if ( ! isset( $themecolors ) ) {
+ $themecolors = array(
+ 'bg' => '',
+ 'border' => '',
+ 'text' => '',
+ 'link' => '',
+ 'url' => '',
+ );
+ }
+
+ /* Add WP.com print styles */
+ add_theme_support( 'print-styles' );
+ }
+}
+
+
+/*
+ * WordPress.com-specific styles
+ */
+add_action( 'wp_enqueue_scripts', 'understrap_wpcom_styles' );
+
+if ( ! function_exists ( 'understrap_wpcom_styles' ) ) {
+ function understrap_wpcom_styles() {
+ wp_enqueue_style( 'understrap-wpcom', get_template_directory_uri() . '/inc/style-wpcom.css', '20160411' );
+ }
+} \ No newline at end of file