STEREO INTERNET TOOLKIT
DOCUMENTATION — v1.4.0
Build the simplest possible version
and then move on with your life!
stereo - primitive/generic - simplified express concept for presentation (user-facing) web application layer - designed to make routing and display a breeze - designed to handle the foundation/baseline setup for server-rendered web apps and enable FAST and efficient dev workflow (remove friction, lower barriers to productivity)

```jsx stereo is: - mysql - php - handlebars - alto - db_handlers - helper abstractions (cookies, email, http requests, settings, etc) - tachyons - alpine - turbolinks - workflow/architecture/conventions/opinions ```

## addl features/content -- links to docs for all included libs (tachyons, alto, etc) stereo / dw docs - want a list of all globally available variables (user_group, is_admin, user_id, etc) (in addition to functions) stereo setup guide - post/article about how to install and best practices for setting up your site not particularly covered by the framework, but good practices (script preloading, enable gzip, simple server-level optimizations / easy wins for perf) here's where to generate favicons, get loader icons, cool 3rd-party libs we like (dropzone, fancybox, etc) want to make templates for stereo/dw like cargo https://cargo.site/Templates that you can just use in your (/my) sites but maybe based on tailwind (or tachyons) []components gallery - list of copy/paste components to throw into your project - php snippets too (bookmarks for snippets that manipulate text, arrays, dates, etc) (shit i always have to look up lol) - and if you like functional components and data management, let me talk to you about our lord and savior darkwave []future - tutorials (medium/devto articles? video screencasts) - how to build ___ w/ stereo (& directus/dw) - compiled stimulus w/ stereo/dw/lexxi? https://stimulusjs.org/handbook/installing#using-without-a-build-system && turbolinks! https://github.com/turbolinks/turbolinks - examples for how to integrate w/ cloud services (s3, twilio, mailgun, etc) []cool software you can use w/ this (write some tutorial examples) - want to do functional programming w/ php? https://github.com/kapolos/pramda - caching / key/val storage http://www.scrapbook.cash/ stereo docs list of cool resources/patterns fw-agnostic libs for common solutions (vanilla js, etc) like this kind of stuff https://www.smashingmagazine.com/2019/05/hybrid-lazy-loading-progressive-migration-native/ []collection of cool resources * 58b of css to look great everwhere https://jrl.ninja/etc/1/ also -- this looks hella badass https://teutonic.co/ lightweight default styles / jumpstart web dev projects * html5bp is not for everyone but it works for a lot of ppl https://github.com/h5bp/html5-boilerplate * you concerned w/ performance? check this out: https://github.com/h5bp/server-configs-apache stereo find a cool diagram of a component stereo system & note components (speakers, receiver, cd player, wires, remote, etc) then show a video of what stereo covers (database, router, templates, utility functions, org system/workflow/conventions, etc) make analogies where appripriate it's like a component stereo system. the important part is the content/application (bring your cds, records, karaoke idk) (write your logic in a neeat and organized way, what are you making?) docs - simple outline (w/ diagrams) about what stereo does highlight the important pieces (htaccess, index/bootstrap logic, config, routes, etc) []stereo docs - make a cool diagram of the application structure -- where it fits in the "stack" -- problems it solves, what it covers, where it stops file tree (all the pieces, everything that's included) education - screencasts on how the system works, what it does, helper functions, workflows, app structure, "boostrap"/processing logic, etc Stereo docs example of how one would use with composer meh stereo list of recommended hosts, serverless setup tutorials, how to set up on varios platforms (do, linode, ec2, etc) []outline system requirements - something about the file structure (everything is organized in a very straightforward manner) - global array_encode - global array_decode - stereo helpers (is_admin, is_auth, year, etc) need documentation (what's available, etc) - "we're not including a lot of js stuff bc we don't want to make TOO many assumptions about what you're doing. darkwave, however, continues this line of thought (w/ the patterns) and provides provides a ton of js resources for building all kinds of stuff on top of this" - re: favicons -- you can do whatever you want obv, but we generated the favicons here: https://www.favicon-generator.org/ -- it seems like the 'best practices' for favicons change frequently. we did a few cross-platform ones (here), check out the 'favicons' partial if you want to see what's going on. btw this includes a manifest.json, so if you're doing anything w/ that, track it down and edit accordingly (it's in images/favicons whatever) stereo docs - writing/using handlebars functions - adding functions/methods to the "system" class - which variables and functions are available colophon - list of projects we utilize (alto router, hbars, etc) and credits for the developers who made those things outline vision (simplicity / limited scope, intentionally limited, evergreen api, etc), contributions are welcome, but all contributions will be considered with this perspective in mind - coding styleguide - coding conventions for building plugins & themes - requirements for dependencies (3rd-party lib restrictions, etc) - quasi-open (juried, anyone is welcome but shit needs to be approved by core group or whatever) []boilerplate/demo - turn-key styleguide w/ light tachyons components []original demo content (what do horses eat, partials, loops, etc) []live version where i can test new stuff (/validate that things are working) []demo.stereotk.com

