Tag: Theme Editing

Understrap Sub Menu Depth

Understrap supports sub menus in their navbars, however what happens if the sub menus have sub menus of their own?

Unfortunately Understrap only supports collapsable menus of depth 2 (meaning that you can’t make the sub sub-menus collapsable).

This is how to increase the depth of your menus by displaying them when the dropdown sub menu containing them is expanded.

First import the file “class-wp-bootstrap-navwalker.php” from the Understrap parent theme under “\inc\class-wp-bootstrap-navwalker.php”

Then alter this line of code within:

// 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';
				}
			}

Into this by removing ” && 0 === $depth”:

// If item has_children add atts to <a>.
			if ( isset( $args->has_children ) && $args->has_children && $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';
				}
			}

Then add to your header (or wherever else your adding your navbar) a dropdown menu of depth 3:

			<div class="container">
				<?php wp_nav_menu(
	array(
		'theme_location'  => 'secondary',
		'container_class' => 'collapse navbar-collapse',
		'container_id'    => 'navbarNavDropdown',
		'menu_class'      => 'navbar-nav mx-auto',
		'fallback_cb'     => '',
		'menu_id'         => 'secondary',
		'depth'           => 3,
		'walker'          => new Understrap_WP_Bootstrap_Navwalker(),
	)
); ?>
			</div>

Then finally add the following Additional CSS:

/**
 * Forces sub-sub menu's
 * to display when sub menu
 * is displayed!
 */
ul.dropdown-menu li > ul.dropdown-menu{
    display: inline-grid;
}
ul.dropdown-menu li>ul {
    position: static!important;
}

And you should get something like this:

Filed under: WordPressTagged with: , , ,

Understrap Entry Footer Widget Area

How to add a new custom Widget Area to an Understrap Child Theme

First simply register a new widget by adding this code within “functions.php”:

/**
 * Registers the "authors" widget area.
 */
add_action( 'widgets_init', 'authors_widgets_init' );
function authors_widgets_init() {
	
	register_sidebar( array(
  'id'            => 'authors',
  'name'          => __( 'Authors', 'understrap' ),
  'description'   => __( 'Widgets in this area will be shown after posts and pages for the purpose of listing the co-authors and date of publishing.', 'understrap' ),
  'before_widget' => '<aside id="%1$s" class="widget %2$s">',
  'after_widget'  => '</aside>',
  'before_title'  => '<h3 class="widget-title">',
  'after_title'   => '</h3>',
) );
}

Heres the widget area resulting from that code:

Show widget area in entry-footer of all posts & pages

Next to make your new custom Widget Area appear in the “entry-footer”.

This means below pages, posts and even under each post in an archive of posts.

How to show widget area in entry-footer of all posts

First I imported and then altered the file “inc > template-tags.php” (which you can find and copy from the Understrap parent theme).

Before:

/**
 * 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() ) {
				/* translators: %s: Categories of current post */
				printf( '<span class="cat-links">' . esc_html__( 'Posted in %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 ) {
				/* translators: %s: Tags of current post */
				printf( '<span class="tags-links">' . esc_html__( 'Tagged %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>';
		}
		edit_post_link(
			sprintf(
				/* translators: %s: Name of current post */
				esc_html__( 'Edit %s', 'understrap' ),
				the_title( '<span class="screen-reader-text">"', '"</span>', false )
			),
			'<span class="edit-link">',
			'</span>'
		);
	}
}

After:


/**
 * 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() ) {
				/* translators: %s: Categories of current post */
				printf( '<span class="cat-links">' . esc_html__( 'Posted in %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 ) {
				/* translators: %s: Tags of current post */
				printf( '<span class="tags-links">' . esc_html__( 'Tagged %s', 'understrap' ) . '</span>', $tags_list ); // WPCS: XSS OK.
			}
		}
		
		
		/**
		 * adds the "authors" widget area!!!
		 */
		if ( !function_exists( 'dynamic_sidebar' ) || !dynamic_sidebar('authors') )
		
		
		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>';
		}
		edit_post_link(
			sprintf(
				/* translators: %s: Name of current post */
				esc_html__( 'Edit %s', 'understrap' ),
				the_title( '<span class="screen-reader-text">"', '"</span>', false )
			),
			'<span class="edit-link">',
			'</span>'
		);
	}
}

How to remove entry footers from posts in post archives

Next I imported and then altered the file “loop-templates > content.php”.

Here I simply commented out this code:

<?php understrap_entry_footer(); ?>

How to show widget area in “entry-footer” of pages

Finally I imported and then altered the file “loop-templates > content-page.php”.

Before:

	<footer class="entry-footer">

		<?php edit_post_link( __( 'Edit', 'understrap' ), '<span class="edit-link">', '</span>' ); ?>

	</footer><!-- .entry-footer -->

