Wapp

Check-in [47e58e7d2b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Restructure and comment the shoplist.tcl example to make it easier for people to read and understand.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 47e58e7d2b87d5bcbe714308e6c59107cca7a068fd2c370060ecb1b1ad28cf49
User & Date: drh 2018-02-01 17:28:45.989
Context
2018-02-01
18:15
Work on the example scripts so that they all work with the new default CSP. Add comments to all scripts. Provide a demonstration database for shoplist.tcl. Add a README.md to the examples folder. (check-in: f28e72c49e user: drh tags: trunk)
17:28
Restructure and comment the shoplist.tcl example to make it easier for people to read and understand. (check-in: 47e58e7d2b user: drh tags: trunk)
13:31
More shoplist.tcl enhancements. (check-in: 2169d31440 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to examples/shoplist.tcl.
14
15
16
17
18
19
20


































































21
22
23
24
25
26
27
#    (2) Edit this script to put the full pathname of the database as the
#        DBFILE variable
#
#    (3) Make this script a CGI on your server.  Or run it in some other
#        way that Wapp supports.
#
set DBFILE /shoppinglist.db  ;# Change to name of the database.


































































proc wapp-default {} {
  if {[shopping-list-header]} return
  set base [wapp-param SCRIPT_NAME]
  if {[wapp-param-exists del]} {
    set id [expr {[wapp-param del]+0}]
    db eval {
       INSERT INTO done(id,x) SELECT id, x FROM shoplist WHERE id=$id;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#    (2) Edit this script to put the full pathname of the database as the
#        DBFILE variable
#
#    (3) Make this script a CGI on your server.  Or run it in some other
#        way that Wapp supports.
#
set DBFILE /shoppinglist.db  ;# Change to name of the database.

# Every page should call this routine first, and abort if this
# routine returns non-zero.
#
# This routine outputs the page header and opens the database file.
# It checks the login cookie.  If the user is not logged in, this routine
# paints the login screen and returns 1 (causing the caller page to abort).
# 
proc shopping-list-header {} {
  wapp-trim {
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link href="%url([wapp-param SCRIPT_NAME]/style.css)" rel="stylesheet">
    <title>Shopping List</title>
    </head><body>
    <h1>Shopping List</h1>
  }
  sqlite3 db $::DBFILE
  db timeout 1000
  db eval BEGIN
  if {[wapp-param-exists logout]} {
    wapp-clear-cookie shopping-list-login
    set pswd {}
  } else {
    set pswd [wapp-param pswd [wapp-param shopping-list-login]]
  }
  if {$pswd=="" 
    || ![db exists {SELECT 1 FROM config WHERE name='password' AND value=$pswd}]
  } {
    wapp-trim {
      <p><form method="POST" action="%url([wapp-param SELF_URL])">
      Password: <input type="password" name="pswd" width=12>
      <input type="submit" value="Login"></form></p>
    }
    db eval COMMIT
    db close
    return 1
  }
  if {[wapp-param-exists pswd]} {
    wapp-set-cookie shopping-list-login $pswd
  }
  return 0
}

# Every page should call this routine at the end to clean up the database
# connection.
#
proc shopping-list-footer {} {
  db eval COMMIT
  db close
}

# The default action is to show the current shopping list.
#
# Query parameters may cause changes to the shopping list:
#    del=ID       Delete shopping list item ID if it exists
#    add=NAME     Add a new shopping list item called NAME
#                 but only if there is no existing item with the
#                 same name
#    undel=ID     Undo a prior delete of item ID.
# Only one of the above edit operations may be applied per request.
# The edit action is applied prior to displaying the shopping list.
# All edit actions are idempotent.
#
proc wapp-default {} {
  if {[shopping-list-header]} return
  set base [wapp-param SCRIPT_NAME]
  if {[wapp-param-exists del]} {
    set id [expr {[wapp-param del]+0}]
    db eval {
       INSERT INTO done(id,x) SELECT id, x FROM shoplist WHERE id=$id;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108

109
110
111
112
113
114
115
116
117
118
119
120
121
122




123

124
125
126
127
128

129



130
131
132
133
134
135
136
137
138
139
140
141
142
143




144
  }
  wapp-trim {
    <p><a class="button" href="%url($base/list)">Refresh</a>
    <p><a class="button" href="%url($base/list?logout=1)">Logout</a>
  }
  shopping-list-footer
}
proc shopping-list-header {} {
  wapp-trim {
    <html>
    <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link href="%url([wapp-param SCRIPT_NAME]/style.css)" rel="stylesheet">
    <title>Shopping List</title>
    </head><body>
    <h1>Shopping List</h1>
  }
  sqlite3 db $::DBFILE
  db timeout 1000
  db eval BEGIN
  if {[wapp-param-exists logout]} {
    wapp-clear-cookie shopping-list-login
    set pswd {}
  } else {
    set pswd [wapp-param pswd [wapp-param shopping-list-login]]
  }
  if {$pswd=="" 
    || ![db exists {SELECT 1 FROM config WHERE name='password' AND value=$pswd}]
  } {
    wapp-trim {
      <p><form method="POST" action="%url([wapp-param SELF_URL])">
      Password: <input type="password" name="pswd" width=12>
      <input type="submit" value="Login"></form></p>
    }
    db eval COMMIT
    db close
    return 1
  }
  if {[wapp-param-exists pswd]} {
    wapp-set-cookie shopping-list-login $pswd
  }
  return 0
}

proc shopping-list-footer {} {
  db eval COMMIT
  db close
}

proc wapp-page-common {} {
  if {[shopping-list-header]} return
  set base [wapp-param SCRIPT_NAME]
  wapp-subst {<p><a class="button" href="%url($base/list)">Go Back</a>}
  db eval {SELECT x FROM
             (SELECT DISTINCT x FROM done ORDER BY delid DESC LIMIT 30)
           ORDER BY x} {
    wapp-trim {
      <p>%html($x)
      <a class="button" href="%url($base/list?add=)%qp($x)">Add</a><br>
    }
  }
  shopping-list-footer
}




proc wapp-page-env {} {

  wapp-trim {
    <html>
    <h1>CGI Environment</h1>
    <pre>%html([wapp-debug-env])</pre>
  }

}



proc wapp-page-style.css {} {
  wapp-mimetype text/css
  wapp-cache-control max-age=3600
  wapp-trim {
     .button {
      font-size: 80%;
      text-decoration: none;
      padding: 2px 6px 2px 6px;
      border: 1px solid black;
      border-radius: 8px;
      background-color: #ddd;
    }
  }
}




wapp-start $argv







<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
>
|
<
|
<
>














>
>
>
>

>





>

>
>
>














>
>
>
>

127
128
129
130
131
132
133










134


























135
136

137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  }
  wapp-trim {
    <p><a class="button" href="%url($base/list)">Refresh</a>
    <p><a class="button" href="%url($base/list?logout=1)">Logout</a>
  }
  shopping-list-footer
}





































# This page shows recent purchases with an opportunity to re-add those
# purchases to the shopping list.  The idea is that to have easy access

# to common purchases.

#
proc wapp-page-common {} {
  if {[shopping-list-header]} return
  set base [wapp-param SCRIPT_NAME]
  wapp-subst {<p><a class="button" href="%url($base/list)">Go Back</a>}
  db eval {SELECT x FROM
             (SELECT DISTINCT x FROM done ORDER BY delid DESC LIMIT 30)
           ORDER BY x} {
    wapp-trim {
      <p>%html($x)
      <a class="button" href="%url($base/list?add=)%qp($x)">Add</a><br>
    }
  }
  shopping-list-footer
}

# The /env page shows the CGI environment.  This is for testing only.
# There are no links to this page.
#
proc wapp-page-env {} {
  if {[shopping-list-header]} return
  wapp-trim {
    <html>
    <h1>CGI Environment</h1>
    <pre>%html([wapp-debug-env])</pre>
  }
  shopping-list-footer
}

# The style-sheet
#
proc wapp-page-style.css {} {
  wapp-mimetype text/css
  wapp-cache-control max-age=3600
  wapp-trim {
     .button {
      font-size: 80%;
      text-decoration: none;
      padding: 2px 6px 2px 6px;
      border: 1px solid black;
      border-radius: 8px;
      background-color: #ddd;
    }
  }
}

# After all pages handling routines have been defined, start up
# the Wapp handler.
#
wapp-start $argv