# EXTERNAL RESOURCES stereo cool alt lib for db stuff? https://github.com/troelskn/pdoext stereo/dw - cool to have a collection of cool resources you can use to make web sites out of nothing (copy/paste elements & stuff) https://www.emojicopy.com/ https://www.toptal.com/designers/htmlarrows/ https://thenounproject.com/ https://github.com/tabler/tabler-icons []resource links -- bitchin tachyons components: http://tachy.tools/ - add links to component docs - http://tachyons.io/docs/ (ships w/ 4.1.0 (just like rails!)) - http://tachyons.io/components/ - TACHYONS COLORS: http://tachyons.io/docs/themes/skins/ - it would be really cool if someone made a cool chart of these - https://www.tachyonstemplates.com/components - https://www.tachyonstemplates.com/ - handy tachyons pieces - http://tachyons.io/docs/typography/scale/ - http://tachyons.io/docs/typography/line-height/ - http://tachyons.io/docs/layout/display/ - http://tachyons.io/docs/layout/heights/ - http://tachyons.io/docs/elements/lists/ - http://tachyons.io/docs/layout/spacing/ - http://tachyons.io/docs/typography/text-align/ - http://tachyons.io/docs/elements/tables/ - http://tachyons.io/docs/layout/floats/ - http://tachyons.io/docs/layout/widths/ - http://tachyons.io/docs/layout/heights/ - http://tachyons.io/docs/themes/borders/ - http://tachyons.io/docs/typography/text-decoration/ - http://tachyons.io/docs/typography/font-style/ - http://tachyons.io/docs/elements/links/ - http://tachyons.io/components/layout/flag-object/index.html - http://tachyons.io/components/lists/slab-stat/index.html - make notes about easily finding components / building patterns with both libs - tachyons styles - http://tachyons.io/docs/table-of-styles/ - http://tachyons.io/docs/table-of-properties/ - tachyons crash course - https://iamsteve.me/blog/entry/why-you-should-use-tachyons-to-make-css-easier - alto router docs http://altorouter.com/usage/mapping-routes.html - something about breakpoints - we set a few for you, if you want to target specific devices (it happens sometimes, ok?) - if you want to use the tachyons breakpoints (s/m/l) that's a good idea, too. good example for that kind of thing here: http://tachyons.io/docs/typography/text-decoration/ /* breakpoints match Tachyons media queries: https://github.com/tachyons-css/tachyons-queries */ /* need to be more specific? check this out: https://responsivedesign.is/develop/browser-feature-support/media-queries-for-common-device-breakpoints */
INSTALLATION / SETUP

[[FIRST PRINCIPLES NEW SECTION - that briefly outlines the impetus for creating the framework, the need it fills, and the ideals/conventions intended to be used for creating apps/sites w/ the framework ]]

