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

From Littledamien Wiki
Jump to navigation Jump to search
Line 295: Line 295:
</syntaxhighlight>
</syntaxhighlight>


Thumbnail upload control:
* [[Album_Image_Uploads#Album-based_content_using_a_gallery_image_as_a_thumbnail|Thumbnail upload controls]]
<syntaxhighlight lang="php">
<? include (COMMON_TEMPLATE_DIR."forms/images/image_upload_link_container.php"); ?>
</syntaxhighlight>


Default form submission buttons and controls. Work off the contents of that include file for custom controls.
Default form submission buttons and controls. Work off the contents of that include file for custom controls.

Revision as of 04:41, 27 March 2012

Configuration

Update content settings in site sections CMS

  • AJAX scripts
    • Listings: /_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 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 code in LITTLED namespace
if (typeof LITTLED.SectionLibName == "undefined") {
 
    LITTLED.SectionLibName = {
 
        /* section library code here */
    }
}
  • Use LITTLED.CMS JQuery binding routines as much as possible

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 (with as much code borrowed form cms.js as possible):
$(document).ready(LITTLED.CMS.bindListingsHandlers);
<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>
  • Filter label container has class “filterlabel”. Other containers are not assigned a CSS class.
  • Any textbox inputs that collect date values should be assigned the “datepicker” class.
  • 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("VIEW_[CONTENT-TYPE]_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"); ?>
  • Listings operations buttons are arranged with:
<td class="centered">
    <div class="listops"><!--
        --><a class="preview-btn" href="<?=$row->local_url?>" target="_blank" title="live content">live content</a><!--
        --><a class="trash-btn" href="javascript:void(0)" rel="nofollow" data-id="<?=$row->id?>" data-tid="<?=press_class::SECTION_ID?>" data-op="delete" title="delete">delete</a>
    </div>
</td>
  • Outside TD element has class “centered”.
  • Inner DIV element class “listops”.
  • Each button is created with an anchor tag.
    • href="javascript:void(0)" rel="nofollow" for buttons that have AJAX handlers.
    • The class attribute of the anchor determines its button style and its AJAX handler. (Buttons implemented with the JQuery UI library.)
    • Configure the AJAX handlers for listings operations with JQuery within the page’s $(document).ready(); handler.
    • “data-*” attributes of the anchor tags specify which records to operate on when calling AJAX handlers. Some examples:
      • data-id – record id
      • data-tid – record content type id
      • data-pid – record parent id
      • data-op – operation name
    • Each anchor tag has a title attribute which serves as a tooltip.
    • The innerhtml of the anchor tag is not displayed if the JQuery UI button is successfully loaded.

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

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');
}