General developer forum

Discussion: Best way of making JS/YUI widgets work with AJAX

Re: Discussion: Best way of making JS/YUI widgets work with AJAX

AJAX_SCRIPT has been there since Moodle 2.0 (unless I'm mistaken).

You might want to consider the following variation on your AJAX page:

ajax-page.php:

define('AJAX_SCRIPT', true);require_once('../../config.php');require_once('lib.php');myclass::view();
view.php:
require_once('../../config.php');require_once('lib.php');...echo $PAGE->header();myclass::view();echo$PAGE->footer();

lib.php:
class myclass {  public static function view() {     echo html_writer::tag('p', 'Hello world!');  }}

By routing most of your logic through a class in a library file, you eliminate many of the problems of multiple entry points, whilst retaining much of the code clarity that comes from them.

Average of ratings:Useful (2)
Re: Discussion: Best way of making JS/YUI widgets work with AJAX

Yes, absolutely, you can do it that way (and I did for quite some time). My experience with doing it that way, however, is that you're far better off trying to minimize your entry points to your apps. Separating the logic from the presentation helps, a bit, but what happens when you for instance try to make an AJAX call to a script supposed to output JSON when you're logged out? You do get breakage, and it's a bigger risk that edge cases causes breakage. That's the primary reason I'm not really fond of multiple entry points.

In the end it's a matter of preference though and both styles have their advantages as well as their disadvantages. But, shouldn't it be possible to do something like:

if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'xmlhttprequest' OR optional_param('isajax',0,PARAM_BOOL)) { define('AJAX_SCRIPT',true);}[...]if (isset(AJAX_SCRIPT)) { myclass::view();} else {$PAGE->header();    myclass::view();    \$PAGE->footer();}

Couldn't that combine both into one "best of both worlds"?

Average of ratings: -
Re: Discussion: Best way of making JS/YUI widgets work with AJAX

Hi Per,

I considered this too. Ignoring the fact that you wouldn't be able to use optional_param (because it's not available until config.php is defined, by which time it's too late to define AJAX_SCRIPT), this can work. I had a play with a proof-of-concept adding the code to lib/setup.php.

I felt at the time that it was still better in some respects to keep the entrypoints separate as this could lead to confusion later on. It's too easy to expect AJAX_SCRIPT to do all of the formatting too, and that may be the case, but chances are that it won't. Although some people will write their code as you suggest, there's a strong chance that people will do a lot of testing AJAX_SCRIPT all over the place in the same script, and will lead to nastier code to read.

Keeping the AJAX version in a separate script, appropriately namespaced, gives a clear indiciation as to purpose.

Perhaps it's worth re-opening the debate though... what are your main reasons for disliking multiple entrypoints?

Andrew

Average of ratings: -
Re: Discussion: Best way of making JS/YUI widgets work with AJAX

Hi Andrew!

Sorry for being a timesink, I'll try to keep this brief.

The main advantages and disadvantages to single- vs multi entry points the way I see it are these:

Single entrypoint

• Less risk of security holes and edge-case bugs
• Opens up for automatic testing and/or (X)HTML validation
• Everything collected in one place, easy to follow and overlook
• Almost impossible to break the "No JavaScript Requirements" rule
• All links can go to "real" places with little to no extra work, thus not breaking middle-clicks

• Not as efficient, intuitive or straightforward as multi-point
• Source code files can get large, complex and hard to overlook, especially with multiple paths
• Does require a bit of "PHP logic juggling", especially if you want automatic test benefits

Multiple entrypoints

• Clear purpose
• Simple structure - one-script-does-everything
• Fast and efficient - All unneccessary fat trimmed away