EuroTcl2026: ADP - The NaviServer Web Anti-Framework

app/adp.adp

app/adp.adp:

<%#-*- mode:tcl -*-
ns_adp_include [ns_serverpath]/app/site.adp

set ::site::header {
    <nav><%::adp::nav%></nav>
    EuroTcl2026: <%=$app::name%> - <%=$app::tagline%>
    <h1><%=$::page::title%></h1>
}
set ::site::footer $::footer

set ::app::name ADP
set ::app::tagline "$::adp::title"

namespace eval adp {
    variable slides "list of slides"
    variable nav
    array set nav {
	parent {/ Home}
	home home
	up home
	prev home
	next home
    }
    variable index 0
    variable page home
}
set ::adp::slides {
    {index.adp " "}
    {toc.adp "Table of Contents"}
    {motivation.adp "The Goal: World Domination"}
    {overview.adp "What Expects You"}
    {structure.adp "Site Structure Concept"}
    {project_tree.adp "ADP Project Directory Tree"}
    {site_template.adp "The Site Template"}
    {loading.adp "Loading Logic of a Page"}
    {app_template.adp "The Application Template"}
    {static_page.adp "Example Static Page"}
    {static_nav.adp "Dynamic Nav Generation"}
    {static_recap.adp "Building Static Websites with ADP"}
    {edf.adp "Whats is EDF?"}
    {forms.adp "Now we need Forms"}
    {method_dispatcher.adp "The Method Dispatcher"}
    {uedf_index.adp "The EDF Main Page"}
    {uedf_add.adp "Add Outcome Action"}
    {app_loading.adp "Loading Logic of an Application"}
    {app_recap.adp "Application Programming"}
    {wapp_to.adp "From WAPP to ADP"}
    {edfn_to_uedf.adp "From edfn to µEDF"}
    {adp_recap.adp "Website Building with ADP"}
    {missing.adp "What Do I Miss?"}
    {thanks.adp "Thank You!"}
}

proc ::adp::link Page {lindex $Page 0}
proc ::adp::title Page {lindex $Page 1}

proc ::adp::nav {} {
    variable slides
    variable nav
    variable page
    variable index

    if {$index == -1} {
	set nav(prev) $nav(home)
	set nav(next) $nav(home)
    } else {
	set len [llength $slides]

	set p [expr {($index+$len-1) % $len}]
	set nav(prev) [lindex $slides $p]

	set n [expr {($index+1) % $len}]
	set nav(next) [lindex $slides $n]

	set ::page::title [title $page]
    }
    ns_adp_include [ns_serverpath]/tpl/adp/nav.adp
}

# Util
proc show_file path {
    set fd [open [ns_serverpath]/$path]
    set content [read $fd]
    close $fd
    return "<p><code>$path</code>:</p>
<pre>[ns_quotehtml $content]</pre>
"
}

proc adp::setup {} {
    variable nav
    variable slides
    variable index
    variable page
    
    set nav(home) [lindex $slides 0]
    set fn [lindex [split [ns_conn url] /] end]
    set index [lsearch -exact -index 0 $slides $fn]
    set page [expr {$index == -1 ? [list fn ""] : [lindex $slides $index]}]
    if {$page eq $nav(home)} {set nav(up) $nav(parent)} else {set nav(up) $nav(home)}

    set ::page::title [title $page]
}

# Calculate home and parent link
adp::setup

%>