This tool kit was designed to make it easy to develop internet-based applications that operate in perpetuity with minimal technical overhead. Templates are dynamically rendered on the server and delivered as static html. This frameworks provides organization for your project and conventions for making technical decisions.

Installation
  • Download the application files and put them on your server or dev environment.
  • Edit the config file: ./settings.php
  • Set up some routes: ./controllers/_routes.php
  • Make some templates: ./pages/index.hbs
  • Go nuts!
  • Server Requirements
  • PHP >= 5.3
  • MYSQL >= 3.0
  • Apache >= 2.4 (nginx support coming soon)
  • optional - allow_url_fopen (?? or whatever...if uploading files) - imagemagick (if messing with images) - apc (if you want to use db caching)
  • * NOTE: If you're using Coda, install the handlebars mode for syntax highlighting in your templates.

    Application Structure

    it's pretty easy to see where everything is and what to do settings (global site vars, db setup, this is a good place to set timezone/debugging/upload/php settings, too) global functions / handlebars helpers controllers / routes [back end code]

    [cool to have a image or diagram of the folder tree / application structure]

    you can organize the controllers folder however you want, it doesn't matter...just remember to link all the files you add in _routes.php (we want to automatically include all the files in this folder but there's no easy way to do that w/ php so whatev)

    Included libraries

    FRONT END STUFF (you can easily comment this out if you don't want it, but it's super handy if you're doing stuff from scratch) - tachyons - http://www.tachyons.io/ - jquery (& cookie) - normalize

    URL ROUTING
    something something define what happens a user visits a given url on your site. by default all of the routes are in ./controllers/_routes.php, but as your site grows, you might find it helpful to break that into different files. organize however you like using php includes, just remember to "link" each new php doc/folder you create and keep all that in "controllers". also.
    Routing with HTTP verbs

    You can accept any type of http request and do things with them (really cool if you want to make an actual rest api with http verbs) (all current http verbs are supported, so you can get as specific as you want)

    
    	$app->get('/whatever/url/you/define', function(){
    	  // your PHP code here
    	});
    
    
    	$app->post('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    
    	$app->post('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    
    	$app->put('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    
    	$app->delete('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    
    	$app->patch('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    
    	$app->copy('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    
    	$app->head('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    
    	$app->options('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    Accepting any/all matching HTTP requests

    you can do that too (this code will run whenever you try to access this url with any kind of http request)

    
    	$app->all('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    
    	$app->any('/whatever/url', function(){
    	  // your PHP code here
    	});
    
    Parsing URL parameters

    also, you can do stuff with regex or whatever to retrieve parameters from the urls. here are a few examples. see the alto router docs for more detailed info (stereo uses alto router, so you can parse the parameters in a lot of ways. here are a few examples. refer to the docs for more) - https://github.com/dannyvankooten/AltoRouter - how to work w/ the router: https://longren.io/basic-routing-in-php-with-altorouter/ CHECK IT OUT!!! http://altorouter.com/usage/mapping-routes.html

    With or without the trailing slash:

    
    	$app->get('/about/?', function(){
    	  // your PHP code here
    	});
    

    Using a url parameter as variable:

    
    	$app->get('/register/activate/[*:hash]', function($hash){ 
    	  // url parameter is available to your PHP code as $hash
    	});
    

    And of course you can access _GET vars like normal PHP docs:

    
    	$app->get('/directory/search/?', function(){ 
    	  // ex url: http://partyphysics.com/directory/search/?fish=betta&dish=espinacas&planet=keppler-452b
    	  echo $_GET['fish'];  // betta
    	  echo $_GET['dish'];  // espinacas
    	  echo $_GET['planet'];  // keppler-452b
    	});		
    
    RENDERING CONTENT
    once you have a URL route set up, it's a good idea to define what happens there. the sky is almost the limit for what you can do at that point...it just has to be php. here are some cool options!
    render_template ($options)

    Render a handlebars template with special STEREO abstraction variables () -- future docs: the passwords part of this requires php >= 5.5

    
    	$app->get('/handlebars-stereo', function(){
    	  $GLOBALS['app']->render_template(array(
    	    'template' => 'planets',
    	    'title' => 'Cool Planets',
    	    'layout' => false,
    	    'data' => array(
    	      'righteous_content' => 'for_sure',
    	      'planets' => array(
    	        'Mercury', 'Venus', 'Earth', 'Nibiru'
    	      )
    	    )
    	  ));
    	});
    
    render_json ($options)

    Render an array of data as a JSON string and send with JSON headers (handy for easily making API responses)

    
    	$app->post('/json-response', function(){
    	  $GLOBALS['app']->render_json(array(
    	    'righteous_content' => 'for sure',
    	    'planets' => array(
    	      'Mercury', 'Venus', 'Earth', 'Nibiru'
    	    )
    	  ));
    	});
    
    render ($template_name, $data)

    Render a handlebars template using a php array for saturation (note this is not attached to the stereo $app class)

    
    	$app->get('/handlebars-normal', function(){
    	  echo $GLOBALS['engine']->render('handlebars-example', array(
    	    'righteous_content' => 'for sure',
    	    'planets' => array(
    	      'Mercury', 'Venus', 'Earth', 'Nibiru'
    	    )
    	  ));
    	});
    
    Show a document at a given url

    want to show just a document? do it like this

    
    	$app->get('/normal-page', function(){
    	  require __DIR__ . '/pages/whatever.html';
    	});
    
    Send headers

    send a header. it can be whatever you want...this is nothing special with the framework, just something good to remember

    
    	$app->get('/whatever', function(){
    	  header("Location: http://partyphysics.com/");
    	});
    
    TEMPLATES
    something something templates go in ./pages and you can call them whatever you want. you can organize this however you want, too! link to handlebars docs for more info.
    Basic Variables

    the simplest thing to do. if you use render_template, stereo includes a few by default (year, etc) as well as a few special things (is_admin, auth, user_id, etc) (title [uses the site title by default, so it's kinda optional])

    php

    
    	$app->get('/variable-example', function(){
    	  $GLOBALS['app']->render_template(array(
    	    'template' => 'demo',
    	    'data' => array(
    	      'fish' => 'salmon',
    	      'dish' => 'paella',
    	      'planet' => 'Nibiru'
    	    )
    	  ));
    	});
    

    hbs (note about literals { { { } } } vs { { } } -- by default hbars doesn't parse html tags, so if you want to have them rendered, do this)

    
    	<h2>Simple Variables Example</h2>
    	<h3>Cool Fish: {{fish}}</h3>
    	<h3>Cool Dish: {{dish}}</h3>
    	<h3>Cool Planet: {{planet}}</h3>
    
    Iterating Arrays

    it's hella easy, just like a foreach loop. you can even nest the arrays to infinity (and beyond) (sorry) (it can be as simple or complex as you want to make it) (see the demo controller/templates for an example of more complex array iteration)

    php (simple & complex example from demo)

    
    	$app->get('/array-example', function(){
    	  $GLOBALS['app']->render_template(array(
    	    'template' => 'demo',
    	    'data' => array(
    	      'snacks' => array(
    	        'Carrots',
    	        'Hay',
    	        'Sugar Cubes',
    	        'Oats',
    	        'Apples',
    	        'Weaker Horses'
    	      )
    	    )
    	  ));
    	});
    

    hbs (simple & complex example from demo)

    
    	<ul>
    	  {{#each snacks}}
    	  <li>{{this}}</li>
    	  {{/each}}
    	</ul>
    
    Simple Logic

    you can do some simple logic to check if a variable exists (or has value). if you would like to do more complex logic, check out [if_either], [in_array], [is]

    php

    
    	$app->get('/logic-example', function(){
    	  $GLOBALS['app']->render_template(array(
    	    'template' => 'demo',
    	    'data' => array(
    	      'fish' => 'salmon',
    	      'dish' => 'paella',
    	    )
    	  ));
    	});
    

    hbs (if/else, unless, (normal hbars logic, link to hbars docs) maybe is & link to helpers)

    
    	{{#if fish}}
    	 Salmon is available
    	{{else}} // this won't show:
    	 No salmon for you.
    	{{/if}}
    	
    	{{#unless snacks}}
    	 No snacks available. We have {{dish}}, though.
    	{{else}} // this won't show:
    	 Look at all the snack options:
    	 {{#each snacks}}
    	 - {{this}} <br />
    	 {{/each}}
    	{{/unless}}
    
    Partials

    You can include templates in other templates! That is neat! all your partials need to be in the _partials directory, but you can organize that however you want!

    normal php whatever example

    
    	$app->get('/partials-example', function(){
    	  $GLOBALS['app']->render_template(array(
    	    'template' => 'demo',
    	    'data' => array(
    	      'fish' => 'salmon',
    	      'dish' => 'paella',
    	      'planet' => 'Nibiru'
    	    )
    	  ));
    	});
    

    hbs

    
    	<h2>Demo page (rendered with partial from separate template)</h2>
    	
    	<h3>Fish: {{fish}}</h3>
    	<h3>Dish: {{dish}}</h3>
    	
    	{{> planets-partial}}
    

    hbs (partial code) (see how it has access to the same data?)

    
    	<ul>
    	  {{#each planets}}
    	  <li>{{this}}</li>
    	  {{/each}}
    	</ul>
    
    Global Layouts

    if you want to use a global header footer, you can! you can define as many global wrappers/layouts as you want (like express, django, ember, whatever...wow!) if you leave the "layout" parameter blank, STEREO will use the layout in ./pages/_layouts/base.hbs by default. your content will be rendered where the [[outlet]] part is

    php example

    
    	$app->get('/layouts-example', function(){
    	  $GLOBALS['app']->render_template(array(
    	    'template' => 'demo',
    	    'title' => 'Site Title Whatever',
    	    'layout' => 'admin',  // false for nothing, base by default
    	    'data' => array(
    	      'fish' => 'salmon',
    	      'dish' => 'paella',
    	      'planets' => array(
    	        'Mercury', 'Venus', 'Earth', 'Nibiru'
    	      )
    	    )
    	  ));
    	});
    

    hbs (wrapper)

    
    	<!DOCTYPE html>
    	<html>
    	<head>
    	  <title>{{title}}</title>
    	  <meta charset="utf-8" />
    	  <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
    	  <link rel="stylesheet" href="/css/app.css" />
    	</head>
    	<body>
    	
    	  <div class="header"><h1>Site Title Whatever</h1></div>
    	
    	  <div class="container">
    	    [[outlet]]  // this is where the content will be rendered
    	  </div>
    	
    	  <div class="footer">(c) {{year}} -- All rights reserved or whatever.</div>
    	
    	<script src="/js/vendor/jquery.min.js"></script>
    	<script src="/js/app.js"></script>
    	
    	</body>
    	</html>
    

    hbs

    
    	<h2>Demo page (rendered with global wrapper)</h2>
    	
    	<h3>Fish: {{fish}}</h3>
    	<h3>Dish: {{dish}}</h3>
    	
    	<ul>
    	  {{#each planets}}
    	  <li>{{this}}</li>
    	  {{/each}}
    	</ul>
    
    Template Locals (Global Variables)

    need to make an arbitrary variable/array available to all the templates? use $GLOBALS['locals'] (hold for laugh) but seriously, folks, treat it like an array and whatever you need. and if it's an array is something you can iterate over. and, of course, all of this is available to the application as $GLOBALS['locals']['numbers'] or whatever

    php example

    
    	$GLOBALS['locals']['eat_this'] = "breakfast";
    

    hbs

    
    	Let's have {{locals.eat_this}} for dinner.
    

    php example

    
    	$GLOBALS['locals']['colors'] = array('red', 'salmon', 'lilac', 'azul');
    

    hbs

    
    	<ul>
    	  {{#each locals.colors}}
    	  <li>{{this}}</li>
    	  {{/each}}
    	</ul>
    
    HANDLEBARS HELPERS
    You can use handlebars helpers to transform any of your handlebars variables. STEREO includes a handful of common php functions as helpers plus a few special ones. you can write your own, too! it's super easy!
    lowercase

    transform string to lowercase (link to php docs)

    
    	{{lowercase hbar_variable}}
    	// "Don't Fear The Reaper"   --->   "don't fear the reaper"
    
    addslashes

    escape quotes (link to php docs)

    
    	{{addshlashes hbar_variable}}
    	// "Don't Fear The Reaper"   --->   "Don\'t Fear The Reaper"
    
    nl2br

    note u gotta use 3 curly braces w/ this because it turns plain text to html just F Y I// nl2br // transform line breaks to "br /" ()link to php docs

    
    	{{{nl2br hbar_variable}}}
    	/* 
    	   "Don't Fear
    	The Reaper"   --->   "Don't Fear <br /> The Reaper"
    	*/
    
    to_fixed

    to_fixed - return given number calculated to given number of decimal places (defaults to 2)

    
    	{{to_fixed hbar_variable}}    // 3.14
    	{{to_fixed hbar_variable 4}}  // 3.1415
    	{{to_fixed hbar_variable 0}}  // 3
    
    date

    parse unix timestamp into human-readable date format (basically php's date()). use "now" for current date/time

    
    	{{date hbar_variable "m/d/Y"}}  // "1459036800"   --->   "3/27/2015"
    	{{date "now" "m/d/Y"}}  // "10/31/2020"
    
    date_transform

    transform time/date format (same as date, but it turns a string [like a js date object] into unix time first)

    
    	{{date_transform hbar_variable "m/d/Y"}}  // "Sun Aug 14 2016 00:00:00 +0000"   --->   "8/14/2016"
    
    in_array

    in_array -- return true(/false) if this item is(/is not) in the array -- can be a csv string, too

    
    	/*
    	  colors_array = ['red', 'salmon', 'lilac', 'azul']
    	                    -- or --
    	  colors_array = "red, salmon, lilac, azul"
    	*/
    	
    	{{#in_array "green" colors_array }} 
    	 it's in the array!
    	{{else}} 
    	 it's not in :(
    	{{/in_array}}		
    
    if_either

    if_either - return true if the first thing equals either the second or third thing (they could also be hbar_variables)

    
    	{{#if_either hbar_variable "salmon" "azul"}}
    	 it's true :)
    	{{else}}
    	 it's false :(
    	{{/if_either}}
    
    is

    this one has a lot of cool options // is // basic comparison operators you can compare either hbars variables or strings (and use arrays, in some cases) acceptable operators: ==, ===, not, !=, <,>, <=,>=, in, typeof

    
    	{{#is hbar_variable "==" "paella"}}
    	 yes :)
    	{{else}}
    	 no :(
    	{{/is}}
    

    // will also show if the first thing is contained within the second thing (even it's CSV) (2nd thing can be a string, csv list, or an array) // 2nd param can beither array or csv

    
    	{{#is hbar_variable_1 "in" hbar_variable_2}}
    	 yes :)
    	{{else}}
    	 no :(
    	{{/is}}
    

    // you can also compare variables by types (array, string, integer, etc) (uses php gettype

    
    	{{#is hbar_variable_1 "typeof" hbar_variable_2}}
    	 yes :)
    	{{else}}
    	 no :(
    	{{/is}}
    
    Custom Helpers

    it's easy, just write a php function and put it in ./controllers/_global.php and then use it in whatever template. look! (you can copy this code as a good starting point). here's a simple example combining a couple simple native php functions. take a look at the handlebars-helpers file to see more examples of how we put together the more complex helpers (we got a lot of these from somewhere, anyone remember where?)

    php example

    
    	$engine->addHelper('lowercase_slashes', function($template, $context, $args, $source) {
    	  $parsed_args = $template->parseArguments($args);
    	  return lowercase(addslashes($context->get($parsed_args[0])));
    	});
    

    corresponding hbs (wrapper)

    
    	{{lowercase_slashes hbar_variable}}
    	// "Don't Fear The Reaper"   --->   "don\'t fear the reaper"
    
    HTTP REQUESTS
    something something it's trivially easy to work with other systems if you use an api! look how easy it is to consume 3rd-party services - a lot of times you might have a need to integrate things you've made with other systems. fortunately, everyone can consume/produce json apis and this is perfect.
    http_request ($url, $data)

    Make an http request to a given url (using curl), send data, return the raw response.

    
    	$data = $GLOBALS['app']->http_request('https://external-api.com/v3/example-response', array(
    	  'user_id' => 581146,
    	  'api_key' => '696719xvckvzxspigh24y1e-b'
    	));
    
    if you need to make a json/http request a GET request instead of post, do this:
    json_request ($url, $data)

    Make an http request to a given url, send data, and return an array of response data (expects response in json format...like the kind sent from render_json). (append _debug to just make an http request and see the raw result)

    
    	$data = $GLOBALS['app']->json_request('https://external-api.com/v3/example-response', array(
    	  'user_id' => 581146,
    	  'api_key' => '696719xvckvzxspigh24y1e-b'
    	));
    	
    	/* expected response: 
    	  {
    	    first_name: "Eddie",
    	    last_name: "Mercury",
    	    favorite_fish: "Salmon"
    	  }
    	*/
    	
    	print_r($data);
    	
    	/* 
    	  array(
    	    'first_name' => 'Eddie',
    	    'last_name' => 'Mercury',
    	    'favorite_fish' => 'Salmon'
    	  );
    	*/
    
    api_request ($url, $data)

    Make a json request to a given url, send hard-coded data from cookies (user_id, auth_token, admin_token, moderator_token). Specialized for use with STEREO patterns/components (coming soon) -- // same as json_request, but in addition to data params, this sends the user_id, auth_token, admin_token, moderator_token set in cookies as those params, uses the $GLOBALS['api_root'] in settings. you can set extra variables to send (like if your api requires a key or whatever...see stereo-core.php, the function called "api_request" obv) (append _debug to just make an http request and see the raw result)

    
    	$data = $GLOBALS['app']->api_request('/admin/events/screen', array(
    	  'parameter_1' => 'cool stuff',
    	  'parameter_2' => 'cooler stuff'
    	));
    	
    	/* data sent to api would look something like:
    	  {
    	    user_id: "581146",
    	    admin_token: "123123-1230973t2097sdv",
    	    auth_token: "1203920rdvslasphwg",
    	    moderator_token: false,
    	    parameter_1: "cool stuff",
    	    parameter_2: "cooler stuff"
    	  }
    	*/
    	
    	/* expected response: 
    	  {
    	    first_name: "Eddie",
    	    last_name: "Mercury",
    	    favorite_fish: "Salmon"
    	  }
    	*/
    	
    	print_r($data);
    	
    	/* 
    	  array(
    	    'first_name' => 'Eddie',
    	    'last_name' => 'Mercury',
    	    'favorite_fish' => 'Salmon'
    	  );
    	*/
    
    COOKIES
    cookie_set ($key, $value, $expiration_date)

    Set a cookie for a given amount of time.

    
    	$GLOBALS['app']->cookie_set(
    	  'user_name',
    	  'Buzz',  // can be a string or an array or whatever
    	  1461619625  // optional, in unix time format, default is time() + 31536000000
    	);
    
    cookie_get ($key)

    Return the value of a given cookie.

    
    	echo $GLOBALS['app']->cookie_get('user_name');  // Buzz
    
    cookie_delete ($key)

    Delete a given cookie.

    
    	$GLOBALS['app']->cookie_delete('user_name');
    
    DATA
    (something mysql crud functionality, requires pdo (php 5.3+), global functions, not part of the $app class, so use it however it suits you)
    db_insert ($table, $input)

    Sanitize parameters and insert array of data into database. Returns the id of the record created.

    
    	$new_id = db_insert("celestial_bodies", array(
    	  'name' => 'Luna',
    	  'classification' => 'moon',
    	  'comment' => 'Earth\'s moon, also commonly referred to as "the moon"'
    	));
    
    	echo $new_id;
    
    db_find ($table, $criteria, $options)

    Sanitize parameters and retrieve data from database. (SELECT *)
    Returns an array with the the data and a total number of results.

    
    	$planets = db_find("celestial_bodies", "classification = 'planet' ORDER BY title ASC LIMIT 8");
    	
    	foreach ($planets['data'] as $p){
    	  echo $p['title'];
    	  echo $p['classification'];
    	  // etc, etc
    	}
    	
    	echo $planets['total'];  // 8
    

    You can run a raw query (if you need to do joins or anything fancy)

    
    	$space_objects = db_find("", "SELECT title, classification FROM celestial_bodies WHERE id IS NOT NULL", array(
    	  'raw' => true
    	));
    

    If APC is enabled on your system, you can cache your queries

    
    	$planets = db_find("celestial_bodies", "classification = 'planet' ORDER BY title ASC", array(
    	  'cache' => true,
    	  'cache_length' => 120  // optional, in seconds, default is 60
    	));
    
    db_update ($table, $input, $criteria)

    Sanitize parameters and update a database record.

    
    	db_update("celestial_bodies", array(
    	  'name' => 'Mars',
    	  'comment' => 'Research "The Phobos Incident" -- we are not alone'
    	), "name='Marz'");
    
    db_delete ($table, $criteria)

    Sanitize parameters and delete a given database record.

    
    	db_delete("celestial_bodies", "name='venice'");
    
    MISC HELPER FUNCTIONS
    email_send ($options)

    Send an plain text or html email (with mailgun api, if available, otherwise using php mail).

    
    	$GLOBALS['app']->email_send(array(
    	  'to' => 'static@hexgirlfriend.com',
    	  'from' => 'sitemeister@partyphysics.com',
    	  'cc' => 'cc-address@partyphysics.com',  // optional
    	  'bcc' => 'bcc-address@partyphysics.com',  // optional
    	  'reply-to' => 'reply-address@partyphysics.com',  // optional
    	  'subject' => 'Send me an email',
    	  'html' => true,  // optional, message will be sent as plain text unless this is true
    	  'message' => 'Right now...<br /><br /><br /><b><u>RIGHT NOW</u></b>'
    	));
    
    update docs: NOW YOU CAN USE TEMPLATES TO MAKE HTML EMAILS!
    
    	$GLOBALS['app']->email_send(array(
    		'from' => 'static@hexgirlfriend.com',
    		'to' => 'jonathan.youngblood@gmail.com',
    	
    		'template' => 'mail/test',
    		'layout' => 'mail',
    	// 	'preview' => true,
    	// 	'debug' => true,
    		'data' => array(
    			'email' => 'jonathan.youngblood@gmail.com'
    		),
    	
    	));
    
    client_ip ()

    Return the address of the computer making the current request.

    
    	echo $GLOBALS['app']->client_ip();
    

    fixit disclaimer about ip addresses and accuracy (we use a couple of redundant methods, but you can't really trust them in general because of the nature of how ip addresses work...easily spoofable, etc)

    more of these: url_slug url_strip url_validate mysql_date video_id br2nl pagination_query pagination_links

    ADVANCED

    - how to work w/ nginx link to patterns/components repo - examples of how to do various kinds of things - copy/paste code samples - routing - crud operations - etc - working w/ compose pattern lib reqs [- phmagick (imagemagick) [- s3 upload (what's it called?) [- smoke [- dropzone [- fancybox [- mailgun setting max file size (w/ htaccess / php) upload_max_filesize = 20M post_max_size = 20M