Static Website Source Files

by Will Moody

Leading on from this post Static Website Boilerplate  here are more details of the src file structure used - my src file structure is as below, this keeps all things easily traceable (I have omitted some items from the scss listings, but will give the full main.scss  and main.js below) :-

src
|
 - assets
   |
   -- fonts
   -- images
   -- scripts
      |
      main.js
      math.js
   -- styles
      |
      base
      |
       - _config.scss
         _normalise.scss
         _debugger.scss
      components
      |
        - _list.scss
          _forms.scss
      grid
      |
       - _grid-settings.scss
      sections
      |
       - _nav.scss
         _header.scss
         _footer.scss
      main.scss
      print.scss
     -- svg
|
 - build files
   |
    - .htaccess
      humans.txt
      robots.txt
|
 - data
   |
    - details.yml
      index.json
|
 - templates
   |
   - components
     |
      - nav.html
        header.html
        footer.html
   layouts
   |
    - default.html
      frontpage.html
   pages
   |
     - index.html

Main.scss looks draws all the scss files together in the order listed; as standard debugger is excluded, but is a really handy include in fault finding a layout. The config.scss holds all the main variables including, colors, borders and font includes and likewise mixins contains all the mixins I find really useful in building websites. 

I find seperating all the components and sections out into individual files makes the whole process much more managable, much of the scss works across any website.

main.scss

@charset 'utf-8';

@import 'base/normalise';
//@import 'base/debugger';
@import "base/config";
@import "base/mixins";
@import "base/type";
@import "components/media";
@import "components/buttons";
@import "components/tables";
@import "components/forms";
@import "components/links";
@import "components/list";
@import "components/alerts";
@import "components/classes";
@import "grid/grid-settings";
@import "node_modules/cookieconsent/build/cookieconsent.min";
@import "node_modules/aos/dist/aos";
@import "node_modules/slick-carousel/slick/slick.scss";
@import "sections/layout";
@import "sections/accessibility";
@import "sections/nav";
@import "sections/header";
@import "sections/content";
@import "sections/gallery";
@import "sections/services";
@import "sections/contact";
@import "sections/sitemap";
@import "sections/prefooter";
@import "sections/footer";
@import "sections/copyright";
@import "sections/scrollup";

Main.js firstly imports jQuery, CookieConsent, Aos and Slick-Carousel, it then initiates them and gives the options for each, apart from Aos which only needs initialization. I also include two snippets, the first opens all external links in a new window with rel="nofollow noopener noreferrer" and the second is a 'skip to main' link for accessibility.

main.js

import {
  addition,
  subtraction,
} from './math';

import $ from 'jquery';
import CookieConsent from 'cookieconsent';
import AOS from 'aos';
import 'slick-carousel';


$('.testimonials').slick({
  slidesToShow: 1,
  slidesToScroll: 1,
  autoplay: true,
  autoplaySpeed: 8000,
  arrows: false,
  dots: false,
  infinite: true,
  speed: 1000,
  fade: true,
  cssEase: 'linear',
});

/* -- Cookie-Consent -- */
window.addEventListener('load', () => {
  window.cookieconsent.initialise({
    'palette': {
      'popup': {
        'background': '#f0149b',
        'text': '#fff',
      },
      'button': {
        'background': '#fff',
        'text': '#f0149b',
      }
    },
    'position': 'bottom',
    'type': 'opt-in',
    'content': {
      'dismiss': 'Disallow Cookies',
      'allow': 'Allow Cookies',
      'href': 'https://www.broadwurx.co.uk/cookies.html',
    },

    onInitialise: function (status) {
      var type = this.options.type;
      var didConsent = this.hasConsented();
      if (type == 'opt-in' && didConsent) {
        // enable cookies
      }
      if (type == 'opt-out' && !didConsent) {
        // disable cookies
      }
    },

    onStatusChange: function (status, chosenBefore) {
      var type = this.options.type;
      var didConsent = this.hasConsented();
      if (type == 'opt-in' && didConsent) {
        // enable cookies
      }
      if (type == 'opt-out' && !didConsent) {
        // disable cookies
      }
    },

    onRevokeChoice: function () {
      var type = this.options.type;
      if (type == 'opt-in') {
        // disable cookies
      }
      if (type == 'opt-out') {
        // enable cookies
      }
    },
  });
});

/* -- Open all external links in a new window -- */
jQuery(document).ready(function ($) {
  $('a')
    .filter('[href^="http"], [href^="//"]')
    .not('[href*="' + window.location.host + '"]')
    .attr('rel', 'nofollow noopener noreferrer')
    .not('.trusted')
    .attr('target', '_blank');
});

/* -- skip-to-main -- */
$(document).ready(function () {
  $('.skip').click(function (event) {
    var skipTo = '#' + this.href.split('#')[1];
    $(skipTo).attr('tabindex', -1).on('blur focusout', function () {
      $(this).removeAttr('tabindex');
    }).focus();
  });
});

/* -- Aos Initialization -- */
AOS.init();

window.add = addition;
window.subtract = subtraction;