Factor1 Tools, Packages, & Libraries - factor1/developer-resources GitHub Wiki
At Factor1 we have some requirements for every site we build to ensure consistency in our sites and to facilitate work on a site you personally may not have built.
- Below is a list of plugins we use on every site:
- ACF Pro
- Classic Editor
- Better Rest Endpoints
- BackUpWordPress
- Gravity Forms (also recommended: ACF Gravity Forms add-on)
- Regenerate Thumbnails
- Safe SVG
- Simple Page Ordering
- Smush Pro
- WP Migrate DB Pro
- WPMU Dev Dashboard
- AIOSEO
We use Prelude as the starting point for every F1 site.
npx prelude-wp theme-name
We are currently on Prelude 6, which replaces Prelude 4’s gulp
tasks with yarn
tasks. Here are a few examples of the changes:
Common Tasks | Prelude 4 | Prelude 6 |
---|---|---|
Install theme packages | npm install |
yarn |
Compile styles | gulp styles |
yarn build-scss |
Compile scripts | gulp scripts |
yarn build-js |
Run browser sync | gulp |
yarn start |
Currently, there are some fixes not included by default in the official release of Prelude 6, so make sure to get these changes in place prior to working on the theme dev.
- In
package.json
:
On the build-js
and build-scss
tasks (lines 6 & 7): Make sure the output directory is updated (after the --public-url
flag). Also remove the extra / from the build-js
task
// Old:
"build-js": "parcel build ./assets/js//theme.js --out-dir ./dist/ --no-content-hash --log-level 4 --public-url ./dist/",
"build-scss": "parcel build ./assets/scss/theme.scss --out-dir ./dist/ --no-content-hash --log-level 4 --public-url ./dist/",
// New:
"build-js": "parcel build ./assets/js/theme.js --out-dir ./dist/ --no-content-hash --log-level 4 --public-url ./ --no-cache",
"build-scss": "parcel build ./assets/scss/theme.scss --out-dir ./dist/ --no-content-hash --log-level 4 --public-url ./ --no-cache",
On the watch-js
and watch-scss
tasks (lines 15 & 16): Make sure the output directory is updated (after the --public-url
flag). Also remove the extra / from the watch-js
task
// Old:
"watch-js": "parcel watch ./assets/js//theme.js --out-dir ./dist --log-level 4 --public-url ./dist/",
"watch-scss": "parcel watch ./assets/scss/theme.scss --out-dir ./dist --log-level 4 --public-url ./dist/"
// New:
"watch-js": "parcel watch ./assets/js/theme.js --out-dir ./dist --log-level 4 --public-url ./ --no-hmr --no-cache",
"watch-scss": "parcel watch ./assets/scss/theme.scss --out-dir ./dist --log-level 4 --public-url ./ --no-hmr --no-cache"
- In
header.php
just after the openingbody
tag, make sure the following snippet is included:
<?php if ( function_exists( 'wp_body_open' ) ) {
wp_body_open();
} ?>
- On line 10 of the
defer_parsing_of_js
function ininc/enqueues.php
, make sure to include the following fix (very important in WP versions >= 5.6)
// Old
if ( strpos( $url, 'jquery.js' ) ) return $url;
// New
if ( strpos( $url, 'jquery.js' ) || strpos( $url, 'jquery.min.js' ) ) return $url;
- Store all color and font variables under
assets/scss/settings/_variables.scss
for easy reference/updates - Create a
templates
folder for custom templates (such as home, about, etc.) - Create a
parts
folder for template parts a. Organize this folder into subfolders based on where the template parts are used b. Create a correspondingassets/scss/parts
folder that mimics the parts folder for easy reference - Create SCSS partials under
assets/scss/components
for elements such as menu icons, nav styles, buttons, decorative elements, etc. - Always delete unneeded files
- For example, if you have a blog view created (
index.php
) and a category, tag, or author view is the exact same (or close enough that a little conditional logic can handle small differences), deletearchive.php
<?php // Index.php
$isCat = is_category();
...
?>
<section class="post-grid">
<div class="container">
<div class="row">
<?php if( $isCat ) : ?>
<!-- Stuff that only appears on category view here -->
<?php endif; ?>
</div>
</div>
</section>
- Refer to the WP template hierarchy for help on which templates can be safely deleted
We use Ginger Grid as our grid system of choice on every site in lieu of Foundation or Bootstrap. It’s much more lightweight and has been thoroughly tested.
yarn add ginger-grid
Factor1 does have 2 versions of the Nifty Nav menus available, but the first version is very outdated/unmaintained and should be avoided on new projects. The second version works to a point but has a known bug with menu flickering.
Until that bug is resolved, use the following snippets to create an easy menu system.
<button class="menu-icon"><span></span></button>
// SCSS Snippets
body {
position: relative;
height: 100%;
overflow-x: hidden;
transition: transform .4s ease;
&:after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
transition: all .4s ease;
}
&.locked {
overflow-y: hidden;
}
&.masked:after {
background: rgba(0, 0, 0, 0.9);
pointer-events: auto;
z-index: 9998;
}
}
/*------------------------------------------------------------------------------
Menu Icons and Buttons
------------------------------------------------------------------------------*/
.menu-icon {
// General styles
position: absolute; // adjust as needed
top: rem(30);
right: rem(15);
padding: rem(20) rem(10);
-webkit-appearance: none;
outline: none;
border: none;
z-index: 99999;
span {
position: relative;
&:before {
content: '';
position: absolute;
top: rem(-10);
left: 0;
}
&:after {
content: '';
position: absolute;
top: rem(10);
left: 0;
}
}
span,
span:before,
span:after {
display: block;
width: rem(25);
height: rem(3);
border-radius: rem(2);
background-color: rgba($white, .85); // insert color here
transform-origin: -4% center;
transition: all .4s ease;
}
&:active,
&:hover {
span,
span:before,
span:after {
background-color: rgba($white, 1); // insert color here
}
}
// Active styles
&.active {
span {
background-color: transparent;
&:before {
left: rem(5);
transform: rotate(45deg);
}
&:after {
left: rem(5);
transform: rotate(-45deg);
}
}
}
}
// Theme.js
// Menu function
$('.menu-icon').on('click', function() {
$('.menu-icon').toggleClass('active');
$('body').toggleClass('locked masked');
$('.nav--primary').fadeToggle(); // or slideToggle, or whatever is called for
});
For sites using Font Awesome, create a kit/project for the site in our Factor1 Font Awesome account (credentials in 1password) and apply the script in inc/enqueues.php
:
function prelude_theme_scripts() {
// Font Awesome
wp_enqueue_script('font-awesome', 'https://kit.fontawesome.com/f114da1312.js', array(), THEME_VERSION );
...
}
This script can sometimes interfere with page loading, so be sure to add the following snippet to add async and defer attributes to the script (a good place for this snippet would be inc/tweaks.php
):
// Add async defer to font awesome script
function add_async_attribute($tag, $handle) {
if ( 'font-awesome' !== $handle )
return $tag;
return str_replace( ' src', ' async="async" src', $tag );
}
add_filter('script_loader_tag', 'add_async_attribute', 10, 2);
For fonts we typically use Typekit or Google Fonts.
For sites using Typekit, create a kit/project for the site in our developer Adobe account (credentials in 1password) and apply the script in inc/enqueues.php
.
For sites using Google Fonts, add all fonts needed and copy the link into inc/enqueues.php
.
function prelude_theme_scripts() {
// Google fonts
wp_enqueue_style('google-fonts', 'https://fonts.googleapis.com/css?family=Raleway:300,400,500,600,700', array(), THEME_VERSION );
...
}
For sliders, we prefer Ken Wheeler’s Slick Slider.
yarn add slick-carousel
When customizing slick settings, make sure to create a _slick-settings.scss
file under assets/scss/settings
and copy/paste the content from node_modules/slick-carousel/slick/slick-theme.scss
into the file you created. (Don’t forget to import that file in your theme.scss file
)
// Theme.scss
...
// Slick
@import 'slick.scss';
@import 'settings/slick-settings';
...
For modals, the library we use is Micromodal.
** We have been running into conflicts with other libraries we use recently with the latest version, so make sure to download version 0.3.2 for now.
yarn add [email protected]
We have a base set of styles to handle modal styles that you can customize as needed. Be sure to copy this snippet into your code (for example, in assets/scss/components/_modals.scss
).
.modal__overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.6);
display: flex;
justify-content: center;
align-items: center;
}
.modal__container {
background-color: #fff;
padding: 30px;
max-width: 500px;
max-height: 100vh;
border-radius: 4px;
overflow-y: auto;
box-sizing: border-box;
}
.modal__close {
background: transparent;
border: 0;
}
.modal__close:before { content: "\2715"; }
.modal__content {
margin-top: 2rem;
margin-bottom: 2rem;
line-height: 1.5;
color: rgba(0,0,0,.8);
}
/**************************\
Demo Animation Style
\**************************/
@keyframes mmfadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes mmfadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
@keyframes mmslideIn {
from { transform: translateY(15%); }
to { transform: translateY(0); }
}
@keyframes mmslideOut {
from { transform: translateY(0); }
to { transform: translateY(-10%); }
}
.micromodal-slide {
display: none;
}
.micromodal-slide.is-open {
display: block;
}
.micromodal-slide[aria-hidden="false"] .modal__overlay {
animation: mmfadeIn .3s cubic-bezier(0.0, 0.0, 0.2, 1);
}
.micromodal-slide[aria-hidden="false"] .modal__container {
animation: mmslideIn .3s cubic-bezier(0, 0, .2, 1);
}
.micromodal-slide[aria-hidden="true"] .modal__overlay {
animation: mmfadeOut .3s cubic-bezier(0.0, 0.0, 0.2, 1);
}
.micromodal-slide[aria-hidden="true"] .modal__container {
animation: mmslideOut .3s cubic-bezier(0, 0, .2, 1);
}
.micromodal-slide .modal__container,
.micromodal-slide .modal__overlay {
will-change: transform;
}
We often use AOS as a “design to delight” feature and can be a nice effect when used tastefully/sparingly.
yarn add aos
Copy the contents of node_modules/aos/dist/aos.css
into a new file, assets/scss/vendor/_aos.scss
and import appropriately.
Unless told otherwise, we always set the global settings to disable this effect on mobile and to fire effects once:
// Theme.js
// AOS
AOS.init({
duration: 900, // adjust as needed
disable: 'mobile',
anchorPlacement: 'top-center',
once: true,
});
For more subtle/fluid scroll-based animations, we use alumbo’s parallax scroll library. The Github documentation does not have an npm install command, so to include in your project, copy the contents of js/jquery.parallax-scroll.js
from the Github link into a file under assets/js
in your theme. Enqueue it before and list it as a dependency for your main js file:
function prelude_theme_scripts() {
...
// JS
wp_enqueue_script('jquery-parallax', get_template_directory_uri() . '/assets/js/jquery.parallax-scroll.js', array('jquery'), THEME_VERSION, true );
wp_enqueue_script('prelude-js', get_template_directory_uri() . '/assets/js/theme.min.js', array('jquery', 'jquery-parallax'), THEME_VERSION, true );
}
add_action( 'wp_enqueue_scripts', 'prelude_theme_scripts' );
For general parallax effects, we prefer pixelcog’s parallax.js.
yarn add jquery-parallax.js
For masonry layouts, we prefer either Macy.js or Masonry.
yarn add macy
yarn add masonry-layout
For clients who request sticky headers, we use Headroom.js. This tool works by applying classes to the sticky element depending on scrolling behavior and position. Simply add styles based on those classes.
yarn add headroom.js
Waypoints is a good general-purpose tool we use for handling events when users scroll to a certain point.
yarn add waypoints