Monkey is a framework to build quick and simple AJAX powered PHP websites.
JavaScript PHP ApacheConf
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


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 Note: This may not be running on the newest version of monkey.

Gettings Started & Settings

Before we begin you will need to copy the class, javascript, and .htaccess files to where you want your working directory. While these files can go anywhere I would suggest you create a classes and js directory for the files, since you'll probably be using more than what is included. Monkey requires jQuery, and well as Malsups jQuery Form plugin. These are all included in the monkey package.

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.

default_placement #content

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.

loading_class monkey-loading

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.

scripts_direcotry /js/

This is the directory your javascript files are located. This will be used when loading scripts with the Monkey load_scripts() function.

passthrough_variables array()

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.

additional_scripts array()

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:

Name Filename Notes
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
meta array()

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.

debug true

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.

get_page_function null

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.

homepage home

This is the slug that is used when there is no slug (at the top level of your site).

page_directory pages

This directory is where pages are stored, used in the default filename function, which can be overriden by the get_page_function setting.

google_analytics_tracking_id UA-XXXXXXXX-X

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 additional_scripts setting.

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:

  1. Go back over the settings, make sure everything is correct. Check the console.log() for any messages that may have gotten passed to it.
  2. Look at the default setup. There are two examples, the first being the repository itself, and the second being in the test-site directory. 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.
  3. 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.

  1. The link has the natural class applied to it. Any anchor tag with that class will be ignored and when you click on it will process normally.
  2. Links with a target are ignored and act normally.
  3. Links that go to other sites or call other protocols will not be handled by monkey in any way.
  4. 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.

  1. If it has the natural class it will redirect the browser to the link, not simply ajax load it into the current page.
  2. If it has a data-target attribute it will open the link at that target.
  3. 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 target or 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");

Then you would call the done() function, listed at the bottom of this section, to tell monkey that you were done providing data and your ready to send it back to the browser. When the Monkey javascript got the data back it would place your $table_data into the #filterable-table for you, without reloading the rest of the content. You could also use this in conjunction with the prepend or append $placement methods to have it simply add the user entered data into the form.


When you update a specific sections content your going to want to place the content on the page in it's appropirate location. This is done for two reasons; it makes sure the content is there for the first load, and it gives the content some way to be loaded when the user is not using AJAX (either because there browser does not support the required features for Monkey to enable AJAX loading or because they have javascript turned off). Expanding off the above example you might have your HTML look something like this:

<table id="filterable-table">
	<?php echo get_content('#filterable-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 18000000 to it (or 5 minutes in javascript time).


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 content() and 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.


The 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 new.

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.


The 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.

There are several other functions and specific varibles you can call in the monkey PHP and javascript classes, they are described in more detail in the following section.


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 print_r() and 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

Outside of the main ones your'll probably be using the most there are other functions and variables Monkey has that you may find of usef. Below are some notes for every public function and variable in Monkey, broken into two parts, PHP and JavaScript. This is just a quick summary, more deatils on what they do and how they do it can be found in their respective files.




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:

	[#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 pass a javascript callback to, which will be fired once the AJAX is done. 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 an object that stores the settings, only the setting needed by the JavaScript are passed to it.



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.

Known Issues


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.

Future Improvements

  • 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().