Monkey is a framework to build quick and simple AJAX powered PHP websites.
Want to see it in action? Check out the test-site at http://phillipgooch.com/github-examples/monkey-test-site/. Note: This may not be running on the newest version of monkey.
Gettings Started & Settings
Once we have the files in place it's time to start work on the site. In your index or other initilization file create an instace of monkey, passing any variables you whish to adjust. While monkey will work out of the box as is with the default settings, you probably going to want to change a few things before you get started. You can change the settings by passing an assocative array into the constructor class, where it will be merged with the defaults array to create your final settings.
Here is a list of the settings, their defaults, details on how you can change them, and what is required of you when you do.
This is the location where content will be placed into your framework page. It can be any valid CSS or jQuery selector, however you want it to be something that will never be repeated. An ID would be preferable for this as it should only ever appear once per page.
This is the class that will be applied to the HTML tag when Monkey is loading a new page, and automatically removed when it is done. Whatever is passed here will also be applied again with -form or -link appended if it is a form or link submission.
The directory from root your monkey site is in. If you are on the root level of your vhost then you would keep this as an empty string. This is used when loading pages and updating the URLs.
This is a assocative array that contains any varibles you would like passed to the pages you are loading. This is usefull for things like database connections that you have already opened and do not whish to re-open on every page. The
key will be the name of the varible when it is passed and the
value will be that varible.
Contains an array of additional scripts you would like to include in the
load_scripts() call. Every script is given a name (stored as the
key) and a filename stored as the
value). This can also be used to override the exsiting scripts, allowing you to use alternate versions on ones placed in a CDN. The default scripts are:
|jQuery||jquery-1.11.2.min.js||Just a basic version of jQuery.|
|malsup-form||jquery.form.js||A copy of Malsup's jQuery from plugin.|
|monkey||monkey.js||The monkey scripts which handel all the AJAX-ness|
The meta data included when the
meta() function is called. This will be included on every page, although it can be overwritten or changed on any page with the
meta() function. Further details on the use of this function can be found below. All items added will use the array
key as the "name" and the
value as the content. The only exception for this is the item with the
key "title", which will be used to create a title tag element instead. There are no default meta tags assigned.
True or false, wether or not you want to output debug information. All debug information is output to the console.log, even recoverable PHP errors are passed to it.
The name of the funciton to call to get page files. If this is null then it will use it's own internal page finder that looks for PHP files in the
page_directory direcotry with the same name as the request slug (the first /section/ of the request path). If you are at the homepage or root level of your site then the
homepage settings will be used as the slug.
If this setting is passed a function it will call that function to get the name of the file to load for the page. The function will be passed 3 variables; the filename generated by the built in function, the slug that was used to generate the filename, and the monkey class object, which you can in turn use to generate a new filename. See the varibles and functions section below for the different ways you get get URL information from the monkey class object. This function should return a filename, complete with path.
If the file name generated by the built in function or returned by the provided function cannot be found it will look for a 404 page. This page is locaed in the
page_directory with the filename
_404.php. If that page cannot be found then it will simple output a basic HTML message.
This is the slug that is used when there is no slug (at the top level of your site).
This directory is where pages are stored, used in the default filename function, which can be overriden by the
Since AJAX pages are loaded differently than a normal web page Google Analytics does not register the page loads properly instead only getting the first one. For accurace analytics you can pass this settings your sites Tracking ID and it will automatically include the GA scripts the reccomended way as well and trigger the proper calls on each AJAX page load. If you leave this with the default settings then no Google Analytics scripting will be included.
Now that you have called the Monkey class, passing any settings that you want to use, you can continue making your base page. This is the page that will load for every page or, perhaps more accuratly, will have every page loaded into it. This page Take a look at the included index page to get an idea of how you might want yours set up. The important thing is that you have a location to load your content into (as set in the
default_placement settings, which defaults to an element with the ID of content). You will also need to tell monkey to output content there on full page loads, you can do this by calling the
get_content() function, passing the same value that is in the
default_placement settings. There is more information about that function, how it can be used and other ways to use it, in the function section below. You also want to call the
load_scripts() function at the bottom of the body of your document. This function will create the appropriate tags to load in all the JS files that are required, as well as any you ma have added by modifying the
When you load the site up you should (if everything was set up correctly) see a page with your homepage content in it, you can now build off of that to create a full featured AJAX powered site.
If you are having problems getting things set up there are three things you can do:
- Go back over the settings, make sure everything is correct. Check the
console.log()for any messages that may have gotten passed to it.
- Look at the default setup. There are two examples, the first being the repository itself, and the second being in the
test-sitedirectory. Note that the test site directory is not set to be run from that directory, so you will need to adjust it or move it out of that directory for it to work.
- Contact me. I know that this documentation may not be the clearest, and I'm always looking for way to improve it. Let me know what issues you are having so I can both help you get things running and use that to improve this readme. Win win.
In the next section we are going to talk about working with monkey, things you can do, and details on some of the more often used functions.
Working with Monkey
Most of Monkey works in the background and tries to stay out of the way, and if you just want to have the pages loaded via ajax then thats fine, theres no need to mess with much of the other stuff. Monkey does offer some additional features however.
First we'll talk about links. As with a normal page
a tag links are going to be the bulk of what you use. These will be ajax except under certian conditions.
- The link has the
naturalclass applied to it. Any anchor tag with that class will be ignored and when you click on it will process normally.
- Links with a target are ignored and act normally.
- Links that go to other sites or call other protocols will not be handled by monkey in any way.
- Links pressed with a modifier key held. Holding Control, Alt, or Command will have a link load normally, this allows you to use built-in features of your browser such of Chromes "Command to open in new tab" and "Alt to download link" features.
Out side of normal link you can also turn any element into a pseudo link. By adding the attribute
data-href to an element it will turn it into a link. This is great for things like table rows that you want clickable to edit that record. These will always be AJAXed except for the following conditions.
- If it has the natural class it will redirect the browser to the link, not simply ajax load it into the current page.
- If it has a
data-targetattribute it will open the link at that target.
- If the Command or Control buttons are help while pressing the link it will open it in a new window.
Forms work very similarly, AJAX submitting unless a
natural class is given, or a modifier is held. Forms however can take advantage of a few additional functions to update sub-sections of the page. These function can be used in other conditions as well giving we more flxibilty to change only parts of your content. There are a few functions that are commonly used when making a site more dynamic.
The content function stores sections of content to be placed on the page. This is the same function that is used to replace the entire page when you navigate around the site, however you can interact with it directly to do a sub section like a table on the page. This, when used with the
get_content() function below, make it easy to have things "live" update. This function takes three varibles.
The first varible is the
$location you want the content to go. This can be any valid CSS or jQuery selector. Keep in mind that there may be a performance hit for replacing multiple sections at once.
The second varible is the
$content you want to place there. This can be anything from a blank string to remove the content to entire tables of data.
The final varible is the
$placement of the content. This has three options with replace being the default option used if nothing, or something it doesn't recognize, is passed:
- prepend - place the content before the existing content at that location.
- append - place the content after the existing content at the location.
- replace - Replace the content at the specified location.
For example lets say you want to update a table of data based on some filters in the form. You can do this by generating to table contents at the top of the table, before any page content is output, and placing it into the
content() functions. It might liik something like:
$table_data = $db->make_table('awesome-data-set','where `is-awesome` = "true"); $_monkey->content('#filterable-table',$table_data);
Then you would call the
$table_data into the
#filterable-table for you, without reloading the rest of the content. You could also use this in conjunction with the
$placement methods to have it simply add the user entered data into the form.
<table id="filterable-table"> <?php echo get_content('#filterable-table'); ?> </table>
That will load the content it for the first load and the above
content() function, in cooperation with the
done() function below, will update that same element when the AJAX request is returned.
The callback function can be used to trigger a script on AJAX load or on page load if AJAX is not used. The first variable will be used as the function name, while any additional variables will be passed to that function in order. This allows you to initiate scripts, or restart scripts once data has been updated. For example if you have a timer keeping track of how long the user has been idle before logging them out, you might have the script trigger on page load like this:
That would, on page load or ajax load, cann the
logoutTimer function and pass
This function, when called, will tell Moneky to stop working on the page load and instead output whatever has been provided. Calling this function will only stop page load when a form has been submitted, otherwise it will continue anyways to load the rest of the page. In the above examples you would call this function after you have added the content but before the page markup starts (right berween the
get_content() functions. This function can also take 1 varbile to force it to stop right away regardless of wether or not a form has ben submitted. This is intended for internal use only, but can be passed externally if you have way that makes sense.
url() function allows you to get information from the URL is a simple manner. If you call the URL function without any varibles you wil get an array with all of the URL parts in it as described in the Variables & Functions,
$pared_url section below. Otherwise it will return part of the URL. The URL is brokwn into individual peices at each directory level. For the examples we will use the fake url /users/add/new/parent/47/
If you pass the URL a number it will get that page of the url for. Using the example URL above
$_monkey->url(3) it will retrun
new. You can get this same information by calling the number with a # prepended on it, so
$_monkey->url('#3') will return the same thing.
You can also get a section by calling the section before it. Each seaction it paired off with the one after it, allowing them all the be called as relations to eachother. For example using the URL above I can call
$_monkey->url("users") and it woudl return
add, and I can call
$_monkey->url("add") and it would return
This is usefull for passing information around in the URL, allowing you to amke it part of your SEO strategy or simply making things programatic and easy to remeber. Some common ways to use this would be to have a single page for adding and editing items in your system, with URLs like /items/add/ and /items/edit/184/awesome-item/. That page would then call
$_monkey->url("items") and you would know that if it was "add" you needed to load the add item version of the page, and if it said edit you would need to call
$_monkey->url("edit") to get the item number you needed to load up to edit. This works well because add and edit pages are generally very similar to eachother so you can save time by only having one version of the page that is slightly tweaked for each action.
meta() function will do one of three things depending on how many varibles you pass it.
If no varbiles are passed it will output the information. This should be called without any varibles in the
<head> of your page. The data created as described in the Getting Started & Settings section by calling it there will automatically be udpated on page change.
The second way to call it would be to pass just a
$tag. If only the
$tag is found then it will return the value of that tag as currently stored. You can use this to get the current page title or description so you can modify it without completly rewriting it.
The third way to call the function is to pass both a tag and some new content, in which case it will be added to the set of meta data to be output on the page. Adding new meta tags will not effect ajax loads, but since search crawler bots do not ajax load page they will see them.
You can use this function to adjust the meta data on a page by page basis. For example you might want to prepend something to your title and completly rewite your default description like this:
$_monkey->meta('title','My Specific Page - '.$_monkey('title')); $_monkey->meta('description','This is my specific page, it gets a specific descrition.');
This would give that page the new title and description, so search engines will see those while the user will see the title updated when the AJAX call is returned, so they have a complete record of the pages they visited in order in their browser history.
You can debug your Monkey site by passing values to the
debug() function, which will in turn pass them to the JS console. The debug function can take 1 or 2 varibles, the first being a string and the second being an object to output. Both the PHP and JS classes have a debug function, with the JS one firing off when called and the PHP firing off when a response is sent to the browser.
Outside of the debug function Monkey will catch any pre-output data and pass it through to the JS, placing it line by line in the
console.log(). This will allow you to use simple functions like
var_dump() in the page wherever you want and see the results in the
console.log(). This will keep the pages loading while allowing you to poke around the code a bit and see why it's not acting in the desired manner.
Variables & Functions
An array containing all the settings currently in use by Monkey. This is generated my merging the provided settings with the defaults.
This is the URL that was requested after the current directory. If you are running Monkey on the root level that means it contains every "directory" in the path.
This is a processed version of the above, and where you will likely want to start if creating a custom get_page_function. The array contains each pseudo-directory stored with a #n string (#1, #2, #2, ect.) and the URL directories paired off in order. This allows you to access information passed through the URL easily. For example take the URL
/this/is/a/test/, once processed
#parsed_url would contain the following array:
Array( [#1] => 'this', [#2] => 'is', [#3] => 'a', [#4] => 'test', [this] => 'is', [is] => 'a', [a] => 'test', [test] => '', )
This is the initializer that makes sure normal page loads occur. You can pass new settings to it when you first call the class. See Getting Started & Settings for more details on what settings can be pased.
This is the function that you give new content sections to, it is discussed in more detail above in the "Working with Monkey" section.
This is the function that can get a section of content for you to place on your page to ensure non AJAX users can still access it, it is discussed in more detail above in the "Working with Monkey" section.
This is the function you call when your done submitting sub-page update information. It is discussed in more detail above in the "Working with Monkey" section.
This gets the specific page that is to be loaded. It will generate the filename as described in the Getting Started & Settings section.
This will create all the script includes required for monkey to work, this includes jQuery. This is talked about in the Getting Started & Settings section.
This function gets the URL parts, either individually or completely. This is covered in more detail in the Working with Monkey section.
This function will store any messages and optional objects to be passed to the JS debug function and ultimate the
console.log() if available.
This is the "constructor" that is called automatically by
load_scripts(). It is passed any options it will need and starts the process of catching any AJAX-able events.
Applies or removes the loading classes from the HTML element. Loading classes are added based on the settings provided to the PHP class (passed through) as well as the type of action you requested (Link, Form, or PopState). You can call this manually to add or remove the loading class.
This function displays a debug message with or without an object.
Outside the monkey class, this creates an object so that errant calls to console.log do not break older versions of IE.
There is a rare bug in safari that causes GET forms with a target to not consistently send the get variables despite them being in the URL. This happen very rarely and only in safari. While the cause is unknown it may be related to any number of Safari specific form issues mentioned in the webkit bug tracker.
Since AJAX calls are not cached (and even in IE where they are they are forcible told not to for consistency) main site pages are not cached. While this does not effect loaded assets like images and scripts it could be improved with some sort of client side caching, either by leveraging browser built in caching or creating a custom caching in the Monkey JS.
Offline capability, at least for some pages, would be nice. It should be theoretically possible, but no research has been done.
More robust and advanced debuging may be in order, although it seems easy to do now not all errors are logged, and logged errors may want to be shown on page when debug is enabled instead always being tucked away in the console.log().