Scripts: Advanced styling or design changes
This tutorial gives you the bases for using Scripts inside Xtreme, for programmable behaviors, or advanced site modifications.
It is not meant to teach you JavaScript, there are plenty of great Tutorial sites for that 🙂
It will take you through:
- General advanced modifications practices
- Base principles of Scripts in Xtreme
- Concepts and examples
General advanced modifications practices
Options and Custom CSS
When trying to create your design with a Weaver theme, you should always follow the logic below
- Search if there is an existing options to do what you want, ask on the forum if you don’t find it.
- If there is no option to apply the style you need, but there is an existing (different) option for the object you are targeting, you can put CSS rules inside the object option CSS+ box
- If there is no option for the object you are targeting, you can create a complete CSS rule using a selector that will target your object, and place it in the Global Custom CSS Rule box
Use your Brower developer tool to figure out the selector. Read below if not familiar with the developer tools
http://guide.weavertheme.com/basic-tips-on-using-the-developer-tools-like-firebug-to-resolve-styling-issues/
If you need different rules for different devices sizes (Desktop / Small Tablet / Phone / OSes…) you can add the theme mobile classes at the beginning of your selector (Check “Weaver Xtreme Helper Classes” in the help)
Beyond that there are two types of advanced changes that can be made.
PHP changes
If you need to alter the very structure of the theme, you may need to make changes to the PHP behind it.
Some PHP changes can be done using the Action and Filter box (“Plus” option)found in:
Customizer: Added Content… > Site Head Section > Action & Filter
Legacy Admin: Advanced Options > Head Section > Action & Filter Box
I have some example below
http://forum.weavertheme.com/discussion/8405/actions-filters-tips-and-examples-part1
http://forum.weavertheme.com/discussion/8406/actions-filters-tips-and-examples-part2
But for most, you would need to create a Child Theme, and make PHP changes in the child theme so they are not lost in the next update.
And when all else fail, there are Scripts …
Base principles of Scripts in Xtreme
CSS can do a LOT of things, and if you are not sure something can be done with CSS, ask In the Forum. But if you need advanced programmable effect, you sometimes may need to use a script (JavaScript / jQuery).
Obviously this is an advanced type of solution, and you should not rush into it before you have exhausted what CSS can do.
A script can also change the HTML generated by the theme without having to modify the PHP behind it, which in some cases can save you from creating a child theme.
You need to proceed with caution, as a script can mess up your site if you don’t know what you are doing, but don’t be afraid, when you remove the script, whatever harm it did will be gone.
If you are going to use JavaScript / jQuery scripts, I strongly advise that you learn a minimum about the scripting language.
jQuery reference site: https://api.jquery.com/
Some general remarks about scripts.
- When using jQuery inside Xtreme, you need to change the syntax $(xxxx) to jQuery(xxxx)
- Use a lot of comments in your script (using //comments…) to explain what each piece is for. A few month from now it may be hard to remember why you did what you did
- Where you place a script can matter.
Most global scripts (that apply to the whole site) will be placed in the Head section > Head Section box.
If the scripts is using or modifying specific page elements, it may need to be run after all these page elements have been created.
The way to do that is to place the script in the Post Footer HTML Insertion Code box.
If the script should only be run on a specific page, you can use the Page custom fields of these areas (page_head_code, postfooter on Xtreme).
For more on page custom field, read
http://guide.weavertheme.com/custom-fields-on-pages-and-posts-what-to-use-them-for-and-how-to-use-them/ - For scripts that only apply to a specific piece of content, they can also be placed with content (before or after depending on what the script does), if you do that on pages or posts, make sure to check the option “Allow Raw HTML and script” and use the TEXT mode of the content editor. You can also add these scripts to text widgets.
Debugging your Script
As long as your script does not do what you want, you know there is a problem, but even when it does, there might still be errors that could cause problems.
To be sure there are no such errors, open your site, open your browser developer tools, open its console, and refresh your site. If you have Script errors, they will show in the console with pointers of where the error is.
The console may report errors from other scripts, it will clearly show if they originate in yours or others.
Make sure to eliminate all errors before moving on.
Do not expect us to debug your scripts! You are better off using developer forums like Stackoverflow.com for that
Concepts and script examples
DISCLAIMER:
– I am not a JavaScript / jQuery expert, I know enough to do some things, but given my limited knowledge in this area, there may be better cleaner ways to do some of the things mentioned in my script examples.
– Use these examples at your own risk, and If you know better, feel free to speak up.
1) Altering the HTML output of the theme PHP to avoid creating a Child theme
This is an example of a script (from @weaver) about removing the links to a specific author while retaining the author’s name.
Note:
This is designed just for an archive page (including the Author Archive page). You will have to have that pair of jQuery statements for each author you want to remove the link from. You replace the name “weaver” with the name displayed for the author in question.
If you wanted to remove the author link on all pages, remove the .archive in the code. The title=”View all posts by” value is likely to be different for different edit translations. You can get the exact wording by looking at the HTML output of the page, either with a developer tool or reading the HTML page source directly.
Add the Script below to:
Customizer: Added Content … > HTML Injection Areas > Post Footer Injection Area
Legacy Admin: Advanced Options > HTML Insertion > Post-Footer box:
<script type="text/javascript"> jQuery('.archive a[title="weaver"]').contents().unwrap(); // remove link around author "weaver" on the "Author Archives : weaver line jQuery('.archive a[title="View all posts by weaver"]').contents().unwrap(); // remove link around "weaver" on the Posted by meta line on the archive page </script>
2) Use a script to apply a set of styling rules, by adding a class to an element.
This is best if there is a lot of styling involved. All the script has to do is add or remove the class under certain conditions.
You can then change the styling applied to the class without having to touch the script. The less scripting you need, the less room for errors.
As an example, let us say you have a Content box made with a div that has the ID mydiv (selector #mydiv), and when scrolling down the page, as the box reaches the top, we want it to become fixed, with a semi-transparent background.
A similar (more elaborate) version of that script is being use by Xtreme to implement the Fixed on Scroll menu option.
The Script will works together with some Custom CSS (below), which defines the styling connected to a made up class named my_top-fixed
The class is used to define a styling rule that will fix and style the menu bar when it reaches the top.
#mydiv.my_top-fixed { background-color: rgba(255,255,255,.9) !important; position:fixed;top:0;z-index:999;max-width:500px; }
The script below gathers the top position of the box, and uses that value as the amount to scroll before adding the styling class to the box element so that it becomes fixed and styled as we want.
Because the script needs to know the position of the box before you start scrolling, it would needs to be executed after the page is generated.
So that Script would need to go in the Post Footer HTML Insertion area
<script type="text/javascript"> //Need to define styling rule for fixed element (below) //#mydiv.wvrx_top-fixed {background-color: rgba(255,255,255,.9) !important;position:fixed;top:0;max-width:500px;z-index:999;} var my_selector = "#mydiv"; //Defines the selector target var ElementPosition = jQuery(my_selector).offset().top; //Gathers the top position of the selected element jQuery(window).scroll(function() { var windowScroll = jQuery(window).scrollTop(); //Collects the amount of scroll if (windowScroll > ElementPosition ) { //Use the selected element top position as the trigger position jQuery(my_selector).addClass("my_top-fixed"); //Add the class to the targeted element to apply the class styling } else { jQuery(my_selector).removeClass("my_top-fixed"); } }); </script>
3) Use a script that makes direct changes to the inline CSS of any object.
This method is suitable if you just have a few CSS properties to change. The script will directly write the CSS on the element HTML in a style attribute.
You need to know the selector of the object to target, or have the ability to add a class to the object (like if you are creating the HTML, or targeting the theme object with the “Plus” Add Class option).
The example below will scale down the size of any object that uses the class my_ScaleHeight while scrolling (down to a predefined size).
Idea comes from the following thread of someone wanting to reduce the size of a Header logo image when people scroll, to maximize space for content.
http://stackoverflow.com/questions/20706647/jquery-image-height-change-on-scroll
For example, if we want the script to affect the size of an image placed in the fixedtop area, you would put the below HTML image tag in that box, giving it a specific class my_ScaleHeight (you can use any name you want).
We will then use that class in the script to change the height of the image when scrolling.
<img style="height:250px;width:auto;" src="imageUrl" class="my_ScaleHeight" />
Note:
Instead of using a made up class, we could also use a unique selector that targets that image if we know it.
For example if there is only one image in the fixedtop area, we could use ‘#inject_fixedtop img’ instead of ‘.my_ScaleHeight’
That script does not need to know anything about the page elements, so it can go in:
Customizer: Added Content… > Site Head Section > Head section
Legacy Admin: Advanced Options > Head Section > Head Section
<script type="text/javascript"> var imageHeight = parseInt(jQuery('.my_ScaleHeight').css('height')); //Gathers the image height var stopHeight = imageHeight * 0.5; //Sets the minimum size for scaling. Replace 0.5 scaling factor by what you want jQuery(window).scroll(function() { var windowScroll = jQuery(window).scrollTop(); //Collects the amount of scroll var newHeight = imageHeight - windowScroll; //Calculate the new height by reducing the height of the image by the scroll value if(newHeight >= stopHeight){ //Apply it only is above the set limit jQuery('.my_ScaleHeight').css("height", newHeight); //Write the inline height CSS on the element } else{ jQuery('.my_ScaleHeight').css("height", stopHeight); //Beyond the limit, set the height as the limit } }); </script>
3) Perform calculations when the browser resizes
Let us say you are displaying posts in columns as boxes, using a background color and or border for each post.
Because post titles and excerpts may have different length, post boxes will have different height and therefore wont line up in a clean grid.
Such a situation poses two problems.
A-Finding the height
You could set a minimum height for each post with CSS, but new posts may require for you to adjust that value overtime.
A script will be able to compute the height of every post in the page, extract the height of the tallest box, and apply that height to all the posts.
Such a script would look like this:
<script type="text/javascript" language="javascript"> //Don't apply script on phones where post are in a single column if(jQuery('body.is-phone').length() == 0) { //Equalize post height var wvrxPostHeight = 0; //Calculate height of highest post jQuery('article.post').each(function () { jQuery(this).css('min-height',''); //Remove min-height if(jQuery(this).outerHeight() > wvrxPostHeight) { wvrxPostHeight = jQuery(this).outerHeight(); } }); //Apply height as a min-height to every post jQuery('article.post').each(function () { jQuery(this).css('min-height',wvrxPostHeight + 'px'); }); }; </script>
B- But then comes the second problem, responsiveness.
As the browser gets smaller, text flows on more lines, making boxes taller. A min-height CSS will no longer have the proper value, and the value computed by the script will no longer be good. In order for the value computed by the script to be updated, a user would have to refresh the page so the script gets executed again, making the solution not dynamically responsive.
The solution to problem two exists but is not trivial. Luckily, Xtreme includes a generic mechanism to rerun any script every time the browser size changes. Even better, it makes that mechanism available to a user defined script.
If order for a Script to be constantly run while the browser resizes, you just need to wrap it inside a specific function called weaverxUserOnResize
function weaverxUserOnResize() { //Your script };
So in order for the Script above to work that way, you would insert the final code in the postfooter Custom field of the page
<script type="text/javascript" language="javascript"> function weaverxUserOnResize() { //Don't apply script on phones where post are in a single column if(jQuery('body.is-phone').length() == 0) { //Equalize post height var wvrxPostHeight = 0; //Calculate height of highest post jQuery('article.post').each(function () { jQuery(this).css('min-height',''); //Remove min-height if(jQuery(this).outerHeight() > wvrxPostHeight) { wvrxPostHeight = jQuery(this).outerHeight(); } }); //Apply height as a min-height to every post jQuery('article.post').each(function () { jQuery(this).css('min-height',wvrxPostHeight + 'px'); }); }; }; </script>
IMPORTANT NOTE:
Running a Script that way is resource intensive, so you should not do that unless absolutely necessary.
In doubt, you can ask on the Weaver Support Forum.
It is also key to FIRST debug your script by itself and make sure it does not generate any errors BEFORE wrapping it in the weaverxUserOnResize function.