BoxLang 🚀 A New JVM Dynamic Language Learn More...

PresideCMS Extension: Launcher

v1.0.9+0000024 Preside Extensions

Preside admin Launcher

The Preside admin launcher extension brings "quick find/launch" functionality to the Preside admin.

Installation

box install preside-ext-launcher

Configuration

The launcher will work as is out of the box if you have a standard Preside admin layout. However, there are some configuration options that you should be aware of to help you tweak the functionality to your requirements.

In Config.cfc

// default datasources list:
// tweak this to add your own datasources
// and/or change the priority order of datasources
settings.launcher.datasources = [ "thispage", "recent", "pages", "objectdata", "navigation"];

// default objects for the objectData + recentObjectData datasources
// you should configure this array with key objects that
// should be quick findable in your application.
settings.launcher.objectDatasources = [ "crm_contact", "crm_organisation" ]; // empty by default

// whether or not to auto inject the launcher
// into the admin layout header. If you are not
// using the default admin layout, you may need to set this
// to false and render the launcher yourself in your header
settings.launcher.autoInjectInHeader = true;

// maximum number of items to store in the recently
// visited records datasource (stores in the database)
settings.launcher.maxRecentlyVisitedItems = 20;

Custom datasources

You can add your own custom datasources by adding them to the settings.launcher.datasources array. e.g.

settings.launcher.datasources.append( "mycustomdatasource" )

Each datasource must then implement:

i18n entry

Two entries in /i18n/launcher.properties, one for the title and one for the iconClass. e.g.

datasource.mycustomdatasource.title=My datasource
datasource.mycustomdatasource.iconClass=fa-database purple

Config handler

Create a handler with a config method at /handlers/admin/launcher/datasource/{datasourcename}.cfc. The config method should return a configuration struct for the datasource (see reference below).

You may also optionally implement recordRecentlyVisited() and renderRecentlyVisitedItem() actions to allow visits to pages in your datasource to appear in the 'Recently visited' menu. For example:

component {

	property name="launcherService" inject="launcherService";

	private array function config( event, rc, prc ) {
		return launcherService.getObjectDataDatasources();
	}

	/**
	 * Runs at the end of a request and should return a
	 * struct of data to identify the recently visited page
	 * (empty struct if current page not relevent to your datasource)
	 * Logic to determine this is up to you. Receives no arguments.
	 */
	private struct function recordRecentlyVisited( event, rc, prc ) {
		if ( Len( Trim( prc.objectName ?: "" ) ) && Len( Trim( prc.recordId ?: "" ) ) ) {
			return {
				  objectName = prc.objectName
				, recordId   = prc.recordId
			}
		}

		return {};
	}

	/**
	 * Must return a launcher item struct representing the saved
	 * recently visited item. Receives the data you returned in
	 * recordRecentlyVisited() as arguments.
	 * Return {} to have the item ignored.
	 */
	private struct function renderRecentlyVisitedItem( event, rc, prc, objectName="", recordId="" ) {
		if ( Len( Trim( arguments.recordId ) ) && Len( Trim( arguments.objectName ) ) ) {
			return {
				  id          = "recent-" & arguments.recordId
				, icon        = translateResource( uri="preside-objects.#arguments.objectName#:iconClass", defaultValue="fa-database" )
				, text        = renderLabel( arguments.objectName, arguments.recordId )
				, description = ""
				, url         = event.buildAdminLink( objectName=arguments.objectName, recordId=arguments.recordId )
			};
		}

		return {};
	}
}

Datasource config reference

Each datasource config is defined as a struct with the following keys:

  • local (optional, required if no remoteURL): an array of items (see item reference below) for the launcher
  • defaultSuggestions (optional): an array of items that will be shown as soon as the launcher is focused
  • remoteUrl (optional, required if no local): URL that will return a json array of items given a search query. Should contain a %QUERY token that will be replaced with the currently active search term
  • prefetchUrl (optional): URL that will return a json array of items to prepopulate search for the datasource
  • javascriptSrc (optional): boolean. If true, then a javascript event will be triggered on the $( "#preside-launcher-input" ) input matching the datasource name that allows you to configure the datasource in javascript. See javascript datasource below

Item reference

Each item in a datasource is represented as a struct with the following items:

  • id: unique ID of the item
  • text: searchable and displayed text
  • description: optional description of the item
  • icon: font-awesome icon class to display with the item
  • url: URL to browse to when item is selected

Javascript datasources

