gloo 6.0.1 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +9 -3
  3. data/README.md +39 -7
  4. data/docs/application.md +184 -0
  5. data/docs/getting_started.md +110 -0
  6. data/docs/iterators.md +294 -0
  7. data/docs/language_objects.md +190 -0
  8. data/docs/language_scripting.md +62 -0
  9. data/docs/language_syntax.md +334 -0
  10. data/docs/objects.md +77 -0
  11. data/docs/operators.md +62 -0
  12. data/docs/plugins.md +376 -0
  13. data/docs/verbs.md +64 -0
  14. data/docs/web_app.md +211 -0
  15. data/gloo.gemspec +3 -1
  16. data/lib/VERSION +1 -1
  17. data/lib/VERSION_NOTES +16 -0
  18. data/lib/gloo/app/engine.rb +17 -2
  19. data/lib/gloo/app/log.rb +5 -4
  20. data/lib/gloo/app/platform.rb +34 -2
  21. data/lib/gloo/app/prompt.rb +2 -1
  22. data/lib/gloo/app/settings.rb +25 -15
  23. data/lib/gloo/app/table.rb +7 -3
  24. data/lib/gloo/app/theme.rb +144 -0
  25. data/lib/gloo/core/gloo_system.rb +52 -1
  26. data/lib/gloo/core/invoker.rb +102 -0
  27. data/lib/gloo/core/parser.rb +48 -7
  28. data/lib/gloo/core/tokens.rb +81 -1
  29. data/lib/gloo/docs/doc_data.rb +160 -0
  30. data/lib/gloo/docs/help_shell.rb +332 -0
  31. data/lib/gloo/docs/markdown_renderer.rb +39 -0
  32. data/lib/gloo/expr/call.rb +54 -0
  33. data/lib/gloo/expr/expression.rb +3 -0
  34. data/lib/gloo/objs/basic/alias.rb +53 -0
  35. data/lib/gloo/objs/basic/boolean.rb +30 -0
  36. data/lib/gloo/objs/basic/container.rb +38 -0
  37. data/lib/gloo/objs/basic/decimal.rb +30 -0
  38. data/lib/gloo/objs/basic/integer.rb +58 -0
  39. data/lib/gloo/objs/basic/script.rb +31 -0
  40. data/lib/gloo/objs/basic/string.rb +31 -4
  41. data/lib/gloo/objs/basic/string_msgs.rb +212 -2
  42. data/lib/gloo/objs/basic/text.rb +30 -4
  43. data/lib/gloo/objs/basic/untyped.rb +21 -0
  44. data/lib/gloo/objs/ctrl/each.rb +63 -1
  45. data/lib/gloo/objs/ctrl/function.rb +86 -4
  46. data/lib/gloo/objs/ctrl/repeat.rb +41 -0
  47. data/lib/gloo/objs/dt/date.rb +43 -0
  48. data/lib/gloo/objs/dt/datetime.rb +50 -0
  49. data/lib/gloo/objs/dt/time.rb +43 -0
  50. data/lib/gloo/objs/str_utils/cipher.rb +59 -0
  51. data/lib/gloo/objs/str_utils/outline.rb +65 -1
  52. data/lib/gloo/objs/str_utils/password.rb +56 -0
  53. data/lib/gloo/objs/system/erb.rb +39 -0
  54. data/lib/gloo/objs/system/file_handle.rb +56 -0
  55. data/lib/gloo/objs/system/system.rb +29 -0
  56. data/lib/gloo/objs/web/http_get.rb +35 -0
  57. data/lib/gloo/objs/web/http_post.rb +33 -0
  58. data/lib/gloo/objs/web/json.rb +40 -0
  59. data/lib/gloo/objs/web/uri.rb +40 -0
  60. data/lib/gloo/shell/command_node.rb +39 -0
  61. data/lib/gloo/shell/context.rb +93 -0
  62. data/lib/gloo/shell/runner.rb +315 -0
  63. data/lib/gloo/verbs/break.rb +32 -0
  64. data/lib/gloo/verbs/check.rb +49 -0
  65. data/lib/gloo/verbs/cls.rb +18 -0
  66. data/lib/gloo/verbs/context.rb +47 -0
  67. data/lib/gloo/verbs/create.rb +42 -0
  68. data/lib/gloo/verbs/eval.rb +27 -0
  69. data/lib/gloo/verbs/execute.rb +27 -0
  70. data/lib/gloo/verbs/exists.rb +54 -2
  71. data/lib/gloo/verbs/files.rb +22 -0
  72. data/lib/gloo/verbs/help.rb +46 -178
  73. data/lib/gloo/verbs/if.rb +52 -0
  74. data/lib/gloo/verbs/invoke.rb +88 -33
  75. data/lib/gloo/verbs/list.rb +37 -4
  76. data/lib/gloo/verbs/load.rb +55 -2
  77. data/lib/gloo/verbs/log.rb +44 -0
  78. data/lib/gloo/verbs/move.rb +36 -1
  79. data/lib/gloo/verbs/put.rb +35 -0
  80. data/lib/gloo/verbs/quit.rb +19 -0
  81. data/lib/gloo/verbs/redirect.rb +52 -2
  82. data/lib/gloo/verbs/reload.rb +27 -0
  83. data/lib/gloo/verbs/run.rb +39 -0
  84. data/lib/gloo/verbs/save.rb +26 -0
  85. data/lib/gloo/verbs/show.rb +54 -0
  86. data/lib/gloo/verbs/tell.rb +32 -0
  87. data/lib/gloo/verbs/throw.rb +29 -0
  88. data/lib/gloo/verbs/unless.rb +50 -0
  89. data/lib/gloo/verbs/unload.rb +23 -0
  90. data/lib/gloo/verbs/version.rb +37 -3
  91. data/lib/gloo/verbs/wait.rb +26 -0
  92. data/test.gloo/objs/string.test.gloo +54 -0
  93. data/test.gloo/verbs/invoke.test.gloo +73 -0
  94. metadata +26 -10
  95. data/.DS_Store +0 -0
  96. data/.travis.yml +0 -5
