Tweaking web2project – overriding the Help button


When I moved to a new position a few months back, the team that I shifted to had just started using web2project for managing and tracking project activity. It comes with the ability to setup various custom fields and do all sorts of project manage-y things that I try to avoid and let the PMPs deal with.

But despite all of the features of web2project, my peers still wanted more than it offers out of the box. There are a number of ways in which it is lacking flexibility or configurable options that my teammates need. I needed to address their concerns while avoiding altering the PHP source code of the application as much as possible. Doing so will make it easier to deploy official upgrades to the application while retaining our customizations.

So I created a tweaks.js javascript file and simply modified ui.class.php script to output a script tag to include it on all pages. I added the output for this just after where it loads the base.js file. We are not yet running the latest version here, but it seems like the most recent code has moved things around. This change will need to be included in the CAppUI.class.php in the latest vesrion of web2project. Since I’m using jQuery as well, I also modified the PHP file to include that before my tweaks.js.

// Load the basic javascript used by all modules.
 echo '<script type="text/javascript" src="'.$base.'js/base.js"></script>';

// additionally load jquery
 echo '<script type="text/javascript" src="'.$base.'lib/jquery/jquery.js"></script>';

// load an additional tweak script file and numeric restrictor
 echo '<script type="text/javascript" src="'.$base.'js/tweaks.js"></script>';

The help button tweak

One other thing I did since coming on to this team is to setup an internal MediaWiki based wiki. We decided to write articles about all things useful for our team in this wiki. This will include the help information for using web2project. The tweak I created finds the Help button by the text and then replaces the functionality of the anchor tag that handles the click event when you click the button.

I also decided to make it easy to add additional help overrides for different pages throughout the site. The code implements some logic to walk a structure where you define alternative help URLs and a set of matching criteria. It takes this matching criteria and checks against the query string to see if an alternative should be used instead.

// Source:
function getUrlVars()
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
        hash = hashes[i].split('=');
        vars[hash[0]] = hash[1];
    return vars;

function setHelpUrl()
    // Default replace help URL
    var url = 'http://wikiserver/wiki/Web2project';
    // Possible substitution URLs based on matching items in the query string
    var substitutions =
            "url": 'http://wikiserver/wiki/Web2project_project_fields',
            "match": {"m": "projects", "a": true}
            "url": 'http://wikiserver/wiki/Web2project_projects',
            "match": {"m": ["projects", 'undefined']}
            "url": 'http://wikiserver/wiki/Web2project_users',
            "match": {"a": ["viewuser", "addedituser"]}
            "url": 'http://wikiserver/wiki/Web2project_tasks',
            "match": {"m": "tasks"}
    // See if we should use a substitution URL instead
    var vars = getUrlVars();
    $.each(substitutions, function(subIdx, sub){
        // Assume matched until we can't match something in the substitution description
        var matched = true;
        // Test all the properties of the substitution match set
        $.each(sub.match, function(queryParm, parmValue){
            // If it's an array then match any entry
            if(parmValue instanceof Array)
                // If the query parameter is not in the match array
                if($.inArray(vars[queryParm], parmValue) == -1)
                    matched = false;
                    return false;
            // Boolean means to test for the presence or absence of the parameter
            else if('boolean' == typeof parmValue)
                // Make sure the presence matches the match value (must-be-present == true, must-be-absent == false)
                if(parmValue == ('undefined' == typeof vars[queryParm]))
                    matched = false;
                    return false;
            // Otherwise, require a simple value match
                if(vars[queryParm] !== parmValue)
                    matched = false;
                    return false;
        // If still matched then use the URL from this subsitution item
            url = sub.url;
            return false;
    console.log('Overriding Help URL: ' + url);
    // Alter Help button to display help article
        // Find the help button by span containing the text Help
        // Remove the existing onclick handler from the parent <a> tag
        // Remove any other existing event handler
        // Bind a new click handler to redirect the help button to the wiki article
            return false;

And then the final thing is to just include a call to run the setHelpUrl function at the end of your tweaks.js file.

   // Override the Help button URL on all pages


After that, clicking on the Help button on any of the pages will cause it to route to a URL of your choosing. All without having to really modify the PHP code (other than that one thing to include the .js).

1 thought on “Tweaking web2project – overriding the Help button

  1. D. Keith Casey, Jr.

    Lead web2project developer here..

    First of all, welcome aboard. If you have any feedback, tips, or annoyances, please let me know. We treat the FAQ as a list of things that should be fixed and I’m always happy to add more.. well, not happy exactly, but along those lines. 😉

    Next, instead of using the hardcoded include, you may be able to include your tweaks.js via the addFooterJavascriptFile method on the AppUI class. Its purpose is to allow modules to include their own js files, but it should work as you plan. Plus that should be upgrade safe.

    Longer term, you should see a *huge* amount of refactoring in the pending v3.0 release. In terms of OO-purity, it’s pretty solid but the real goal behind that is to allow module developers to write way less code and just use core functionality *if* they follow the naming conventions. I’ve updated some of my modules and have deleted upwards of 20-40% of the code.

    Anyway, I’m happy to talk details. Feel free to drop me a note.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s