In the Key Concepts, we introduced the fundamentals of WaSQL -- a database-driven framework that stores all your page logic in the database. Now, let's level up with advanced patterns for AJAX navigation, dynamic forms, and multi-view page flows -- the same techniques used in production WaSQL sites today.
WaSQL integrates seamlessly with WACSS, its front-end JavaScript/CSS framework. With WACSS, AJAX navigation is built in -- no extra JS setup required.
<!--
data-div defines what DOM element to display the content returned by AJAX
data-nav defines the AJAX endpoint to call to get the content
-->
<a href="#" data-div="content" data-nav="/t/1/people/list" onclick="return wacss.nav(this);">
View People
</a>
<div id="content"><!-- Content loads here --></div>
The data-div attribute specifies where the response should load, while data-nav defines which page/action to fetch. The backend can respond with any WaSQL view.
WaSQL's addEditDBForm() function handles full create and update operations automatically -- including validation, saving, and rendering.
function pageAddEdit($id = 0) {
$opts = [
'-table' => 'people',
'-fields' => getView('form_fields'),
'name_options' => ['inputtype' => 'text', 'required' => 1],
'age_options' => ['inputtype' => 'number', 'required' => 1]
];
//if $id then turn form into edit mode
if($id > 0) {
$opts['_id'] = $id;
}
return addEditDBForm($opts);
}
Your view defines the layout of those fields:
<view:form_fields>
<div class="field">
<label class="label">Name</label>[name]
</div>
<div class="field">
<label class="label">Age</label>[age]
</div>
</view:form_fields>
This eliminates repetitive form markup and ensures consistent validation.
$PASSTHRURouting is handled in the controller via the $PASSTHRU array. This array is populated by the URL. If your URL looks like https://www.mysite.com/contact/process/next then contact would be your _page record and $PASSTHRU would be an array ('addedit','next'). Here is an example of using $PASSTHRU:
global $PASSTHRU;
switch(strtolower($PASSTHRU[0])){
case 'addedit':
$id = $PASSTHRU[1] ?? 0;
setView('addedit');
break;
case 'list':
$records = getDBRecords(['-table' => 'people', '-order' => 'created_date DESC']);
setView('list');
break;
case 'delete':
delDBRecordById('people', $PASSTHRU[1]);
setView('list');
break;
}
Every action lives in the same page record and is simply defined in the URL -- no external files or routers required.
Instead of using if/endif, WaSQL uses view-based conditionals for clean templating:
>
<view:admin_panel>
<div class="notification is-info">
Welcome, <?=encodeHtml($USER['name']);?> (Admin)
</div>
</view:admin_panel>
<?=renderViewIf(isAdmin(), 'admin_panel', $rec,'rec');?
<view:person>
<div class="person">
<div class="w_bigger w_bold"><?=$rec['name'];?></div>
<div><?=$rec['address'];?></div>
<div><a href="mailto:<?=$rec['email'];?>"><?=$rec['email'];?></a></div>
</div>
</view:person>
<?=renderEach('person',$people,'rec');?>
This keeps your HTML valid and maintainable while staying within WaSQL's sandboxed view system.
WaSQL provides built-in user management via the $USER global and helper functions like isUser() and isAdmin().
global $USER;
if(!isUser()) {
setView('login_required');
return;
}
You can use $USER['role'] for role-based views and navigation.
WaSQL isn't limited to PHP. It supports Python, Node.js, Ruby, Perl, Lua, and Bash in the same app. Each language receives the same $_REQUEST, $_SESSION, and $_SERVER context.
This makes WaSQL uniquely flexible -- you can mix languages based on performance or library needs.
encodeHtml() for user input. global $PASSTHRU; for URL routing. $_POST; use $_REQUEST. renderViewIf() instead of PHP if. WaSQL is more than a framework -- it's a full-stack database-native web environment. Once you master these advanced patterns, you can rapidly build secure, dynamic web apps that deploy as easily as exporting a single SQL file. Check it out at WaSQL.com or on GitHub