data/docs/operators.md ADDED
@@ -0,0 +1,62 @@
1
+ # Operators
2
+
3
+ Gloo operators can be used to do basic math and to compare values.
4
+
5
+ **Contents**
6
+
7
+ - Math Operators
8
+ - Comparison Operators
9
+ - Example
10
+
11
+ ## Math Operators
12
+
13
+ These are the gloo math operators:
14
+
15
+ ```
16
+ + addition
17
+ - subtraction
18
+ * multiplication
19
+ / division
20
+ ```
21
+
22
+ ## Comparison Operators
23
+
24
+ Strings, integers, and decimal numbers can be compared.
25
+
26
+ These are the gloo comparison operators:
27
+
28
+ ```
29
+ = equal (== also works, as an alternate spelling — not a separate identity check)
30
+ != not equal
31
+ > greater than
32
+ < less than
33
+ >= greater than or equal to
34
+ <= less than or equal to
35
+ ```
36
+
37
+ ## Example
38
+
39
+ Here are some examples of math operator usage:
40
+
41
+ ```
42
+ > show 2 + 5
43
+ > put 12 / 3 into x
44
+ > show 23 * 3 - 6
45
+ ```
46
+
47
+ And some examples of comparison operator usage:
48
+
49
+ ```
50
+ > show 2 = 2
51
+ > show 2 != 2
52
+ > show 2 > 2
53
+ > show 2 < 2
54
+ > show 2 >= 2
55
+ > show 2 <= 2
56
+
57
+ > if a = b then show "the strings are equal"
58
+ > if x > y then run my_script
59
+ > put x != y into my_bool
60
+ ```
61
+
62
+ See also: Put, Show.
data/docs/plugins.md ADDED
@@ -0,0 +1,376 @@
1
+ # Plugins
2
+
3
+ **Contents**
4
+
5
+ - Core Libraries
6
+ - User Extensions
7
+
8
+ ## Core Libraries
9
+
10
+ Core Libraries extend gloo functionality, primarily by adding object types and potentially verbs.
11
+
12
+ Be sure to load a core library (or extension) prior to loading a gloo file that includes object types defined in the library.
13
+
14
+ Use the Load Verb to use an extension.
15
+
16
+ A core library ships as its own gem (`gloo-<name>`). `load lib <name>` requires the gem, installing it first via `gem install` if it isn't already present — so the explicit `gem install` step below is optional, but doing it yourself ahead of time is recommended so the install doesn't happen mid-script. Once loaded, a library's objects and verbs show up in the `help`/`?` shell exactly like built-ins:
17
+
18
+ ```gloo
19
+ > gem install gloo-yaml
20
+ > load lib yaml
21
+ help> object yaml
22
+ ```
23
+
24
+ ### Available Core Libraries
25
+
26
+ - **CLI** — Use the `gloo-cli` gem when building CLI applications.
27
+ - Library Objects: Prompt, Colorize, Confirm, Select, Menu, Menu Item, Shell, Command
28
+ ```gloo
29
+ > gem install gloo-cli
30
+ > load lib cli
31
+ help> object prompt
32
+ ```
33
+ - **Database** — Use the `gloo-db` gem and one or more of `gloo-sqlite`, `gloo-mysql`, `gloo-pg` connector gems.
34
+ - Library Objects: Query, Table, SQLite, MySQL, Postgres
35
+ ```gloo
36
+ > gem install gloo-db gloo-sqlite
37
+ > load lib db
38
+ > load lib sqlite
39
+ help> object query
40
+ ```
41
+ - **Email** — Use the `gloo-email` gem to send and receive email.
42
+ - Library Objects: Email, Email SMTP, Email IMAP
43
+ ```gloo
44
+ > gem install gloo-email
45
+ > load lib email
46
+ help> object email_smtp
47
+ ```
48
+ - **Markdown** — Use the `gloo-md` gem to render markdown.
49
+ - Library Objects: Markdown, MD Doc (a markdown file with YAML frontmatter), Markdown Extensions (part of the markdown object)
50
+ ```gloo
51
+ > gem install gloo-md
52
+ > load lib md
53
+ help> object markdown
54
+ ```
55
+ - **Test** — Use the `gloo-test` gem to manually include. See Test Runner for notes about the gloo test runner.
56
+ - Library Objects: Test
57
+ - Library Verbs: Assert, Refute
58
+ - See also: Eval, It
59
+ ```gloo
60
+ > gem install gloo-test
61
+ > load lib test
62
+ help> verb assert
63
+ ```
64
+ - **Web Server** — Use the `gloo-web` gem when building web applications.
65
+ - Library Objects: Server, Page, Partial, Form, Field, Element
66
+ ```gloo
67
+ > gem install gloo-web
68
+ > load lib web
69
+ help> object page
70
+ ```
71
+ - **YAML** — Use the `gloo-yaml` gem for YAML file read/write support.
72
+ - Library Objects: YAML
73
+ ```gloo
74
+ > gem install gloo-yaml
75
+ > load lib yaml
76
+ help> object yaml
77
+ ```
78
+
79
+ ## User Extensions
80
+
81
+ A User Extension is a mechanism that can be used to add verbs and objects that are not built into gloo.
82
+
83
+ Extensions are ruby code that live in the `extensions` folder inside the gloo root folder (`~/gloo/extensions` by default — see `ext_path` in Settings).
84
+
85
+ An extension is structured thus:
86
+
87
+ ```
88
+ ~/gloo/extensions/
89
+ /ext_name
90
+ /doc/
91
+ /src/
92
+ /test/
93
+ /ext_name_ext.rb
94
+ ```
95
+
96
+ - `ext_name_ext.rb` — the extension's entry point. Loaded and registered when `load ext ext_name` runs.
97
+ - `src/` — the verb and/or object classes themselves, one file per class.
98
+ - `doc/` — narrative markdown for the extension (a `README.md` at the extension root plus optional per-object/verb `.md` files under `doc/` are the convention used by the built-in extensions — see e.g. `extensions/beep/`).
99
+ - `test/` — both Ruby unit tests (`*_test.rb`, minitest, same conventions as this project's own `test/` — see Test Suites in the root `CLAUDE.md`) and/or a gloo-language integration test (`*.test.gloo`).
100
+
101
+ Be sure to load an extension (or core library) prior to loading a gloo file that includes object types defined in the extension.
102
+
103
+ Use the Load Verb to use an extension: `load ext ext_name`.
104
+
105
+ ### The extension entry point
106
+
107
+ `ext_name_ext.rb` defines a class named `<ExtName>Ext` (the extension's folder name, capitalized, plus `Ext`) that derives from `Gloo::Plugin::Base` and implements `register`. `register` is handed a `Gloo::Plugin::Callback` that it uses to register one or more verb and/or object classes:
108
+
109
+ ```ruby
110
+ #
111
+ # Registers the beep extension.
112
+ #
113
+ # This extension provides a simple beep command.
114
+ #
115
+ class BeepExt < Gloo::Plugin::Base
116
+
117
+ #
118
+ # Register verbs and objects.
119
+ #
120
+ def register( callback )
121
+ require_relative 'src/beep'
122
+
123
+ callback.register_verb( Beep )
124
+ end
125
+
126
+ end
127
+ ```
128
+
129
+ `callback.register_verb` and `callback.register_obj` both take a class, not an instance. Wrap the calls in a `begin`/`rescue` if the extension has external dependencies (a gem, a CLI tool on the `PATH`, etc.) that might not be present, so a missing dependency logs an error instead of crashing the whole extension load — see `extensions/stats/stats_ext.rb` or `extensions/git/git_ext.rb` for the pattern:
130
+
131
+ ```ruby
132
+ def register( callback )
133
+ require_relative 'src/git'
134
+
135
+ begin
136
+ callback.register_obj( Git )
137
+ rescue => e
138
+ puts "Failed to load Git extension: #{e.message}"
139
+ end
140
+ end
141
+ ```
142
+
143
+ ### Adding a Verb
144
+
145
+ A verb subclasses `Gloo::Core::Verb` and must implement `self.keyword`, `self.keyword_shortcut`, and `run`. Inside `run`, `@tokens` gives access to the parsed command line and `@engine` is the running engine (use `@engine.err` for user-facing errors, `@engine.heap.it` to set the implicit `it` result).
146
+
147
+ The simplest possible verb — `beep`, which takes no parameters (`extensions/beep/src/beep.rb`):
148
+
149
+ ```ruby
150
+ #
151
+ # Play a standard system beep sound.
152
+ #
153
+ class Beep < Gloo::Core::Verb
154
+
155
+ KEYWORD = 'beep'.freeze
156
+ KEYWORD_SHORT = 'b'.freeze
157
+
158
+ def self.keyword
159
+ return KEYWORD
160
+ end
161
+
162
+ def self.keyword_shortcut
163
+ return KEYWORD_SHORT
164
+ end
165
+
166
+ def run
167
+ print 7.chr
168
+ end
169
+
170
+ # ---------------------------------------------------------------------
171
+ # Verb Documentation
172
+ # ---------------------------------------------------------------------
173
+
174
+ def self.doc_data
175
+ {
176
+ :name => KEYWORD,
177
+ :shortcut => KEYWORD_SHORT,
178
+ :description => 'Play a standard system beep sound.',
179
+ :syntax => [ 'beep' ],
180
+ :result => 'A system beep (chime) is sounded.',
181
+ :examples => <<~EXAMPLES.strip
182
+ > beep
183
+ EXAMPLES
184
+ }
185
+ end
186
+
187
+ end
188
+ ```
189
+
190
+ A verb that reads a parameter — `alert`, which evaluates an expression and shows it as a system notification (`extensions/alert/src/alert.rb`):
191
+
192
+ ```ruby
193
+ class Alert < Gloo::Core::Verb
194
+
195
+ KEYWORD = 'alert'.freeze
196
+ KEYWORD_SHORT = '!'.freeze
197
+
198
+ MISSING_EXPR_ERR = 'Missing Expression!'.freeze
199
+ NO_RESULT_ERR = 'Expression evaluated with no result!'.freeze
200
+
201
+ def run
202
+ unless @tokens.token_count > 1
203
+ @engine.err MISSING_EXPR_ERR
204
+ return
205
+ end
206
+
207
+ expr = Gloo::Expr::Expression.new( @engine, @tokens.params )
208
+ result = expr.evaluate
209
+
210
+ if result
211
+ @engine.heap.it.set_to result
212
+ post_alert result
213
+ else
214
+ @engine.err NO_RESULT_ERR
215
+ end
216
+ end
217
+
218
+ def self.keyword
219
+ return KEYWORD
220
+ end
221
+
222
+ def self.keyword_shortcut
223
+ return KEYWORD_SHORT
224
+ end
225
+
226
+ private
227
+
228
+ def post_alert( msg )
229
+ @engine.log.info msg
230
+ return if @engine.args.quiet?
231
+
232
+ post_osx msg
233
+ end
234
+
235
+ def post_osx( msg )
236
+ cmd1 = '/usr/bin/osascript -e "display notification \"'
237
+ cmd2 = '\" with title \"Gloo\" "'
238
+ system( cmd1 + msg.to_s + cmd2 )
239
+ end
240
+
241
+ end
242
+ ```
243
+
244
+ Register it from `alert_ext.rb` with `callback.register_verb( Alert )`, and the verb `alert {message}` becomes available anywhere after `load ext alert`.
245
+
246
+ ### Adding an Object
247
+
248
+ An object subclasses `Gloo::Core::Obj` and must implement `self.typename` and `self.short_typename`. Objects typically:
249
+
250
+ - expose named children (settings/parameters) that are read with `find_child`
251
+ - optionally auto-add default children on creation, via `add_children_on_create?` and `add_default_children`
252
+ - respond to messages (`tell obj to some_message`) by overriding `self.messages` to list the message names and defining a `msg_<name>` method for each
253
+
254
+ `stats`, from `extensions/stats/src/stats.rb`, shows all three. It declares three children (`folder`, `types`, `skip`), adds them automatically on `create`, and implements three messages that delegate to a plain Ruby helper class (`Gloo::Utils::Stats`, in `extensions/stats/src/stats_util.rb`) that does the real work:
255
+
256
+ ```ruby
257
+ class Stats < Gloo::Core::Obj
258
+
259
+ KEYWORD = 'stats'.freeze
260
+ KEYWORD_SHORT = 'stat'.freeze
261
+ FOLDER = 'folder'.freeze
262
+ TYPES = 'types'.freeze
263
+ SKIP = 'skip'.freeze
264
+
265
+ def self.typename
266
+ return KEYWORD
267
+ end
268
+
269
+ def self.short_typename
270
+ return KEYWORD_SHORT
271
+ end
272
+
273
+ def path_value
274
+ o = find_child FOLDER
275
+ return o ? o.value : nil
276
+ end
277
+
278
+ def types_value
279
+ o = find_child TYPES
280
+ return o ? o.value : ''
281
+ end
282
+
283
+ def skip_list
284
+ o = find_child SKIP
285
+ val = o ? o.value : ''
286
+ return val.split ' '
287
+ end
288
+
289
+ # ---------------------------------------------------------------------
290
+ # Children
291
+ # ---------------------------------------------------------------------
292
+
293
+ def add_children_on_create?
294
+ return true
295
+ end
296
+
297
+ def add_default_children
298
+ fac = @engine.factory
299
+ fac.create_file FOLDER, '', self
300
+ fac.create_string TYPES, '', self
301
+ fac.create_can SKIP, self
302
+ end
303
+
304
+ # ---------------------------------------------------------------------
305
+ # Messages
306
+ # ---------------------------------------------------------------------
307
+
308
+ def self.messages
309
+ all = %w[show_all]
310
+ more = %w[show_busy_folders show_types]
311
+ return super + all + more
312
+ end
313
+
314
+ def msg_show_all
315
+ o = Gloo::Utils::Stats.new(
316
+ @engine, path_value, types_value, skip_list )
317
+ o.show_all
318
+ end
319
+
320
+ def msg_show_types
321
+ o = Gloo::Utils::Stats.new(
322
+ @engine, path_value, types_value, skip_list )
323
+ o.file_types
324
+ end
325
+
326
+ def msg_show_busy_folders
327
+ o = Gloo::Utils::Stats.new(
328
+ @engine, path_value, types_value, skip_list )
329
+ o.busy_folders
330
+ end
331
+
332
+ end
333
+ ```
334
+
335
+ `self.messages` should call `super` and append to it — the base `Gloo::Core::Obj` already contributes messages every object receives (`reload`, `unload`, `blank?`, `contains?`, `responds_to?`).
336
+
337
+ Used from gloo, once loaded:
338
+
339
+ ```gloo
340
+ main [can] :
341
+ stats [stats] :
342
+ folder [file] : /Users/me/dev/project
343
+ types [string] : rb erb js
344
+ skip [string] : .git tmp
345
+ on_load [script] :
346
+ tell main.stats to show_all
347
+ ```
348
+
349
+ Register it from `stats_ext.rb` with `callback.register_obj( Stats )`.
350
+
351
+ ### Custom `each` iterators
352
+
353
+ An extension's object can also plug into the built-in `each` verb by providing its own iterator. `extensions/git/src/each_repo.rb` shows the shape: a plain Ruby class (not a `Gloo::Core::Obj`) with `self.use_for?( iterator_obj )` — which returns `true` when the `each` loop's iterator object looks like a match (here, when it has a `repo` child) — and a `run` method that walks whatever it's iterating over, setting the loop's child value and calling `@iterator_obj.run_do` for each item. See the git extension for the full pattern; this hook only makes sense for extensions that also register a matching object type (here, `git_repo`).
354
+
355
+ ### Documenting the extension
356
+
357
+ Add `self.doc_data` to every verb/object class (see the `beep` and `stats` examples above) — this is what powers the in-app `help`/`?` shell once the extension is loaded, exactly as it does for built-in verbs and objects (see `lib/gloo/docs/doc_data.rb`). Also add a top-level `README.md` for the extension (usage, `load ext` line, list of verbs/objects, a pointer to `help> verb <name>` / `help> object <name>` for the full reference) — see `extensions/beep/README.md` or `extensions/git/README.md` for the expected shape and length.
358
+
359
+ ### Testing an extension
360
+
361
+ Add a Ruby unit test per verb/object class under `test/` (mirrors the conventions in the root `CLAUDE.md`'s Test Suites section — inherit from the project's `GlooTest`/`BaseEngineTest` base), and add a `*.test.gloo` integration test that loads the extension and exercises it end to end, e.g. `extensions/beep/test/beep.test.gloo`:
362
+
363
+ ```gloo
364
+ tests [can] :
365
+ beep [can] :
366
+
367
+ on_load [script] :
368
+ load ext beep
369
+
370
+ assert_verb [test] :
371
+ description [string] : The beep verb exists
372
+ on_test [script] :
373
+ exists? verb beep
374
+ assert "beep verb should exist"
375
+ beep
376
+ ```
data/docs/verbs.md ADDED
@@ -0,0 +1,64 @@
1
+ # Verbs
2
+
3
+ Verbs are the commands that make up a gloo script — `put`, `show`, `run`, `tell`, and 25 others. Every statement in gloo starts with a verb.
4
+
5
+ Verbs aren't just for scripts, though. They're also the interactive language of the gloo application itself: run `gloo` in CLI mode (see Application, Running Gloo) and you can type these same verbs directly at the prompt, one at a time, in a REPL.
6
+
7
+ **Contents**
8
+
9
+ - Run
10
+ - Tell
11
+ - Put
12
+
13
+ This page walks through three of the most commonly used verbs to get a feel for how they work together. For the complete list of verbs, their full syntax, and every error they can raise, use the in-app help: enter `help` (or `?`), then `verbs` to list them all, or `verb {name}` for detail on one (see Application, Help).
14
+
15
+ ## Run
16
+
17
+ `run` runs a script or other runnable object — the same as sending it a `run` message.
18
+
19
+ ```gloo
20
+ run {path.to.object}
21
+ ```
22
+
23
+ ```gloo
24
+ > run my.script
25
+
26
+ > create s as script : "show 3 + 4"
27
+ > run s
28
+ ```
29
+
30
+ ## Tell
31
+
32
+ `tell` sends a message to an object, asking it to do something. Where `run` executes a runnable object, `tell` is the general-purpose way to invoke any message an object supports (`up`, `count`, `inc`, `randomize` — see Objects).
33
+
34
+ ```gloo
35
+ tell {path.to.object} to {message}
36
+ ```
37
+
38
+ ```gloo
39
+ > tell an.obj to unload
40
+ > tell the.script to run
41
+ > tell my.str to up
42
+ > tell the.container to count
43
+ ```
44
+
45
+ ## Put
46
+
47
+ `put` evaluates an expression and stores the result in an object.
48
+
49
+ ```gloo
50
+ put {expression} into {dst.path}
51
+ ```
52
+
53
+ ```gloo
54
+ > put 'one' into str
55
+ > put 123 into x
56
+ > put 3 + 5 into x
57
+ > put TRUE into flag
58
+ ```
59
+
60
+ `it` also picks up the result of the evaluation, same as with other verbs — see It.
61
+
62
+ ---
63
+
64
+ `run`, `tell`, and `put` cover a lot of ground on their own, but there are 26 more verbs — `show`, `if`, `create`, `each`, `check`, and so on — all documented in-app. Enter `help` (or `?`), then `verbs` to browse them. (This page itself is also viewable in-app: `help> doc verbs`.)
data/docs/web_app.md ADDED
@@ -0,0 +1,211 @@
1
+ # A Trivial Web App
2
+
3
+ **Contents**
4
+
5
+ - Overview
6
+ - File and Folder Layout
7
+ - start.gloo
8
+ - app/app.gloo
9
+ - layout/primary.gloo
10
+ - shared/nav.gloo
11
+ - page/home.gloo
12
+ - page/about.gloo
13
+ - Running It
14
+ - Where To Go From Here
15
+
16
+ ## Overview
17
+
18
+ This walks through the smallest complete gloo web app: a "Hello World" with two pages (`home` and `about`) sharing a common layout and nav bar. It uses the `gloo-web` core library — see Plugins for how core libraries are installed and loaded in general.
19
+
20
+ The app runs in App Mode (`gloo --app {path}`, see Application) — gloo looks for a `start.gloo` file at the root of the app folder and runs it. That file loads everything else and starts the web server.
21
+
22
+ ## File and Folder Layout
23
+
24
+ ```
25
+ hello/
26
+ start.gloo
27
+ app/
28
+ app.gloo
29
+ layout/
30
+ primary.gloo
31
+ shared/
32
+ nav.gloo
33
+ page/
34
+ home.gloo
35
+ about.gloo
36
+ ```
37
+
38
+ - `start.gloo` — the entry point. Loads the `web` core library, then everything under `app/`, `layout/`, `shared/`, and `page/`, then starts the server.
39
+ - `app/app.gloo` — the `app` object: the app's URL and its `svr` (web server), including server config and the default routes (layout, home page).
40
+ - `layout/primary.gloo` — the page layout shared by every page: the HTML shell, the nav bar, and where a page's own head/body content gets inserted.
41
+ - `shared/nav.gloo` — a partial (reusable fragment) for the nav bar, included by the layout.
42
+ - `page/home.gloo`, `page/about.gloo` — the two pages. Every `[page]` object loaded under the root `page` container automatically becomes a route: `page.home` answers `/`, `page.about` answers `/about`. Routes are wired up by the router when the server starts — there's no separate routing table to maintain by hand.
43
+
44
+ ## start.gloo
45
+
46
+ ```gloo
47
+ #
48
+ # Start the hello app.
49
+ #
50
+ # Run it:
51
+ # gloo --app ~/gloo/projects/apps/hello
52
+ #
53
+
54
+ start [container] :
55
+
56
+ on_load [script] :
57
+
58
+ # Load the web core library.
59
+ load lib web
60
+
61
+ # Load the app's own objects.
62
+ load app/*
63
+ load layout/*
64
+ load shared/*
65
+ load page/*
66
+
67
+ # Start the server and open it in a browser.
68
+ tell app.svr to start
69
+ tell app.url to open
70
+ ```
71
+
72
+ ## app/app.gloo
73
+
74
+ ```gloo
75
+ #
76
+ # The hello app: web server config and default routes.
77
+ #
78
+
79
+ app [can] :
80
+
81
+ # The app's URL.
82
+ url [uri] : http://localhost:8080/
83
+
84
+ # The web server for the app.
85
+ svr [svr] :
86
+
87
+ config [container] :
88
+ scheme [string] : http
89
+ host [string] : localhost
90
+ port [string] : 8080
91
+
92
+ on_start [script] : show 'hello app started'
93
+ on_stop [script] : show 'hello app stopped'
94
+
95
+ # Default layout and home page.
96
+ layout [alias] : layout.primary
97
+ home [alias] : page.home
98
+ ```
99
+
100
+ `svr` is a `gloo-web` object type (see Plugins — Core Libraries). `layout` and `home` are conventional aliases: `layout` points at the partial used to wrap every page that doesn't specify its own, and `home` points at the page served for `/`. A real app would also set `error [alias] : page.err` to control the page shown on a server error, but it's optional — gloo falls back to a generic message if it's not set.
101
+
102
+ ## layout/primary.gloo
103
+
104
+ ```gloo
105
+ #
106
+ # The shared page layout: HTML shell + nav bar.
107
+ # Every page renders inside this unless it specifies its own layout.
108
+ #
109
+
110
+ layout [can] :
111
+ primary [part] :
112
+ content [can] :
113
+
114
+ html_open [text] : BEGIN
115
+ <!DOCTYPE html>
116
+ <html lang="en">
117
+ <head>
118
+ <%= head %>
119
+ </head>
120
+ <body>
121
+ END
122
+
123
+ nav [alias] : shared.nav
124
+ body [string] : <%= body %>
125
+
126
+ html_close [text] : BEGIN
127
+ </body>
128
+ </html>
129
+ END
130
+ ```
131
+
132
+ `primary` is a `[part]` (partial) — see Plugins for the `gloo-web` object list. `<%= head %>` and `<%= body %>` are filled in automatically by the page being rendered: whatever that page defines under its own `head` and `body` children. `nav` is an alias to the shared nav partial below, rendered inline wherever it appears in the layout's content.
133
+
134
+ ## shared/nav.gloo
135
+
136
+ ```gloo
137
+ #
138
+ # The shared nav bar, included by the layout.
139
+ #
140
+
141
+ shared [can] :
142
+ nav [part] :
143
+ content [text] : BEGIN
144
+ <nav>
145
+ <a href="/">Home</a>
146
+ <a href="/about">About</a>
147
+ </nav>
148
+ END
149
+ ```
150
+
151
+ ## page/home.gloo
152
+
153
+ ```gloo
154
+ #
155
+ # The home page ("/").
156
+ #
157
+
158
+ page [can] :
159
+ home [page] :
160
+
161
+ params [can] :
162
+ msg [string] : Hello, World!
163
+
164
+ head [e] :
165
+ content [can] :
166
+ title [e] : Hello
167
+
168
+ body [e] :
169
+ content [can] :
170
+ h1 [e] : <%= msg %>
171
+ p [e] : This is the home page.
172
+ ```
173
+
174
+ `page.home` is what `app.svr.home` points to, so it answers requests to `/`. `params` declares values the page's content can reference — here just `msg`, used in the `<h1>` via `<%= msg %>`. `head` and `title` and `body`, `h1`, `p` are `[e]` (element) objects — see Plugins — the building blocks the layout's `<%= head %>`/`<%= body %>` render.
175
+
176
+ ## page/about.gloo
177
+
178
+ ```gloo
179
+ #
180
+ # The about page ("/about"), reached by name automatically —
181
+ # no routing table entry required.
182
+ #
183
+
184
+ page [can] :
185
+ about [page] :
186
+
187
+ head [e] :
188
+ content [can] :
189
+ title [e] : About
190
+
191
+ body [e] :
192
+ content [can] :
193
+ h1 [e] : About
194
+ p [e] : A trivial two-page gloo web app.
195
+ ```
196
+
197
+ Because this page is named `about` and lives directly under the root `page` container, it's automatically routed to `/about` the moment the server starts — see File and Folder Layout above.
198
+
199
+ ## Running It
200
+
201
+ ```shell
202
+ gloo --app ~/gloo/projects/apps/hello
203
+ ```
204
+
205
+ This runs `start.gloo`, which starts the server and opens `http://localhost:8080/` in a browser. Visit `/about` to see the second page. Stop the app the same way as any other gloo app (`q` at the prompt, or `Ctrl-C`).
206
+
207
+ Once the app is running, `gloo-web`'s objects (`page`, `part`, `e`, `svr`, `form`, `field`) are all documented in-app — `help> object page`, etc. — see Plugins.
208
+
209
+ ## Where To Go From Here
210
+
211
+ This example deliberately leaves out most of what `gloo-web` supports: forms and fields (`form`, `field`), page parameters populated from query strings, sessions, static assets (images/CSS/JS served from an `asset/` folder, with `image_tag`/`css_tag`/`js_tag` layout helpers), a database-backed page (`gloo-db` plus a `sqlite`/`mysql`/`postgres` driver — see Plugins), and a dedicated error page. Each of those follows the same shape shown here: an object type from `gloo-web` (or another core library), loaded the same way, documented the same way in `help`.