The main reason for adding this addition to your WordPress Theme is best said by its author [Git Link]
“A custom WordPress Nav Walker Class to fully implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager.”
By implementing this code, you will be changing how the menus are generated by WordPress. This will allow the incorporation of Bootstrap 4 styling and standards found on a pure Bootstrap built website. This addition should be pair with an installation of Bootstrap by Twitter [Link] and a consideration for using a Bootstrap focused design.
Please check out “ADDING BOOTSTRAP TO AN UNDERSCORES THEME” for a detailed guide demonstrating how to add and create a brand new underscores theme with a bootstrap integration.
Downloading the Navwalker Files
Lets head over to the main Git Repo for WP Bootstrap Navwalker [Link]. Go ahead and download a copy of repository and open the downloaded Zip file.
Open the downloaded Zip and select the file called:
class-wp-bootstrap-navwalker.php
Place this file in your active theme folder, or the theme folder you plan to use. File Path should look like so:
Now that your file has been added to your theme we can start hooking up the Navwalker to your Menus, First lets head over to the functions.php file located in the theme folder – and add the following code:
Lets take a second to look at what we have completed. First, we added the files needed to use WP Navwalker with our theme, added the code necessary to connect the new WP Navwalker file to our WordPress Theme, and for our last step we will create a Menu (most likely located in the header.php file) that will use WP Navwalker!
To update any Wordpress Menu in your theme with the newly added Navwalker use the new wp_nav_menu argument by adding a ‘walker’ item to the wp_nav_menu args array.
You menu will now implement the same drop down features found in the Bootstrap by Twitter examples!
Typically additional markup is added to these menus, here is an example of a fixed-top menu that collapse for responsive navigation at the md breakpoint. Additional menu options can also be found in the Bootstrap documentation as well [Link]
I reviewed some recent client Classic ASP code and found a 4 level deep branching of an IF statement. Reading the code, its intent is to look at the object type and return an icon representing the type.
<%
if obj.type = "car" then
response.write("<img src="/images/icons/car.png" />")
ElseIf obj.type = "boat" then
response.write("<img src="/images/icons/boat.png" />")
ElseIf obj.type = "bike" then
response.write("<img src="/images/icons/bike.png" />")
Else
response.write("<img src="/images/icons/placeholder.png" />")
%>
I try to stay away from IF statements altogether but using a SINGLE if statement is something I do use. However, once the IF statement gets past 2 branches, I consider this a CODE SMELL it requires refactoring.
I am going to break my thoughts into small code refactorings so you can understand each step. each step in itself is an improvement to the code, but combined, it will help make changes for the client easier and less prone to bugs.
Step 1
Taking a look at the above code, I notice we are repeating the IMAGE SRC path. So let’s see if we can make better.
Now, we are still repeating the response.write(" block several times. Let’s refactor the IF statement to only have logic about the obj.type.
<%
Dim imgSrc, img
imgSrc = "/images/icons/"
img = "placeholder.png"
if obj.type = "car" then img = "car.png"
if obj.type = "boat" then img = "boat.png"
if obj.type = "bike" then img = "bike.png"
response.write("<img src='" & imgSrc & img & "'" />")
%>
Refactoring Results
The code is much easier to read and to maintain. We can easily add more branches without thinking of the rest of the logic. A non-programmer can look at this code and figure out how to add more images or even change the root path to the images.
In the next post, we will extract the IF statements into a Classic ASP Function.
I the last blog post Converting Recordset into Objects in Classic ASP we created a public function initialize(rs) which takes in a single row from the database and creates a single class object account. Our goal is to add a new property named fullname where we combine firstname and lastname
We will update the public function initialize(rs) as follows:
public function initialize(rs)
dim row
set row = New account
row.id = rs("id")
row.guid = rs("guid")
row.lastName = rs("lastName")
row.firstName = rs("firstName")
row.fullname = rs("firstName") & ", " & rs("firstName")
row.email = rs("email")
row.password = rs("password")
row.passwordSalt = rs("passwordSalt")
row.clientId = rs("clientId")
row.administrator = rs("administrator")
row.lastLogin = rs("lastLogin")
row.created = rs("created")
row.modified = rs("modified")
row.active = rs("active")
set initialize = row
end function
Updated the UL code with a new LI item for fullname.
<%
Dim rsAccount
set rsAccount = getall()
%>
<ul>
<%
While (NOT rsAccount.EOF)
Dim account
call account = initialize(rsAccount)
%>
<li><%=account.id%></li>
<li><%=account.guid%></li>
<li><%=account.lastname%></li>
<li><%=account.firstname%></li>
<li><%=account.fullname%></li>
<li><%=account.email%></li>
<li><%=account.password%></li>
<li><%=account.passwordSalt%></li>
<li><%=account.clientId%></li>
<li><%=account.administrator%></li>
<li><%=account.lastLogin%></li>
<li><%=account.created%></li>
<li><%=account.modified%></li>
<li><%=account.active%></li>
<%
rsAccount.MoveNext()
Wend
%>
</ul>
If you run the code as is, you will get an error Variable is undefined: 'fullname'
All we need to do is make sure the account Class a property defined for fullname.
Class account
public id
public guid
public lastName
public firstName
public fullname
public email
public password
public passwordSalt
public clientId
public administrator
public lastLogin
public created
public modified
public active
End Class
Now your code should run without an error. You now have an account object with a property fullname.
Now that you know how to create a Class and Objects in Classic ASP, we will look at Converting Recordset into Objects in Classic ASP.
Lets create a Class account which has several properties. I usually use the database table account and copy the model so the Class matches the database model
Class account
public id
public guid
public lastName
public firstName
public email
public password
public passwordSalt
public clientId
public administrator
public lastLogin
public created
public modified
public active
End Class
Here I am creating a getall function to return all the rows in the account table in the database.
public function getall()
dim sql
sql = "select * from account"
dim rs
set rs = conn.execute(sql)
set getall = rs
end function
When I started with Classic ASP, I would have written a simple While Loop
The above code would write to the screen a <UL> foreach account row and <LI> foreach field/record in the database.
Object-Oriented Programming Approach
An OOP [Object-Oriented Programming] approach would be to initialize each account record using the account Class.
Instead of getting each data element using Recordset rsAccount("lastName"), we will use another function to map the Recordset row into our account object.
The public function initialize(rs) takes in a single row from the database and creates a single class object account.
public function initialize(rs)
dim row
set row = New account
row.id = rs("id")
row.guid = rs("guid")
row.lastname = rs("lastname")
row.firstname = rs("firstname")
row.email = rs("email")
row.password = rs("password")
row.passwordSalt = rs("passwordSalt")
row.clientId = rs("clientId")
row.administrator = rs("administrator")
row.lastLogin = rs("lastLogin")
row.created = rs("created")
row.modified = rs("modified")
row.active = rs("active")
set initialize = row
end function
Updated code combining Recordset with Class and Initializing each row into an object.
<%
Dim rsAccount
set rsAccount = getall()
%>
<ul>
<%
While (NOT rsAccount.EOF)
Dim account
set account = initialize(rsAccount)
%>
<li><%=account.id%></li>
<li><%=account.guid%></li>
<li><%=account.lastname%></li>
<li><%=account.firstname%></li>
<li><%=account.email%></li>
<li><%=account.password%></li>
<li><%=account.passwordSalt%></li>
<li><%=account.clientId%></li>
<li><%=account.administrator%></li>
<li><%=account.lastLogin%></li>
<li><%=account.created%></li>
<li><%=account.modified%></li>
<li><%=account.active%></li>
<%
rsAccount.MoveNext()
Wend
%>
</ul>
Creating Objects in programming is one the best ways to have code that is easily maintainable. With new Classic ASP clients, I have found creating Classes and Objects is a very good way to begin refactoring legacy code.
Class trip
public arrive_date
public depart_date
End Class
Here we have created a Class trip with 2 properties arrive_date and depart_date. Now, when we need to access the arrival date, you can access the values as
myobject.arrive_date
myobject.depart_date
Before we can access or use the trip Class, we need to create a new instance of a class. The newly instantiated trip Class, which is now an object with the properties, that we can use.
Class trip
public arrive_date
public depart_date
End Class
dim objTrip
set objTrip = new trip
objTrip.arrive_date = '02/11/2017'
objTrip.depart_date = '02/16/2017'
Now that we have created a new instance of our trip and assigned values to each property, we can write some simple HTML to retrieve the values
<p>
I will be arriving on <%=objTrip .arrive_date%> and leaving on <%=objTrip .depart_date%>
<p>
We worked on a project where we had a media library. We decided to use Isotope to filter/sort through a list of all the media items available. We wanted to the user to be able to sort through the items in both Ascending / Descending order. Below is how we accomplished that.
By default, Isotope sorts ascendingly: A, B, C and 1, 2, 3. To sort descendingly Z, Y, X, and 9, 8, 7, set sortAscending: false.
// sort highest number first
$grid.isotope({
sortBy: 'number',
sortAscending: false
});
We first added a data-attribute called data-sort-direction="asc" on a button element. When the button is clicked we get the data-sort-direction="asc" data-attribute value and convert that value to a boolean. We then use that boolean to set our new direction and store that in a variable called newDirection to use later.
/* convert it to a boolean */
var isAscending = (direction == 'asc');
var newDirection = (isAscending) ? 'desc' : 'asc';
We then pass in our isAscending value into the sortAscending property.
/* pass it to isotope */
$grid.isotope({ sortBy: sortValue, sortAscending: isAscending });
The last bit of code we use is to change the value data-sort-direction="asc" to the value of newDirection. This is so that next time the button is clicked it will sort the items in the opposite order.
While working on a project you may have had custom fields that are left behind and that are no longer in use for the current theme these unused custom fields remain in your database. I came across this exact scenario when I was upgrading a section of a website that was outdated and needed to be re-done. The previous programmer had use a plethora of custom fields and my goal was to reduce the amount of custom fields used.
Take a look at the following example. All the custom fields that are not being used
Removing Unused Custom Fields
Log into to phpMyAdmin
Select your database.
If you use a different database prefix than the default “wp_” one, then you’ll need to change that in the example below. Replace “meta_key” with your actual custom field name.
Run the following script. ( The script will run and delete any references to that custom field and the data associated with it )
DELETE FROM wp_postmeta WHERE meta_key = 'meta_key';
Alternatively you can also run an sql script that looks at meta_key and see if there are any empty values
SELECT * FROM wp_postmeta WHERE meta_key = 'meta_key';
In my scenario I needed to look for any custom field containing the words productOption running the sql script returned the following.
SELECT * FROM wp_postmeta WHERE meta_key LIKE '%productOption%';
We recently upgraded our development and production servers to PHP 7. We develop locally using Wamp Server so we needed to install PHP 7 on our computers as well. After digging around and some trial and errors I found the youtube video below.
Notes: PHP 7 needs Apache 2.4 otherwise it will not run. Make Sure Wamp Server is running Apache 2.4. In the video the extensions were changed I tried it and it PHP 7 wouldn’t load in Wamp Server so i kept the same extensions from my previous php.ini file and it worked
Google fonts are a great free resource for web designers. Using them however, wasn’t straight forward for me at first. I’ve created a quick step by step guide for new web designers to use as reference.
Enjoy!
How to run a google font on a site.
First, go to https://www.google.com/fonts and select the fonts you wish to use by using the add to collection button.
In the bottom right corner, select use. This will take you to a page asking you to select the font weights you wish to use. Scroll down until you see the lines of code provided.
Next, open your theme folder from the repository using sublime. You will need to open the functions file and the style.css file.
In the functions file, scroll down to the Enqueue scripts and styles section.
Copy the “add this code to your website” line and paste it into the file with a new wp_enqueue line. It should look like line 163 below.
Next, open the style.css file and scroll to the typography section. Paste in the “integrate the fonts into your CSS” line as shown below on line 275.
Save your files and your font should be loaded.
If you want to use different fonts for headings and body content, make the following adjustments.
First, select the two fonts you want to use from https://www.google.com/fonts and select the fonts you wish to use by using the add to collection button, click use, and go to the almost done page.
When you copy the code, copy the line now containing two fonts.
Next, add the body font-family as previously instructed.
For the headings, open the css folder (not the css file used before.) From here, open the styles.css folder.
(For the body font, open the styles.css file highlighted in the picture below. For the header font, open the css folder at the top, then open the styles.css file contained.)
Once you open the other styles.css file, scroll down to the styles section. Paste in the font-family as shown below.