Javascript based datasources can be created by setting a javascriptSrc=true configuration in your datasource config handler and providing javascript that listens for the jQuery event prepare{lower-cased-datasource-name}Datasource. The event will be passed three arguments:

  1. the javascript event object
  2. an empty 'helper' object. You are expected to set a 'bh' key in here with a configured BloodHound instance
  3. a 'config' object containing the launcher datasource from Preside

Example:

( function( $ ){
	( "#preside-launcher-input" ).on( "preparethispageDatasource", function( ev, helper, config ){
		var items = [{text:"Oranges", ...}, {text:"Apples", ...}]; // should have same keys as item definition, above

		helper.bh = new Bloodhound( $.extend( {}, {
			  datumTokenizer : function(d) { return Bloodhound.tokenizers.whitespace( d.text); }
			, queryTokenizer: Bloodhound.tokenizers.whitespace
			, local : items
		}, config.bloodhoundOptions ) );

		config.typeaheadOptions.minLength = 0;
		config.typeaheadOptions.source = function(q, sync) {
			if ( q === '' ) {
				sync( items );
			} else {
				helper.bh.ttAdapter()(q, sync);
			}
		}
	} );
} );

ObjectData datasource

The ObjectData datasource allows you to search preside objects (configured in settings.launcher.objectDatasources) within your application. By default, the launcher will search the labelfield of the given object. If you want a specific set of fields to be used for searching you can add a launcherSearchFields attribute to your object cfc.

/**
 * @launcherSearchFields   productId,label
 */
component {
	property name="productId" ype="string" dbtype="varchar" maxlength=40 uniqueIndexes="product_identifers";
    // .. etc.
}

Changelog

v1.0.9

  • Fix issues with duplicate entry errors recording "recently visited" entries for launcher

v1.0.8

  • #10 compat issue: siteTreeService not available in admin only apps

v1.0.7

  • #9 Prevent duplicate entry attempts for 'recently visited' data

v1.0.6

  • #8 Cascade delete 'recently visisted' records when deleting admin users

v1.0.5

  • Quick find not working properly for multi-word search terms
  • Build using GitHub Actions

v1.0.4

  • Fix umlaut characters in the German translations

v1.0.3

  • Only do launcher operations for admin requests.

v1.0.2

  • Cache navigation items that otherwise require expensive permissioning checks, etc.

v1.0.1

  • Added German translations for the UI

v1.0.0

  • Public release

v0.2.11

  • Tidy up build files (remove redundant test parts)
  • Update install instructions in README

v0.2.10

  • Fix issue where prefetch was very slow due to no limit on the number of records fetched

v0.2.9

  • Added changelog :)

v0.2.8

  • Move to MIS publishing method

v0.2.7

  • Try/catch rendering of links to remembered objects + fix i18n for system config recently visited items. Try catch necessary because either DB entries could be falsified OR become out of date where application objects no longer exist, etc.

v0.2.6

  • Add ability to configure search fields per object for the object datasource search (thanks to Sacha)

v0.2.5

  • Fix issue with getting 'recently visited' entries for objects that don't render for launcher, etc.

v0.2.4

  • Add a feature flag for launcher extension installation detection
  • Always initialize launcher context data pre layout, regardless of autoinjection

v0.2.3

  • Ensure we don't add duplicate items to the launcher + remove bad shortcut descriptions

v0.2.2

  • Fix issue with missing 'args'

v0.2.1

  • Fix bad config reference

v0.2.0

  • Add some documentation
  • Add interception point to be able to modify core datasource configs
  • Add a 'navigation' datasource and merge with datamanager + system config
  • Always have the 'this page' datasource say 'This page' rather than change with the page title
  • Add tab navigation to 'this page' datasource
  • Add concept of javascript generated datasources + implement datasource that finds action links buttons on pages

v0.1.5

  • Document the recently visited features of datasources
  • Harden the recently visited system so that we can have abritrary recording and rendering of recently visited items per datasource (rather than only catering for object data)

v0.1.4

  • Ensure that box does not overlap other top nav items when not focused

v0.1.3

  • Add site tree pages to datasource

v0.1.2

  • Tweak positioning of autosuggest search box
  • Add a more in-depth hint when activating search
  • Fix js errors when local datasources are empty (e.g. recently viewed)

v0.1.1

  • Add README

v0.1.0

  • First alpha release

$ box install preside-ext-launcher

No collaborators yet.
  • {{ getFullDate("2019-10-21T09:47:33Z") }}
  • {{ getFullDate("2024-09-23T10:34:47Z") }}
  • 2,806
  • 90,132