Sublime Text Per Type File Preferences
0I’ve been using Sublime Text for a while now on Windows and I sometimes forget to change the file type preferences to the following to ensure indentation (e.g. important for Python!) and to remove trailing white space.
My basic options for Python (Python.sublime-options) and Javascript.
# Settings in here override the defaults in: # Packages/Default/Options/Default File Type.sublime-options # See there for the available options and their description. tabSize 4 translateTabsToSpaces true trimTrailingWhiteSpaceOnSave true wordWrap false
Zend Framework JSON based REST/RPC Controller Code Snippet
2It’s a start towards a standard controller snippet I can re-use, will evolve over time.
<?php
class <ModuleName>_<ControllerName>Controller extends Zend_Controller_Action {
public function <ActionName>Action() {
// Making sure the date gets refreshed.
$this->_response->setHeader('Cache-Control', 'no-cache, must-revalidate');
$this->_response->setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT');
/*
Already performed by sendJson()
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
*/
$this->_helper->json->sendJson(<DATA>);
}
public function init() { }
public function indexAction() {}
public function getAction() {}
public function postAction() {}
public function putAction() {}
public function deleteAction() {}
}
// Optional base class to inherit from, adds authentication and/or context switching.
class Default_Service_BaseRestController extends Zend_Controller_Action {
public $requireAuthentication = false;
public function init() {
/* @var $contextSwitch Zend_Controller_Action_Helper_ContextSwitch */
$contextSwitch = $this->_helper->getHelper ( 'contextSwitch' );
/*
$contextSwitch->addContext('csv', array());
$contextSwitch->addActionContext ( 'index', 'csv' )->initContext ();
$contextSwitch->addActionContext ( 'index', 'xml' )->initContext ();
*/
$contextSwitch->addActionContext ( 'index', 'json' )
->setAutoJsonSerialization ( false )->initContext ();
if ($this->requireAuthentication) {
$this->authorize();
}
}
// Just a helper ...
public static function isAuthenticated() {
$auth = Zend_Auth::getInstance();
return $auth->hasIdentity();
}
public function authorize() {
$auth = Zend_Auth::getInstance();
if (!$auth->hasIdentity()) {
/* Not authenticated, could additionally also check for authorization ...
$this->_helper->json->sendJson('error');
exit;
*/
}
}
}
Minify and Merge JavaScript Project Files in Aptana (2.0) with Ant
1Based on:
Minify JavaScript and CSS files in IDE
but added merging the files.
<?xml version="1.0" encoding="UTF-8"?>
<project name="YUICompression" basedir=".">
<target name="default" description="Minifiy a set of files">
<taskdef name="yuicompress" classname="com.yahoo.platform.yui.compressor.YUICompressTask">
<classpath>
<pathelement path="${basedir}/lib/yuicompressor-2.4.2.jar"/>
<pathelement path="${basedir}/lib/yuiant.jar"/>
</classpath>
</taskdef>
<delete>
<fileset dir="${basedir}/output" includes="*.js"/>
</delete>
<concat destfile="${basedir}/output/javascript.js" append="true">
<fileset dir="${basedir}/src" includes="*.js"/>
</concat>
<yuicompress linebreak="16000" warn="false" munge="no" preserveallsemicolons="true" outputfolder="${basedir}/minified">
<fileset dir="${basedir}/output">
<include name="**/*.js"/>
</fileset>
</yuicompress>
</target>
</project>

