-
Notifications
You must be signed in to change notification settings - Fork 14
Architecture
This document is intended to provide a basis of understanding for the architecture behind WebBlocks, with a focus on the WebBlocks compile process, configuration settings, and package structure.
The WebBlocks compilation process creates the following in the build
directory:
css/blocks.css
css/blocks-ie.css
js/blocks.js
js/blocks-ie.js
js/scripts/
img/
Some general terminology useful throughout the system:
-
Package: A third-party extension checked out as a git submodule within the
/package
directory -
Adapter: A set of SASS that links WebBlocks definitions to a framework by defining mixins, generally defined as a subdirectory within
/src/adapter
. The default adapter is "bootstrap", although others may be written to implement WebBlocks within additional frameworks like Foundation and HTML 5 Boilerplate. -
Extension: A set of SASS that is loaded in that may change the behavior of mixins, generally defined as a directory within
/src/extension
. These are like adapters in the way they change behavior, but are intended not to bridge a framework to WebBlocks, but instead modify WebBlocks for a particular organization or unit. Fo example, if UCLA provided a WebBlocks fork, it would likely include/src/extension/ucla
. -
Module: A module is a definition (or set of definitions) as they reside within
/src/core/definitions
. For example, if one wants to build WebBlocks with just the base definitions and not the entities, they would setWebBlocks.config[:src][:modules] = ['base']
. This will load everything under/src/core/definitions/base
. This can be done at any granularity and the array may define as many entities as desired. Note that this is additive, soWebBlocks.config[:src][:modules] = ['base', 'base/block']
is superfluous sincebase
includesbase/block
. -
Core Definitions: This is where all of the actual WebBlocks components are defined, and it defines the modular structure for
WebBlocks.config[:src][:modules]
where whatever is set for that variable is what is included (as well as all subdirectories underneath). -
Core Adapter: This is a base set of definitions of mixins used by the core definitions, as defined in
/src/core/adapter
. Generally, these mixins should be empty, although for basic things that are not framework-dependent (such asbase/type/align
), the mixins actually include CSS properties. When creating a new adapter, it is recommended that/src/core/adapter
be copied into a subdirectory of/src/adapter
and then modified to provide just the things that the adapter changes from the core adapter.
The SASS compile process works as a stack, loading in definitions from various locations which will override earlier definitions. As such, it is important to understand how this stack works:
- User-defined Extension Variables File(s) [
src/core/extension/
directories with file_variables.scss
] - SASS Source Variables File [
src/sass/_variables.scss
] - Core Adapter [
src/core/adapter/
directories] - User-defined Adapter(s) [
src/adapter/
directories] - User-defined Extension(s) [
src/core/extension/
directories] - Core Definitions [
src/core/definitions/
directories] - SASS Source Files [
src/sass/blocks.scss
andsrc/sass/blocks-ie.scss
]
NOTE: Paths are all configurable in Rakefile-config.rb
so they will not necessarily be as listed above
Under this scheme, the core definitions (which are mixin calls) are loaded based on the core adapter and user-defined adapters. Extensions are then loaded afterwards, meaning that extensions should be used to modify behavior by overriding settings in earlier loads.
An example of what a compile stack might look like is as follows:
@import "/var/www/WebBlocks/src/extension/ucla/_variables";
@import "/var/www/WebBlocks/src/extension/oit/_variables";
@import "variables";
@import "/var/www/WebBlocks/src/core/adapter/base/block/float";
@import "/var/www/WebBlocks/src/core/adapter/base/type/align";
@import "/var/www/WebBlocks/src/core/adapter/entity/_button";
@import "/var/www/WebBlocks/src/core/adapter/entity/_list";
@import "/var/www/WebBlocks/src/core/adapter/entity/_table";
@import "/var/www/WebBlocks/src/core/adapter/entity/header/_masthead";
@import "/var/www/WebBlocks/src/core/adapter/entity/nav/_bar";
@import "/var/www/WebBlocks/src/core/adapter/entity/nav/_main";
@import "/var/www/WebBlocks/src/adapter/bootstrap/_requisites";
@import "/var/www/WebBlocks/src/adapter/bootstrap/_util";
@import "/var/www/WebBlocks/src/adapter/bootstrap/base/block/float";
@import "/var/www/WebBlocks/src/adapter/bootstrap/base/type/align";
@import "/var/www/WebBlocks/src/adapter/bootstrap/entity/_button";
@import "/var/www/WebBlocks/src/adapter/bootstrap/entity/_list";
@import "/var/www/WebBlocks/src/adapter/bootstrap/entity/_table";
@import "/var/www/WebBlocks/src/adapter/bootstrap/entity/header/_masthead";
@import "/var/www/WebBlocks/src/adapter/bootstrap/entity/nav/_bar";
@import "/var/www/WebBlocks/src/adapter/bootstrap/entity/nav/_main";
@import "/var/www/WebBlocks/src/extension/ucla/defs";
@import "/var/www/WebBlocks/src/extension/oit/defs";
@import "/var/www/WebBlocks/src/core/definitions/base/block/float";
@import "/var/www/WebBlocks/src/core/definitions/base/type/align";
@import "/var/www/WebBlocks/src/core/definitions/entity/_list";
@import "/var/www/WebBlocks/src/core/definitions/entity/_table";
@import "/var/www/WebBlocks/src/core/definitions/entity/button/_button";
@import "/var/www/WebBlocks/src/core/definitions/entity/button/_input_reset";
@import "/var/www/WebBlocks/src/core/definitions/entity/button/_input_submit";
@import "/var/www/WebBlocks/src/core/definitions/entity/header/_masthead";
@import "/var/www/WebBlocks/src/core/definitions/entity/nav/_bar";
@import "/var/www/WebBlocks/src/core/definitions/entity/nav/_main";
One can determine the entirety of this stack (besides the variables files and source files) through the command rake includes
.
While compass
(and thus sass
) are used underneath to do much of the compile process, because of the extremely modular nature of the build, the process is managed through rake
and two underlying classes, WebBlocks::builder
and WebBlocks::compiler
, as well as supporting utilities to handle specific portions of the process. These definitions reside within the /rake
folder.
-
WebBlocks::builder
- used by the majority ofrake
tasks to construct the build environment, move files around as needed, etc. -
WebBlocks::compiler
- used to assemble all of the libraries that are made available when calling@import "WebBlocks"
as done insrc/sass/blocks.scss
, as set inRakefile-config.rb
or through the defaults defined inWebBlocks::config
[rake/config.rb
].
The following describe the configuration settings available to the build.
All configuration settings have defaults defined in rake/config.rb
. However, any of these can be changed by setting them explicitly in Rakefile-config.rb
or in some other file that is passed to rake
via a command-line argument as rake -- --config=[PATH]
.
The general configuration components are as follows:
-
WebBlocks.config[:build]
- Settings related to the build produced byrake
throughWebBlocks::builder
. -
WebBlocks.config[:src]
- Settings related to the sources built byWebBlocks::compiler
. -
WebBlocks.config[:exec]
- Paths for the various executables used by WebBlocks -
WebBlocks.config[:package]
- Settings related to third-party packages locations and builds
The following settings are ones that are anticipated to be used in general day-to-day development and integration of WebBlocks:
# location of the build directory relative to WebBlocks root
WebBlocks.config[:build][:dir] = 'build'
# the adapter (or set of adapters as an array) that are loaded in FIFO order (or false for no adapters)
WebBlocks.config[:src][:adapter] = 'bootstrap'
# an array of extensions that are loaded in FIFO order (or false for no extensions)
WebBlocks.config[:src][:extensions] = false
# array of directories in the core definitions directory
# or :all to include all modules or false to include no modules
WebBlocks.config[:src][:modules] = :all
# which third-party packages are included in the build
WebBlocks.config[:build][:packages] = [
:bootstrap,
:jquery,
:modernizr,
:respond,
:selectivizr
]
Several settings exist mostly for trouble-shooting or handling of specific environments (such as when executables are not in the user path):
# true to generate a debug directory inside build directory
WebBlocks.config[:build][:debug][:enabled] = false
# will soon be this instead:
# WebBlocks.config[:build][:debug] = false
# executable path to Git
WebBlocks.config[:exec][:git] = 'git'
# executable path to Grunt
# defaults to relative path for npm module installation
WebBlocks.config[:exec][:git] = 'node ./node_modules/grunt/bin/grunt'
# executable path to NPM
WebBlocks.config[:exec][:npm] = 'npm'
# executable path to SASS
WebBlocks.config[:exec][:sass] = 'sass'
# executable path to Uglifycss
# defaults to relative path for npm module installation
WebBlocks.config[:exec][:uclifycss] = 'node ./node_modules/uglifycss/uglifycss'
# executable path to Uglifyjs
# defaults to relative path for npm module installation
WebBlocks.config[:exec][:uglifyjs] = 'node ./node_modules/uglify-js/bin/uglifyjs'
# executable path to Compass
WebBlocks.config[:exec][:compass] = 'compass'
When integrating WebBlocks into another package, the following settings may be useful:
# the source directory where core, adapters, extensions, SASS, JS and images reside
# individual components within src can have their paths changed by other variables
# recommended for integration to set this outside WebBlocks and then set adapter and core dir inside WebBlocks
WebBlocks.config[:src][:dir] = 'src'
# the directory within source directory where adapter directories reside
# absolute path supported
WebBlocks.config[:src][:adapters][:dir] = 'adapter'
# the directory within source directory where core definition and adapter directories reside
# absolute path supported
WebBlocks.config[:src][:core][:dir] = 'core'
The following settings are more advanced, likely never needing to be changed, although in some cases it may be useful hence provisions are provided as such:
# directory within the build directory for debug
WebBlocks.config[:build][:debug][:dir] = 'debug'
# will soon be removed!
# directory within the root for temporary files involved with the build process
WebBlocks.config[:build][:dir_tmp] = '.build-tmp'
# directory within the root for metadata related to WebBlocks
WebBlocks.config[:build][:dir_metadata] = '.blocks'
# directory within build directory where CSS files are placed
WebBlocks.config[:build][:css][:dir] = 'css'
# name of primary CSS file within CSS build dir
WebBlocks.config[:build][:css][:name] = 'blocks.css'
# name of IE CSS file within CSS build dir
WebBlocks.config[:build][:css][:name_ie] = 'blocks.css'
# directory within build directory where JS files are placed
WebBlocks.config[:build][:js][:dir] = 'js'
# name of primary JS file within JS build dir
WebBlocks.config[:build][:js][:name] = 'blocks.js'
# name of IE JS file within JS build dir
WebBlocks.config[:build][:js][:name_ie] = 'blocks-ie.js'
# name of stand-alone scripts directory within JS build dir
WebBlocks.config[:build][:js][:name_script_dir] = 'script'
# directory within build directory where image files are placed
WebBlocks.config[:build][:img][:dir] = 'img'
# the directory within source directory where SASS files reside for build
# absolute path supported
WebBlocks.config[:src][:sass][:dir] = 'sass'
# the directory within source directory where image files reside for build
# absolute path supported
WebBlocks.config[:src][:img][:dir] = 'img'
# the directory within source directory where JS files reside for build
# absolute path supported
WebBlocks.config[:src][:js][:dir] = 'js'
# the file name within core directory where Compass config file resides
# absolute path supported
WebBlocks.config[:src][:core][:compass][:config] = 'config.rb'
# the directory within core directory where core definition directories reside
# absolute path supported
WebBlocks.config[:src][:core][:definitions][:dir] = 'definitions'
# the directory within core directory where core adapter directories reside
# absolute path supported
WebBlocks.config[:src][:core][:adapter][:dir] = 'adapter'