Constitution: a Method

Systematic web apps development (notes towards…). The method I follow with my still work in progress Constitution stack.

1. Bootstrapping

(The least important step. Nu, from a marketing perspective (funnel), assuming a long tail distribution of adoption (time spent with this stack), it makes sense to emphasize painless installation and… but, at what price? I do 1,000 hours scale projects. It’s astonishing how frameworks fuss about the first five minutes, and hardly give thought to the rest. Market failure much?)

  1. Skeleton(s) (forthcoming)
    1. Copy (DL and unzip) or clone it:
      $ git clone $SKELETON ./Code/

      Remove, or keep and rename that remote, so can diff against future skeleton updates?

      $ git remote rename origin skeleton
  2. Git/flow
    1. Unless cloning a skeleton, or repo created on GitHub, init a local development repo:
      1. $ git flow init --defaults
      2. .gitignore (GitHub can generate it, if repo created there.)
    2. Publish (probably) remote repo
      1. GH
      2. Add “origin”
      3. URLs in package.json, etc.
    3. Useful .git/config, or global, settings:
      1. Remember passwords, briefly:
        $ git config --global credential.helper "cache --timeout=9999"

        Cf man git-credential-cache.

      2. Force HTTPS for when Wi-Fi blocks SSH port:
        $ git config --global url.https://.insteadof git://

        Cf git config –help.

      3. $ git config push.default current

        so can just “git push” from separate local clones of different branches, particularly “gh-pages”.

      4. Bash aliases, prompt, and completion fix.

      Etc.

    4. README.md (or index.html for GHP? Separate branch?)…
    5. config.coffee, ecosystem.coffee (config for PM2): environmental defaults, feature toggling…
  3. Dependencies: package.json (NPM), bower.json…
    1. Project’s metadata: edit package.json. What about duplication in bower.json? DRY!
    2. CDN URLs? See, under SPA templates, Double Macchiato helper “cdn_script”.
  4. Tooling (SDLC, CD)…
    1. Cake
    2. Mocha…

2. Wireframes (specifications)

  1. Prototyping on paper (POP)
    1. Extremes first (what I call “deep RWD”) instead of narrow first (aka mobile first, in the olden days; shallow RWD).
    2. Input methods: pointer/touch (adapt/consolidate?).
  2. Inventory
    1. List screens. Per SPA. (“Screen” includes modals, mutations… anything that’s recorded in navigation history, ie back button applies. At least?)
    2. Widgets: inventory (sub)components of screens; separate list for recurring.
    3. Layouts (modular), eg:
      1. Narrow (single column): questionnaire screen has outline/nav in collapsed drawer, sliding in from right (align:end)
      2. Wide (double): questionnaire in right column, outline/nav in left, always expanded
      3. Huge (triple): wide, plus preview of results in a third column
  3. Navigation: URLs, transitions…
    1. Nav conceptual structure/organization; cf “lost in hyperspace”.
    2. URLs (per SPA), eg:
      Screen URL Selector Notes
      Favorites /favs #favs
      Item /items/:id #item
      Catalog /items/ #catalog Listing. (Redirect if missing trailing slash.)

      Also: redirections (eg root(s), auth’ dependent), screens without URLs (no history tracking)…

3. SPA

  1. Templates
    1. “Single page”: combine screens into one template per SPA; eg: public.html.coffee, app.html.coffee, admin.html.coffee.
    2. i18n/L10n: rendered into static assets once; eg app..html.coffee will be rendered into app.en.html, app.es.html, etc.
    3. For now, Cakefile mixes Bash and CoffeeScript:
      shell """for fp in template/*.-.html.coffee; do 
      	for lang in #{config.translations}; do 
      		f=${fp#template/}
      		coffee -e "console.log (require './$fp')('$lang')" > build/${f%.-.html.coffee}.$lang.html
      	done
      done"""
    4. CoffeeScript modules exporting an HTML renderer:
      ## public.-.html.coffee
      # HTML rendering. (Importing Double Macchiato functions globally, except single letter elements, because typically used for local variables, and CoffeeScript will overwrite globals.)
      {renderable,comment,title,link,meta,script,section,main,aside,div,span,nav,header,footer,h1,h2,h3,h4,img,form,input,textarea,label,button,select,option,fieldset,ol,ul,li,table,tr,th,td,em,strong,blockquote,text,raw,template,tag,iframe,hr,br,coffeescript}=dom=require 'double-macchiato'
      {action,cdn_script,empty,gray,hide,html5bp,screen}=require 'const-helpers/common.html.coffee'
      ## Renderer.
      module.exports=renderable (lang)->
      	html5bp {lang},->
      		title 'CoverArk (Public SPA)'
      		#...
      

      (See skeleton for useful “templates”.)

  2. Routing (server side): handle each SPA’s URLs, so they can be bookmarked, shared, etc (order significant: decreasing specificity).
    ## server.coffee
    # (Express...)
    app 
    # Public SPA (anonymous).
    .all /\/(..)\/(|login|logout|terms)$/,(req,res)->res.sendFile ASSETS+"/public.#{req.params[0]}.html" 
    # Admin SPA.
    .all /\/(sys|error)$/,(req,res)->res.sendFile ASSETS+'/admin.html'
    
    1. Redirects:
      # Root.
      .all '/',(req,res)->res.redirect '/en/' # Default lang???

      Also, redirect to appropriate SPA based on session (cookie), or UA preferences…

    2. Directories in URL path, for namespacing collections:
      # Directories: redirect to append slash.
      .all /\/(..)\/(items|profiles|help)$/,(req,res)->res.redirect req.path+'/'

      allowing for URLs like /en/items/foo and /en/items/, not /en/items.

    3. (Server/client side (SS/CS) scaffolding, helpers… forthcoming.)
  3. History API (client side): capture navigation “internal” to an SPA; eg:
    ## app.coffee
    page.base "/#{lang}"
    page '/favs',->show_screen '#favs'; set_title 'Favorites'
    page '/i/',->show_screen '#dir'; set_title 'Directory'
    page '/i/:id',->show_screen '#item'; set_title 'Item'
    
    1. Render absolute URLs, so can navigate up/down the URL path, eg app.-.html.coffee:
      a href:"/#{lang}/i/123",'Item'
      a href:"/#{lang}/help/me",->i '.fa.fa-question';text 'Help'
      a href:"/#{lang}/flow",->i '.fa.fa-shopping-cart';text 'Workflow'
      
    2. Screens (HTML <section>s) have unique IDs, which show_screen copies to an attribute on <body>:
      $('body').attr 'data-screen',p

      so can easily target screens in CSS, eg (Stylus):

      a
      	header &
      		color inherit
      		[data-screen="#favs"] &.fa-star
      		[data-screen="#profile"] &.fa-user
      			color white
      

      (But, second thoughts about this example: mixing state with styling smells…)

4. Grayscreening

Mockups that work in browser!

Top-down…

  1. Nav links (backdoor)
  2. Layouts: flexbox!
    1. Patterns…
  3. Widgets
    1. Nav bars, dropdowns, modals…

5. Continuous

Styleguide

Editing (WYSIWYG)

i18n/L10n

Data Modeling and I/O

Auth



Comments are closed.