Lasso Soft Inc. > Home

[tags_load]

Linktags_load
AuthorJason Huck
CategoryCustom Tag
Version8.5.x
LicensePublic Domain
Posted09 Apr 2008
Updated10 Apr 2008
More by this author...

Description

This tag loads all the custom tag files in a given path into the global namespace so that they stay resident in memory. It's designed to work with files where each tag is in its own file with the same name as the tag (i.e., the tag 'foo_bar' would be in a file named 'foo_bar.inc'). You can specify what file extension should be loaded (the default is .inc), and a condition which will cause all tags to be reloaded. Errors are trapped and logged to Lasso's built-in error database. Also includes a [tags_unload] tag which can be used to unload tags in a similar manner. This article provides a more in-depth explanation.

Sample Usage

tags_load(
	'/path/to/mytags/',
	-ext='.lasso',
	-refresh=(var_defined('reloadmytags') && $reloadmytags === true)
);

Source Code

Click the "Download" button below to retrieve a copy of this tag, including the complete documentation and sample usage shown on this page. Place the downloaded ".inc" file in your LassoStartup folder, restart Lasso, and you can begin using this tag immediately.

define_tag(
	'load',
	-namespace='tags_',
	-req='path', -type='string',
	-opt='ext', -type='string',
	-opt='refresh', -type='boolean',
	-priority='replace',
	-description='Loads all files in the given path into the global namespace.'
);
	// assumes custom tags/types are kept in separate files,
	// each named with the name of the tag and the provided
	// extension, i.e., a tag named foo_bar would be in a 
	// file named 'foo_bar.inc'.
	
	// for files that contain multiple related tags/types,
	// use the pattern _library. and include
	// a simple tag which returns 'Loaded' for that name, i.e.
	// the Foo tag library would be called 'foo_library.inc',
	// and would contain a tag at the end like so:
	
	// define_tag('foo_library');
	// 	return('Loaded');
	// /define_tag;

	// set defaults
	// ext is the file extension to load
	// refresh is whether or not to refresh all files/tags
	!local_defined('ext') ? local('ext') = '.inc';
	!local_defined('refresh') ? local('refresh') = false;

	// initialize vars
	// tagsLoaded stores the number of tags loaded
	// ctags is an array of files to load
	// to remove is an array of files to remove from ctags
	// tagmapname is a unique name to use in globals
	local(
		'tagsLoaded' = 0,
		'ctags' = array,
		'toRemove' = array,
		'tagmapname' = string_replaceregexp(
			server_name + #path,
			-find='^[a-zA-Z0-9]',
			-replace='',
			-ignorecase
		)
	);

	// create some globals if they do not already exist
	// one to control thread locking (LP8.1 compatible method)
	// and one to store a count of successfully loaded files/tags
	!global_defined(#tagmapname + '_lock') ? global(#tagmapname + '_lock') = thread_lock;	
	local('tagloader_threadlock') = @global(#tagmapname + '_lock');
	
	!global_defined(#tagmapname + '_count') ? global(#tagmapname + '_count') = 0;	
	local('tagloader_count') = @global(#tagmapname + '_count');
	
	if(#refresh && #tagloader_threadlock->lock);
		#tagloader_count = 0;	
		#tagloader_threadlock->unlock;
	/if;

	// LP 8.5 and higher only could use this instead:
	// thread_atomic(#tagloader_count);
	// 	!#tagloader_count || #refresh ? #tagloader_count = 0;
	// /thread_atomic;

	// get list of tags		
	#path->endswith('/') ? #ctags = file_listdirectory(#path) | #ctags->insert(#path);

	// remove files that start with a period (LP8.1 compatible method)		
	iterate(#ctags, local('i'));
		#i->beginswith('.') || !#i->endswith(#ext) ? #toRemove->insert(#i);
	/iterate;
	
	#ctags->sort;
	#toRemove->sort;
	#ctags = #ctags->difference(#toRemove);

	// LP 8.5 and higher only could use this instead:
	// #ctags->removeall(match_regexp('^\\..*'));
	
	// compare to current size, only run if different
	if(#ctags->size != #tagloader_count || #refresh);	
		// loop through list
		iterate(#ctags, local('thisTag'));
			// pop off extension
			local('thisTagName' = #thisTag);
			#thisTagName->removetrailing(#ext);

			// if not already defined (or refreshing)
			if(!lasso_tagexists(#thisTagName) || #refresh);
				// use global namespace so tags stay resident in memory
				namespace_using(namespace_global);
					protect;
						#ctags->size > 1 ? library(#path + #thisTag) | library(#path);
						#tagsLoaded += 1;
						
						// log any errors
						handle_error;
							log_critical('[Tagloader] Error loading [' + #thisTagName + ']: ' + error_msg);
						/handle_error;
					/protect;
				/namespace_using;
			else;
				// account for tags that already exist
				#tagsLoaded += 1;
			/if;
		/iterate;

		// update global	
		// LP 8.1 compatible method
		if(#tagloader_threadlock->lock);
			#tagloader_count = #tagsLoaded;	
			#tagloader_threadlock->unlock;
		/if;
		
		// LP 8.5 and higher only
		// thread_atomic(#tagloader_count);
		// 	#tagloader_count = #tagsLoaded;
		// /thread_atomic;	

		// log results
		log_warning('[Tagloader] ' + #tagsLoaded + ' of ' + #ctags->size + ' tags loaded successfully.');
	/if;		
/define_tag;



define_tag(
	'unload',
	-namespace='tags_',
	-req='path',
	-priority='replace',
	-description='Unloads all tags in the given path from memory.'
);
	if(file_isdirectory(#path));
		local('files') = file_listdirectory(#path);		
	else;
		local('files') = array(#path);
	/if;
	
	iterate(#files, local('i'));
		if(!#i->beginswith('.') && !#i->endswith('/'));
			local('ext') = #i->split('.')->last;
			local('tagname') = string(#i)->removetrailing('.' + #ext)&;
			namespace_unload(#tagname);
		/if;
	/iterate;
/define_tag;

Comments

15 Mar 2011, Nikolaj de Fine Licht

Extension independent

I have a small suggestion to make the tag independent from the extension(s) of the files to load (if this is desireable - for me it is):
Change these lines:
local('thisTagName' = #thisTag);
#thisTagName->removetrailing(#ext);
to:
local('thisTagName' = #thisTag->(split('.')->first));
and remove completely the #ext param from the tag

08 Jan 2009, Jason Huck

Re: Loading tags_load

It is a bit of a chicken-and-egg scenario. You can either drop it into LassoStartup, just reload it on every request, or do a little bootstrap like so:

if(!lasso_tagexists('tags_load')); namespace_using(namespace_global); library('tags_load.inc'); /namespace_using; /if;

12 Dec 2008, Steve Piercy

Loading tags_load

How do you recommend loading tags_load itself?

Please log in to comment

Subscribe to the LassoTalk mail list

LassoSoft Inc. > Home

 

 

©LassoSoft Inc 2015 | Web Development by Treefrog Inc | PrivacyLegal terms and Shipping | Contact LassoSoft