After:

	<footer class="entry-footer">
		
		<?php
  if ( !function_exists( 'dynamic_sidebar' ) || !dynamic_sidebar('authors') )
?>

		<?php edit_post_link( __( 'Edit', 'understrap' ), '<span class="edit-link">', '</span>' ); ?>

	</footer><!-- .entry-footer -->
Filed under: WordPressTagged with: , , ,

Adding Log In/Out Links

After figuring out how to change the “site-info” in the Understrap theme I decided to add log in and log out buttons.

These visible based on if the user is already logged in or not.

It also dynamically gets the site url so that this code can be reused on sites with little changed.

To do this simply add the following code to “functions.php” of your child theme:

/**
 * Changes "site-info" to our boilerplate copyright.
 * Also adds Log In and Log Out links.
 */
function remove_parent_functions() {
    remove_action( 'understrap_site_info', 'understrap_add_site_info' );
    add_action( 'understrap_site_info', 'understrap_add_site_child_info' );
}
add_action( 'init', 'remove_parent_functions', 15 );
function understrap_add_site_child_info() {
	
	if(is_user_logged_in()) {
		?>
    <div class="wrap"><p>Site commissioned from Tees Valley Arts &nbsp; ⁄ &nbsp; Copyright ©&nbsp;2021 &nbsp; ⁄ &nbsp; <a rel="nofollow" href=<?php echo get_site_url().'/wp-login.php?action=logout&amp;_wpnonce=5969d1c9bc' ?>>Log out</a></p></div>
    <?php
	} else {
		?>

    <div class="wrap"><p>Site commissioned from Tees Valley Arts &nbsp; ⁄ &nbsp; Copyright ©&nbsp;2021 &nbsp; ⁄ &nbsp; <a rel="nofollow" href=<?php echo get_site_url().'/wp-login.php' ?>>Log in</a></p></div>
    <?php
	}
}

Filed under: WordPressTagged with: , , ,

Changing Understrap “site-info”

Now the organisation I volunteer at is moving over to a bootstrap based theme named “Understrap”.

When fiddling with the official “Understrap Child Theme” I figured out a few of my old tricks.

In order to change the annoying copyright info in “site-footer” what you’ll actually want to aim at is “site-info”.

I accomplished that by adding this code to my child themes “functions.php”:

/**
 * Changes "site-info" to our boilerplate copyright.
 * Also adds Log In and Log Out links.
 */
function remove_parent_functions() {
    remove_action( 'understrap_site_info', 'understrap_add_site_info' );
    add_action( 'understrap_site_info', 'understrap_add_site_child_info' );
}
add_action( 'init', 'remove_parent_functions', 15 );
function understrap_add_site_child_info() {
    //your new site footer here.
}

Filed under: WordPressTagged with: , , ,

Scheduling Functions (Cron Jobs)

Now that I’ve created a way to compile a list of how many comments I get from various countrys I wanted to run it automatically.

When I mentioned this to the head IT guy in Tees Valley Arts he suggested I use a “cron job”.

This can be done by first adding a hook for the cron job to run.

/**
 * Adds the "cron_hook" action hook.
 * This is then called by a cron job.
 */
add_action( 'cron_hook', 'location_list_shortcode' );

Then I decided to be lazy and simply use the plugin “Advanced Cron Manager”.

Once installed it can be found under “Tools”.

There sou simply add a new event.

Then you input your hook and when it should run.

Now my list of countries I get comments from is updated daily without any input from myself!

Filed under: WordPressTagged with: , , , ,

Improved Country Counter

New and improved function for counting the amount of comments from various countries.

Now stores also stores the information by updating an existing row within an existing database table named “locations”.

/**
 * Adds the "location_list" shortcode.
 * [location_list]
 */
add_shortcode('location_list', 'location_list_shortcode');
/*
 * Lists locations I have recieved comments from.
 * 
 * Also stores it in the "locations" table.
 */
