Refactoring a CMS to Use Shared LITTLED Libraries: Difference between revisions

From Littledamien Wiki
Jump to navigation Jump to search
Line 193: Line 193:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
if (!defined("VIEW_[CONTENT-TYPE]_URI"))
if (!defined("[CONTENT-TYPE]_DETAILS_URI"))
{
{
     require_once (realpath(dirname(__FILE__).'/../../')."/_config/scripts.php");
     require_once (realpath(dirname(__FILE__).'/../../')."/_config/scripts.php");

Revision as of 17:20, 13 December 2012

Configuration

Update content settings in site sections CMS

  • AJAX scripts
    • Listings: /_hostmgr/_ajax/utils/listings.php or /_hostmgr/[CONTENT]/_ajax/listings.php
    • Delete: /_hostmgr/_ajax/utils/delete_record.php
    • Update cache: /_hostmgr/_ajax/utils/update_cache.php
    • Resort: /_hostmgr/_ajax/utils/resort.php
  • ID parameter
  • Sortable flag
  • Cache Content flag

Rename existing directories in VCS

  • common > _config
  • common/*.js > _scripts/*.js
  • inline > _ajax
  • forms > _templates/forms
  • content > _templates/content

Refactor PHP content class

  • Refactor include directives
  • (Optional) add Netbeans-friendly class documentation
  • Wrap code within functions in try { /*...*/ } catch (Exception $ex) { /*...*/ }
  • Use db_content_class as base class for all classes that represent records in the database.

Refactor PHP content filtering class

  • Refactor include directives
  • (Optional) add Netbeans-friendly class documentation
  • Refer to a class that’s been refactored for logic updates within the class’s routines.
  • Use filter_collection_class as base class for any class that represents records in the database.
  • Add $site_section property to any class that handles listings and pagination.
    TODO: Consider making this a property of filter_collection_class.
  • Add $section_operations property to any class that handles listings and pagination.
    TODO: Consider making this a property of filter_collection_class.

Add content handlers to PHP cache and resort classes

  • Add include directives for PHP content and content filtering classes to cache_class
  • Add case for the content type in class routines as necessary
    • cache_class::update_content()
    • cache_class::set_initial_properties()
    • cache_class::update_keywords()
    • cache_class::set_filters()
    • cache_class::set_content()
    • cache_class::load_json_content()
    • cache_class::refresh_content_after_edit()
    • cache_class::refresh_content_after_image_edit()
    • resort_class::retrieve_section_properties()

Refactor config files

  • _config/core_includes.php
    • fix paths to include files.
  • Refactor _config/scripts.php
    • add definition for SECTION_BASE_URI
    • *_SCRIPT > *_URI
    • ADMIN_HTTP_ROOT_URI."section_name/" > SECTION_BASE_URI."

Local AJAX scripts

  • Refactor include directives
  • (Optional) refactor to use ajax_page_class
  • Add any necessary scripts
    • listings.php

Local JavaScript libraries

  • Minify existing libraries
  • Wrap content-specific code in jQuery plugin code:
(function($) {

	var methods = {
		<methodName>: function() {
			return this.each(function() {
				/* custom code goes here... */
			});
		}
	};

	$.fn.<pluginName> = function( method ) {
	
		/* method calling logic */
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if ( typeof method === 'object' || !method ) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('Method ' + method + ' does not exist on jQuery.<pluginName>.');
		}

	};

})(jQuery);

Listings pages

Page setup & initialization

  • (Optional) Update comments to use Netbeans editor folds: //<editor-fold>
  • Refactor include directives
  • Refactor local CMS page URI definitions (*_SCRIPT > *_URI)
  • Add $breadcrumbs, $sTitle as global variables in the page’s initialize() function.
  • When calling $filters->format_query_string(), make sure not to append any values for P_FILTER.
  • Remove calls to urlencode() when formatting URLs for header links.
  • Use shared AJAX script for any “update cache” links.
  • Configure breadcrumbs.

Page framework

  • Refactor header and footer includes to use the path ADMIN_TEMPLATE_DIR."framework/".
  • Use appropriate PHP include rollup for CSS/JavaScript resources for the page, e.g.
include (ADMIN_TEMPLATE_DIR."framework/css/listings_css_and_scripts.php");
  • Use JQuery initialization
$(document).ready(function() {
    $('#listings-container').cms('bindListingsHandlers');
});
  • Make sure to include a container for error messages on the page:
<div id="error-container" class="error" style="display:none;"></div>
  • Wrap listings in a container that will allow JQuery script to locate them:
<div id="listings-container" class="listings">
    <? include (SECTION_BASE_DIR."_templates/content/[CONTENT-TYPE]_listings.php"); ?>
</div>
  • Remove any includes for popup containers.

Filters form

  • Update any lib routines to use the analogous routine from a utility class. E.g. db_utils_class::display_cached_options()
  • Form container has id “listings-filters” and class “listings-filters ui-corner-all”. Make sure to include JQuery UI stylesheet and that the local stylesheet contains the relevant definitions.
<div id="listings-filters" class="listings-filters ui-corner-all">
  • Form element has method “get”, id “filters_form”, and class “filters”.
<form action="<?=SECTION_CMS_URI ?>" method="get" id="filters_form">
  • Store “next” filter value in form.