Woltlab Burning Board Sequence Diagrams …
0Just some additional documentation, also a little experiment of using Evolus Pencil (free Firefox Add-on) for light weight modeling.
Forms
![]() |
| From Blog |
Installing and Using Topia for Term Extraction, My First Python Code :)
0Installed Python 27
http://www.python.org/download/
Installed the required Setuptools to install Topia
http://pypi.python.org/pypi/setuptools
Executed the build and install option on the setup and was ready to hit the Topia road!
The result:
#buildkeywords.py
import json
import sys
from topia.termextract import tag
from topia.termextract import extract
#set path=%path%;c:python27
#http://pypi.python.org/pypi/topia.termextract
#http://www.peterbe.com/plog/uniqifiers-benchmark
def uniqify(seq, idFun=None):
# order preserving
if idFun is None:
def idFun(x): return x
seen = {}
result = []
for item in seq:
marker = idFun(item)
# in old Python versions:
# if seen.has_key(marker)
# but in new ones:
if marker in seen: continue
seen[marker] = 1
result.append(item)
return result
def build(language='english'):
# initialize the tagger with the required language
tagger = tag.Tagger(language)
tagger.initialize()
# create the extractor with the tagger
extractor = extract.TermExtractor(tagger=tagger)
# invoke tagging the text
extractor.tagger(sys.argv[1])
# extract all the terms, even the &quot;weak&quot; ones
extractor.filter = extract.DefaultFilter(singleStrengthMinOccur=1)
# extract
return extractor(sys.argv[1])
resultList = []
# get a results
result = build('english')
# or result = build('dutch')
for r in result:
# discard the weights for now, not using them at this point and defaulting to lowercase keywords/tags
resultList.append(r[0].lower())
# dump to JSON output
print json.dumps(sorted(uniqify(resultList)))
Conclusion
I LIKE PYTHON :)
Merging Woltlab Burning Board/Woltlab Community Framework with Zend Framework
0The creation of a monster …
Use the following index.php to merge WCF/WBB with Zend Framework. Now why would you want that?!?!
Well, personally I wanted to create Zend Framework REST services of Woltlab Burning Board features and also make use of various ZF components in combination with WBB data.
I also ran into some issues:
- Somehow the SetEnv in my .htaccess was not accepted (had to hard code the environment setting into my index.php)
- Zend_Filter_PregReplace seemed to fail on the unicode support check on line 75, hard coded it to false unfortunately
Enjoy this madness:
<?php
// xdebug_start_trace( 'C:\Zend\Zend Server\ZendServer\logs\xdebugtrace',1 );
// ------------------------------------ WOLTLAB INIT --------------------------------------------
$path = realpath(dirname(APPLICATION_PATH).'/../board/');
if (!defined('WBB_DIR')) define('WBB_DIR', $path.'/');
if (!defined('RELATIVE_WBB_DIR')) define('RELATIVE_WBB_DIR', WBB_DIR);
$wcfpath = realpath(dirname(APPLICATION_PATH).'/../wcf/');
if (!defined('WCF_DIR')) define('WCF_DIR', $wcfpath.'/');
if (!defined('RELATIVE_WCF_DIR')) define('RELATIVE_WCF_DIR', $wcfpath.'/');
// include WBB
require_once(WBB_DIR.'/config.inc.php');
// include WCF
require_once(RELATIVE_WCF_DIR.'/global.php');
$packageDirs = array();
if (!count($packageDirs)) $packageDirs[] = WBB_DIR;
$packageDirs[] = WCF_DIR;
// starting wbb core
require_once(WBB_DIR.'lib/system/WBBCore.class.php');
new WBBCore();
// Woltlab WCF autoloading is required on top of the ZF autoloading
function wcf_autoload($className) {
// search util class in wcf dir
if (file_exists(WCF_DIR . 'lib/util/' . $className . '.class.php')) {
// include file
require_once(WCF_DIR . 'lib/util/' . $className . '.class.php');
return;
}
// search exception class in wcf dir
if (file_exists(WCF_DIR . 'lib/system/exception/' . $className . '.class.php')) {
// include file
require_once(WCF_DIR . 'lib/system/exception/' . $className . '.class.php');
return;
}
// search util or exception class in application dirs
global $packageDirs;
if (isset($packageDirs) && is_array($packageDirs)) {
foreach ($packageDirs as $packageDir) {
if (file_exists($packageDir . 'lib/util/' . $className . '.class.php')) {
// include file
require_once($packageDir . 'lib/util/' . $className . '.class.php');
return;
}
if (file_exists($packageDir . 'lib/system/exception/' . $className . '.class.php')) {
// include file
require_once($packageDir . 'lib/system/exception/' . $className . '.class.php');
return;
}
}
}
}
spl_autoload_register('wcf_autoload');
// ------------------------------------ ZEND FRAMEWORK INIT --------------------------------------------
ini_set('mbstring.internal_encoding','UTF-8');
ini_set('mbstring.http_input','UTF-8');
ini_set('mbstring.http_output','UTF-8');
// Define path to application directory
defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/application'));
// Define application environment
// WARNING!! SetEnv did not seems to work, maybe not allowed to perform it ...
defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'development'));
if ('development' === APPLICATION_ENV) {
error_reporting(E_ALL);
ini_set("display_errors", 1);
}
// Ensure library/ is on include_path
// Library relative to the current path!
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/library'), get_include_path(),
)));
/** Zend_Application */
require_once 'Zend/Application.php';
// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
->run();
// xdebug_stop_trace();
Deploy the bare minimum required Zend Framework scripts in your application library.
2If you want to deploy your application with the bare minimum required Zend Framework scripts, attach the following PHP error handling function and run your application through all it’s features until it no longer complains about missing required scripts :)
Goal: minimize the deployment package!
Had to copy these additional directories (it tried to load through it via plug-in logic instead of throwing a require_once error) :
- Zend\Application\Resource
- Zend\Filter
- Zend\Controller\Action\Helper
That’s what it needed for a plain index controller and a rest index controller with json support (module), 171 Files and 33 Folders of the Zend Library.
Could probably scale it down more if we cherry pick from the directories mentioned above.
function error_handler($errno, $errstr, $errfile, $errline) {
// ------------------------------ START CONFIGURATION --------------------------------------
$sourcedir = 'X:\source\library';
$destination = realpath(APPLICATION_PATH . '\library');
// ------------------------------ END CONFIGURATION ----------------------------------------
// echo $errstr;
// echo "/Zend[a-zA-Z0-9.\\\\\/]*/i"."<br/>";
preg_match("/Zend[a-zA-Z0-9.\\\\\/]*/i", $errstr, $matches);
echo "<br/>missing script matches<br/>";
var_dump($matches);
if (isset($matches[0])) {
echo "copy file<br/>";
/* Examples:
Zend/Loader/PluginLoader/Interface.php
Zend\Application\Bootstrap\Exception.php
*/
// echo '/Zend[a-zA-Z0-9\\\\\/]*[\\\\\/]{1}/i'."<br/>";
preg_match('/Zend[a-zA-Z0-9\\\\\/]*[\\\\\/]{1}/i', $matches[0], $matchpath);
echo "path matches<br/>";
var_dump($matchpath);
echo 'path: '.$matchpath[0]."<br/>";
if (isset($matchpath[0])) {
echo "creating: ".$destination.'\\'.$matchpath[0]."<br/>";
// create a missing path
mkdir ($destination.'\\'.$matchpath[0] ,0777, true);
}
// copy the file
copy ( $sourcedir.'\\'.$matches[0] , $destination.'\\'.$matches[0] );
}
}
set_error_handler ( 'error_handler', E_ALL );
Custom jQuery Validation Rules
2Just a little example of custom validation rules. It highlights some of the features like parameter passing, custom messages and common pitfalls (and as a bonus exact date parsing with datejs). I don’t do this daily so it’s also a code snippet for myself ;-)
Common mistake:
- Use the name attribute on your input elements, the validator depends on it.
- Initiate the validator before adding rules :)
- check if the element has been tagged optional, hence the rule does not need to be enforced if it is.
- pass element dependencies as parameters instead of hard coding them, i.e. makes the rule reusable.
( – check if the date parsing was a success )
$(function(){
$.validator.addMethod("after", function(value, element, elementid) {
var start = Date.parseExact ( $(elementid).val(), 'd-M-yyyy' );
var end = Date.parseExact ( $(element).val(), 'd-M-yyyy' );
/*
* There seems to be a bug in the next check,
* it never returns true if a value has been given although the required rule has been set to false.
* Using jQuery validation plug-in 1.7
* Test snippet:
var strange = $.validator.methods.required.call(this, $.trim(element.value), element);
console.debug(strange);
console.debug(this.optional(element));
*/
if (this.optional(element)) { return true; }
// Parsing failed.
if (!start || !end) { return false; }
var after = start <= end;
return after;
}, 'Incorrect date specified'
);
$('#foo').validate();
$('#end').rules("add", {
// required: false,
after: '#start',
messages: {'after':'End date must be after the start date.'}
});
$('#validate').click(function(){
$('#foo').valid();
});
});
References:
Date Parsing
http://www.datejs.com/
http://code.google.com/p/datejs/wiki/APIDocumentation
http://code.google.com/p/datejs/wiki/FormatSpecifiers
Validation
http://bassistance.de/jquery-plugins/jquery-plugin-validation/
http://docs.jquery.com/Plugins/Validation