function location_list_shortcode() {
	$list_of_locations1 = array();
	$comments = get_comments();
	//LOOP THROUGH COMMENTS CHECKING LOCATIONS
	for($a = 0; $a < count($comments); $a++) {
		//TOO MANY REQUESTS IN 1 MINUTE GETS YOU BLOCKED FROM USING GEOPLUGIN FOR 1 HOUR!!
		//if a is a multiple of 50 then wait 1 minute
		if($a % 50 == 0) {
			// sleep for 60 seconds
			sleep(60);
		}
		$comment = $comments[$a];
		$comment_ip = $comment->comment_author_IP;
		$geopluginURL = 'http://www.geoplugin.net/php.gp?ip=' . $comment_ip;
		$geoip_response = unserialize( file_get_contents( $geopluginURL ) );
		if ( ! empty( $geoip_response ) ) {
			$location = $geoip_response['geoplugin_countryName'];
			$list_of_locations1[] = $location; 
		}
	}
	//creates array of unique names and how often they were used
	$locations_without_duplicates = array_count_values($list_of_locations1);
	//splits the array into names and numbers
	$names = array_keys($locations_without_duplicates);
	$values = array_values($locations_without_duplicates);
	$resultz = "";
	//combines the 2 arrays into a single string.
	for($b = 0; $b < count($names); $b++) {
		if($b != 0) {
			$resultz .= ", ";
		}
		$resultz .= $names[$b];
		$resultz .= " = ";
		$resultz .= $values[$b];
	}
	//Updates the 1 row in the locations table
	global $wpdb;
	$sql = "UPDATE `locations` SET `location`='";
	$sql .= $resultz;
	$sql .="' WHERE `location` IS NOT NULL;";
	require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
	dbDelta( $sql );
	//return result string.
	return $resultz;
}

Once stored this row can be quickly accessed and displayed to visitors of the site using this simple shortcode.

/**
 * Adds the "read_locations" shortcode.
 * [read_locations]
 */
add_shortcode('read_locations', 'read_locations');


/**
 * Reads the rows of the "locations" table.
 */
function read_locations() {
	global $wpdb;
	$row = $wpdb->get_results("SELECT * FROM `locations` LIMIT 1");
	$result = $row[0];
	return implode(get_object_vars($result));
}

As seen here:

Germany = 2, United Kingdom = 2, Israel = 1, Ukraine = 5
Filed under: WordPressTagged with: , ,

Counting Comments From Countries

I finally figured out how to automatically generate a list of countries that users have commented from along with how many have come from each.

This can be accomplished simply by adding this code to functions.php and then using the shortcode.

/**
 * Adds the "location_list" shortcode.
 * [location_list]
 */
add_shortcode('location_list', 'location_list_shortcode');

/*
 * Lists locations I have recieved comments from.
 * 
 * How should I store this info so it can be quickly displayed to the user?
 * 
 * database? (have a single string in a table, 
 * have a function which updates that specific row)
 * 
 */
function location_list_shortcode() {
	$list_of_locations1 = array();
	
	$comments = get_comments();
	
	//LOOP THROUGH COMMENTS CHECKING LOCATIONS
	for($a = 0; $a < count($comments); $a++) {
		//if a is a multiple of 50 then wait 1 minute
		//TOO MANY REQUESTS IN 1 MINUTE GETS ME BLOCKED FROM USING GEOPLUGIN FOR 1 HOUR!!
		if($a % 50 == 0) {
			// sleep for 60 seconds
			sleep(60);
		}
		
		$comment = $comments[$a]; //THE ID's OF COMMENTS: 375, 357, 136, 132, 130, 73, 72, 66
		
		$comment_ip = $comment->comment_author_IP;

		$geopluginURL = 'http://www.geoplugin.net/php.gp?ip=' . $comment_ip;

		$geoip_response = unserialize( file_get_contents( $geopluginURL ) );

		if ( ! empty( $geoip_response ) ) {
			$location = $geoip_response['geoplugin_countryName'];

			$list_of_locations1[] = $location; 
		}
	}

	//creates array of unique names and how often they were used
	$locations_without_duplicates = array_count_values($list_of_locations1);
	
	$names = array_keys($locations_without_duplicates);
	$values = array_values($locations_without_duplicates);
	$resultz = "";
	
	for($b = 0; $b < count($names); $b++) {
		if($b != 0) {
			$resultz .= ", ";
		}
		$resultz .= $names[$b];
		$resultz .= " = ";
		$resultz .= $values[$b];
	}
	return $resultz;
}

Now I just have to figure out where I’m going to store this info so I don’t make the user wait 1-3 minutes for the shortcode to calculate this whenever they view the page I put it in.

Filed under: WordPressTagged with: , ,

Removing “Menu” From Burger Menu

After implementing a “Burger” menu you may notice that the word “Menu” is shown besides the ≡ symbol when viewed in mobile.

This can be removed from the Beans theme using this code:

/**
 * Getting rid of arrow on dropdown menu when viewed on mobile.
 */
beans_remove_action( 'beans_primary_menu_offcanvas_button' );
add_action( 'beans_primary_menu_append_markup', 'myfunction' );
function myfunction() {
?><a href="#offcanvas_menu" class="uk-button uk-hidden-large your-class-name" data-uk-offcanvas="" data-markup-id="beans_primary_menu_offcanvas_button"><i class="uk-icon-navicon uk-margin-small-right" data-markup-id="beans_primary_menu_offcanvas_button_icon"></i><!-- open output: beans_offcanvas_menu_button --><!--where "Menu" was --!><!-- close output: beans_offcanvas_menu_button --></a>
<?php }
Filed under: WordPressTagged with: , ,