<input type="hidden" name="<?=$filters->next->param ?>" value="<?=$filters->next->value ?>" />
  • Table element within form does not have any attributes.
<table>
  • Use <label> tags around all form inputs.
  • Any textbox inputs that collect date values should be assigned the “datepicker” class.
<td><label>name <input type="text" name="<?=$filters->name->param ?>" value="<?=$filters->name->value ?>" maxlength="50" /></label></td>
  • Submit button markup:
<input type="submit" class="filter-btn ui-corner-all" name="<?=P_FILTER ?>" value="filter" />

Listings content include file

  • (Optional) Add include directive for the section’s scripts config file for the benefit of the cache_class routines. Test if one of the script definitions is defined. If not, include the scripts config file.
if (!defined("[CONTENT-TYPE]_DETAILS_URI"))
{
    require_once (realpath(dirname(__FILE__).'/../../')."/_config/scripts.php");
}
  • Add try/catch for retrieving listings.
  • Remove include directives for any stand-alone routines that render pagination links.
  • Use shared include file to render pagination links.
include (COMMON_TEMPLATE_DIR."framework/navigation/listings_page_links.php");
<? include (COMMON_TEMPLATE_DIR."forms/ajax/status_cell.php"); ?>

Edit Pages

Page setup & initialization

  • The points under the listings pages setup & initialization apply here also.
  • Refactor stand-alone routines such as parse_numeric_input() to use analogous routines in shared utility classes, e.g validation_class::parse_numeric_input().
  • Set exception handler for the page that will load the page framework with the caught error displayed at the top:
set_exception_handler("exception_handler");

and

function exception_handler($ex)
{
    global $nav_menu, $breadcrumbs, $sTitle, $sParam, $input, $filters;
    $input->error_string = $ex->getMessage();
    include (SECTION_BASE_DIR."_templates/edit_[CONTENT-TYPE]_page.php");
}

Page framework

include (SECTION_BASE_DIR."_templates/edit_[CONTENT-TYPE]_page.php");

Gallery listings

  • If editing an existing record, load gallery listings with
$(document).ready(function() {
<? if ($input->id->value>0): ?>
	$('#pages-<?=$input->id->value?>').galleries('retrieveGallery', function() {
		$('#pages-<?=$input->id->value?>').galleries('bindImageOverlayHandlers');
	});
<? endif; ?>
});
  • $.galleries('retrieveGallery') in turn calls $.galleries('bindGalleryHandlers'). All AJAX button handlers should be fully active after the gallery listings are rendered.
  • The gallery images still need to be retrieved in PHP when the parent record is read even though they are displayed with this AJAX call. TODO: fix this so that the gallery properties are retrieved even when the gallery images are not retrieved.
$input->read(true); /* <<< true = retrieve gallery images */

TinyMCE WYSIWYG editors

  • JavaScript includes
<script type="text/javascript" src="/scripts/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript" src="/scripts/tinymce_config.js"></script>
  • The first one, the TinyMCE library, is in the common directories. The second one is local, and allows local configuration of the WYSIWYG editors.
  • Assign a textbox class="mce-editor" to have a TinyMCE WYSIWYG editor attached to it.
class content_type extends db_content_class
{
    function __construct()
    {
        parent::__construct();
        $this->description = new string_textarea_class("Description", self::DESCR_PARAM, false, "", 2000);
        $this->description->class = "mce-editor";
    }
}

Edit form

  • Form data to preserve in hidden inputs:
<input type="hidden" name="<?=P_REFERER?>" value="<?=((isset($_REQUEST[P_REFERER]))?($_REQUEST[P_REFERER]):(""))?>" />
		<input type="hidden" name="MAX_FILE_SIZE" value="10240000" />
		<input type="hidden" name="<?=P_ID?>" value="<?=$input->id->value?>" />
		<input type="hidden" name="<?=$input->id->param?>" value="<?=$input->id->value?>" />
		<input type="hidden" name="<?=$input->slot->param ?>" value="<?=$input->slot->value ?>" />
<? $filters->preserve_in_form(); ?>
  • Default form submission buttons and controls (including "next operation" radio options). Work off the contents of that include file for custom controls.
<? include (COMMON_TEMPLATE_DIR."forms/submit_container.php"); ?>

Main page logic

  • Remove checks on if($input->error()). Let the exception handler catch and handle these errors.
  • Put status messages in session variables:
$_SESSION[P_MESSAGE] = $sStatus;

Details Pages

Sample inline edit funcationality setup:

$(document).ready(function(){

	/* with album-based content, this loads the gallery of images on the page */
	$('#pages-<?=$input->id->value?>').galleries('retrieveGallery', function() {
		
		/* callback code executed after the gallery is fully loaded into the DOM */
		$('#pages-<?=$input->id->value?>')

		/* with a gallery of full-sized images this would load edit & delete buttons after clicking the images */
		.galleries('bindImageOverlayHandlers')

		/* with a listings-style of presentation this would enable inline editing of keywords within the gallery */
		.keywords('bindListingsHandlers');
	});

	/* adds edit and delete buttons to thumbnail image */
	/* this works for both album-based thumbnails and stand-alone images linked to the parent record */
	$('.image-upload-container').galleries('bindImageOverlayHandlers');

	/* enables inline editing of keywords */
	$('.metadata').keywords('bindListingsHandlers');
}