index.html (15477B)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <title>Documentation</title> 7 <style> 8 html, body { 9 min-height: 100%; 10 margin: 0; 11 padding: 0; 12 background: #0f1113; 13 color: #e6eef3; 14 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; 15 line-height: 1.5; 16 -webkit-font-smoothing: antialiased; 17 -moz-osx-font-smoothing: grayscale; 18 } 19 20 main { 21 max-width: 830px; 22 margin: 0 auto; 23 padding: 36px; 24 } 25 26 header { 27 margin-bottom: 36px; 28 } 29 30 h1 { 31 font-size: 40px; 32 font-weight: 700; 33 margin: 0 0 20px 0; 34 } 35 36 h2 { 37 font-size: 32px; 38 margin: 26px 0 14px; 39 border-bottom: 1px solid rgba(255,255,255,.1); 40 padding-bottom: 6px; 41 } 42 43 h3 { 44 font-size: 26px; 45 margin: 22px 0 12px; 46 } 47 48 p { 49 margin: 14px 0; 50 } 51 52 header p { 53 color: #9aa6b1; 54 } 55 56 nav { 57 margin: 28px 0; 58 padding: 20px; 59 background: #1a1c20; 60 border: 1px solid rgba(255,255,255,.06); 61 border-radius: 4px; 62 } 63 64 nav h2 { 65 font-size: 20px; 66 margin: 0 0 12px 0; 67 border: none; 68 padding: 0; 69 } 70 71 nav ul { 72 list-style: none; 73 padding: 0; 74 margin: 0; 75 } 76 77 nav li { 78 margin: 6px 0; 79 } 80 81 a { 82 color: #68a6ff; 83 text-decoration: none; 84 transition: color .15s ease; 85 } 86 87 a:hover { 88 text-decoration: underline; 89 } 90 91 section { 92 margin-top: 36px; 93 } 94 95 ul, ol { 96 margin: 14px 0; 97 padding-left: 26px; 98 } 99 100 li { 101 margin: 6px 0; 102 } 103 104 code { 105 padding: 3px 7px; 106 border-radius: 3px; 107 font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace; 108 font-size: .9em; 109 color: #cde7ff; 110 background: #1a1c20; 111 border: 1px solid rgba(255,255,255,.06); 112 } 113 114 pre { 115 padding: 20px; 116 border-radius: 4px; 117 margin: 14px 0; 118 overflow-x: auto; 119 background: #1a1c20; 120 border: 1px solid rgba(255,255,255,.06); 121 font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace; 122 font-size: 14px; 123 line-height: 1.6; 124 } 125 126 pre code { 127 background: none; 128 border: none; 129 padding: 0; 130 font-size: inherit; 131 color: inherit; 132 } 133 134 blockquote { 135 border-left: 3px solid #68a6ff; 136 padding-left: 18px; 137 margin: 14px 0; 138 color: #dfe9ee; 139 font-style: italic; 140 } 141 142 table { 143 width: 100%; 144 border-collapse: collapse; 145 margin: 14px 0; 146 } 147 148 th, td { 149 padding: 12px 16px; 150 text-align: left; 151 border-bottom: 1px solid rgba(255,255,255,.06); 152 } 153 154 th { 155 background: #1a1c20; 156 font-weight: 600; 157 color: #f0f6f8; 158 } 159 160 tr:hover { 161 background: rgba(255,255,255,.02); 162 } 163 164 footer { 165 margin-top: 48px; 166 padding-top: 20px; 167 border-top: 1px solid rgba(255,255,255,.1); 168 color: #9aa6b1; 169 font-size: 14px; 170 } 171 </style> 172 </head> 173 <body> 174 <main> 175 <header> 176 <h1>Documentation</h1> 177 <p>Fes: A lightweight, static, and opinionated microframework.</p> 178 </header> 179 180 <nav> 181 <h2>Contents</h2> 182 <ul> 183 <li><a href="#introduction">Introduction</a></li> 184 <li><a href="#installation">Installation</a></li> 185 <li><a href="#usage">Usage</a></li> 186 <li><a href="#quick">Quick Start</a></li> 187 <li><a href="#cli-reference">Cli Reference</a></li> 188 <li><a href="#reference">Reference</a></li> 189 </ul> 190 </nav> 191 192 <section id="introduction"> 193 <h2>Introduction</h2> 194 <p>Fes, or Free Easy Site, is a microframework used for small static sites. It is not designed for complex web applications and that is why it is good. Yes, I hate modern web and that is the reason this exists.</p> 195 </section> 196 197 <section id="installation"> 198 <h2>Installation</h2> 199 <pre><code>git clone https://git.vxserver.dev/fSD/fes</code></pre> 200 <pre><code>cd fes</code></pre> 201 <pre><code>go install fes</code></pre> 202 </section> 203 204 <section id="usage"> 205 <h2>Usage</h2> 206 <p>Typical workflows and examples.</p> 207 <ul> 208 <li>Creating project</li> 209 <li>Hosting websites</li> 210 <li>Generating websites</li> 211 </ul> 212 </section> 213 214 <section id="quick"> 215 <h2>Quick Start</h2> 216 <pre><code>fes new hello</code></pre> 217 <p>This creates a new project under the name <code>hello</code>.</p> 218 <pre><code>fes run hello</code></pre> 219 <p>This runs your project <code>hello</code>, by default at <a href="localhost:3000" target="_blank">localhost:3000</a>.</p> 220 <h3>Extensions</h3> 221 <p>Let's add a paragraph to this simple site. Right now you have the following page:</p> 222 <pre><code>local fes = require("fes") 223 local site = fes.fes() 224 225 -- site.copyright = fes.util.copyright("https://fsd.vxserver.dev", "vx-clutch") 226 227 site:h1("Hello, World!") 228 229 return site</code></pre> 230 <p>To add a simple paragraph modify like so:</p> 231 <pre><code>local fes = require("fes") 232 local site = fes.fes() 233 234 -- site.copyright = fes.util.copyright("https://fsd.vxserver.dev", "vx-clutch") 235 236 site:h1("Hello, World!") 237 site:p("This is a paragraph") 238 239 return site</code></pre> 240 </section> 241 242 <section id="cli-reference"> 243 <h2>Cli Reference</h2> 244 <table> <thead> 245 <tr> 246 <th>Name</th> 247 <th>Description</th> 248 </tr> 249 </thead> 250 <tbody> 251 <tr> 252 <td><code>new <project></code></td> 253 <td>Create a new projet called <project></td> 254 </tr> 255 <tr> 256 <td><code>doc</code></td> 257 <td>Open this documention page</td> 258 </tr> 259 <tr> 260 <td><code>run <project></code></td> 261 <td>Run the projet called <project></td> 262 </tr> 263 <tr> 264 <td><code>-help</code></td> 265 <td>Display help information.</td> 266 </tr> 267 <tr> 268 <td><code>-V1</code></td> 269 <td>Print extended version information, this is very helpful when it comes to bug reporting.</td> 270 </tr> 271 <tr> 272 <td><code>-no-color</code></td> 273 <td>Disable color output.</td> 274 </tr> 275 <tr> 276 <td><code>-p <port></code></td> 277 <td>Set the server port.</td> 278 </tr> 279 <tr> 280 <td><code>-static</code></td> 281 <td>Render and save all pages. (this feature is yet to be implemented)</td> 282 </tr> 283 <tr> 284 <td><code>-version</code></td> 285 <td>Print the version.</td> 286 </tr> 287 </tbody> 288 </table> 289 </section> 290 291 <section id="reference"> 292 <h2>Reference</h2> 293 All <code>std</code> functions have binding for the site and can be used like so: <code>site:h1("Hello, World!")</code>, where site is the site object. 294 <h3>Builtin</h3> 295 <table> 296 <thead> 297 <tr> 298 <th>Name</th> 299 <th>Description</th> 300 </tr> 301 </thead> 302 <tbody> 303 <tr> 304 <td><code>fes()</code></td> 305 <td>Generate a site object</td> 306 </tr> 307 <tr> 308 <td><code>:custom()</code></td> 309 <td>Add a custom string to the site body</td> 310 </tr> 311 <tr> 312 <td><code>markdown_to_html(str: string)</code></td> 313 <td>Returns generated HTML from provided Markdown string.</td> 314 </tr> 315 </tbody> 316 </table> 317 <h3>Std</h3> 318 <table> 319 <thead> 320 <tr> 321 <th>Name</th> 322 <th>Description</th> 323 </tr> 324 </thead> 325 <tbody> 326 <tr> 327 <td><code>std.fes_version()</code></td> 328 <td>Get the current version of fes.</td> 329 </tr> 330 <tr> 331 <td><code>std.site_version()</code></td> 332 <td>Get the current version of the site, defined in <code>Fes.toml</code>.</td> 333 </tr> 334 <tr> 335 <td><code>std.site_name()</code></td> 336 <td>Get the current name of the site, defined in <code>Fes.toml</code>.</td> 337 </tr> 338 <tr> 339 <td><code>std.site_title()</code></td> 340 <td>Get the current name of the site, defined in <code>Fes.toml</code>.</td> 341 </tr> 342 <tr> 343 <td><code>std.site_authors()</code></td> 344 <td>Get a table of the authors of the site, defined in <code>Fes.toml</code>.</td> 345 </tr> 346 <tr> 347 <td><code>std.join</code></td> 348 <td>Get a table of the authors of the site, defined in <code>Fes.toml</code>.</td> 349 </tr> 350 <tr> 351 <td><code>std.a(link: string, str: string)</code></td> 352 <td>Returns an anchor tag.</td> 353 </tr> 354 <tr> 355 <td><code>std.ha(link: string, str: string)</code></td> 356 <td>Returns an anchor tag with sytiling to make it hidden.</td> 357 </tr> 358 <tr> 359 <td><code>std.external(link: string, str: string)</code></td> 360 <td>Returns an anchor tag that opens up in a new tab.</td> 361 </tr> 362 <tr> 363 <td><code>std.note(str: string)</code></td> 364 <td>Returns a note object.</td> 365 </tr> 366 <tr> 367 <td><code>std.muted(str: string)</code></td> 368 <td>Returns a muted object.</td> 369 </tr> 370 <tr> 371 <td><code>std.callout(str: string)</code></td> 372 <td>Returns a callout object.</td> 373 </tr> 374 <tr> 375 <td><code>std.h1(str: string)</code></td> 376 <td>Returns a header level 1 object.</td> 377 </tr> 378 <tr> 379 <td><code>std.h2(str: string)</code></td> 380 <td>Returns a header level 2 object.</td> 381 </tr> 382 <tr> 383 <td><code>std.h3(str: string)</code></td> 384 <td>Returns a header level 3 object.</td> 385 </tr> 386 <tr> 387 <td><code>std.h4(str: string)</code></td> 388 <td>Returns a header level 4 object.</td> 389 </tr> 390 <tr> 391 <td><code>std.h5(str: string)</code></td> 392 <td>Returns a header level 5 object.</td> 393 </tr> 394 <tr> 395 <td><code>std.h6(str: string)</code></td> 396 <td>Returns a header level 6 object.</td> 397 </tr> 398 <tr> 399 <td><code>std.p(str: string)</code></td> 400 <td>Returns a paragraph object.</td> 401 </tr> 402 <tr> 403 <td><code>std.pre(str: string)</code></td> 404 <td>Returns preformated text.</td> 405 </tr> 406 <tr> 407 <td><code>std.code(str: string)</code></td> 408 <td>Returns a codeblock.</td> 409 </tr> 410 <tr> 411 <td><code>std.ul(items: {...strings})</code></td> 412 <td>Generates an unordered list from a table of strings.</td> 413 </tr> 414 <tr> 415 <td><code>std.ol(items: {...strings})</code></td> 416 <td>Generates an ordered list from a table of strings.</td> 417 </tr> 418 <tr> 419 <td><code>std.tl(items: {...strings})</code></td> 420 <td>Generates a table from a table of strings.</td> 421 </tr> 422 <tr> 423 <td><code>std.blockquote(str: string)</code></td> 424 <td>Returns a blockquote.</td> 425 </tr> 426 <tr> 427 <td><code>std.hr()</code></td> 428 <td>Returns a horizonal rule.</td> 429 </tr> 430 <tr> 431 <td><code>std.img(src: string, alt: string)</code></td> 432 <td>Returns an image at location source with given alternative text.</td> 433 </tr> 434 <tr> 435 <td><code>std.strong(str: string)</code></td> 436 <td>Returns bolded text.</td> 437 </tr> 438 <tr> 439 <td><code>std.em(str: string)</code></td> 440 <td>Returns italicized text.</td> 441 </tr> 442 <tr> 443 <td><code>std.br()</code></td> 444 <td>Returns a break.</td> 445 </tr> 446 <tr> 447 <td><code>std.div(content: string, class: string)</code></td> 448 <td>Returns a div of class <code>class</code> with content of <code>content</code>.</td> 449 </tr> 450 <tr> 451 <td><code>std.spa(content: string, class: string)</code></td> 452 <td>Returns a span of class <code>class</code> with content of <code>content</code>.</td> 453 </tr> 454 <tr> 455 <td><code>std.escape(str: string)</code></td> 456 <td>Returns an html escaped string.</td> 457 </tr> 458 <tr> 459 <td><code>std.highlight(str: string)</code></td> 460 <td>Returns highlighted text.</td> 461 </tr> 462 <tr> 463 <td><code>std.banner(str: string)</code></td> 464 <td>Returns a banner that is attached to the top of the site.</td> 465 </tr> 466 <tr> 467 <td><code>std.center(str: string)</code></td> 468 <td>Returns centered text.</td> 469 </tr> 470 <tr> 471 <td><code>std.nav(link: string, str: string)</code></td> 472 <td>Returns a speical navigation link, used for in-site traversal.</td> 473 </tr> 474 <tr> 475 <td><code>std.rl(r: string, l: string)</code></td> 476 <td>Right and light alight content.</td> 477 </tr> 478 </tbody> 479 </table> 480 <h3>Symbol</h3> 481 <table> <thead> 482 <tr> 483 <th>Name</th> 484 <th>Symbol</th> 485 </tr> 486 </thead> 487 <tbody> 488 <tr> 489 <td><code>symbol.copyright</code></td> 490 <td>©</td> </tr> 491 <tr> 492 <td><code>Registered Trademark</code></td> 493 <td>®</td> 494 </tr> 495 <tr> 496 <td><code>Trademark</code></td> 497 <td>™</td> 498 </tr> 499 </tbody> 500 </table> 501 <h3>Util</h3> 502 <table> <thead> 503 <tr> 504 <th>Name</th> 505 <th>Description</th> 506 </tr> 507 </thead> 508 <tbody> 509 <tr> 510 <td><code>util.cc(tbl: {...strings})</code></td> 511 <td>Concatenate a table of strings into a single string.</td> 512 </tr> 513 <tr> 514 <td><code>util.copyright(link: string, holder: string)</code></td> 515 <td>Used when setting the website copyright holder.</td> 516 </tr> 517 </tbody> 518 </table> 519 <h3>Dkjson</h3> 520 This is a third party object and is best documented <a href="https://dkolf.de/dkjson-lua/documentation" target="_blank">here</a> 521 <table> <thead> 522 <tr> 523 <th>Name</th> 524 <th>Description</th> 525 </tr> 526 </thead> 527 <tbody> 528 <tr> 529 <td><code>dkjson.encode(obj: {...any})</code></td> 530 <td>Serilize a Lua table into JSON.</td> 531 </tr> 532 <tr> 533 <td><code>dkjson.decode(obj: {...any})</code></td> 534 <td>Deserilize JSON into a Lua table.</td> 535 </tr> 536 </tbody> 537 </table> 538 <h3>Bus</h3> 539 <table> <thead> 540 <tr> 541 <th>Name</th> 542 <th>Description</th> 543 </tr> 544 </thead> 545 <tbody> 546 <tr> 547 <td><code>bus.url</code></td> 548 <td>The current url that was given.</td> 549 </tr> 550 <tr> 551 <td><code>bus.params</code></td> 552 <td>A table of url parameters if any. Ex: ?foo=bar*baz=foobar</td> 553 </tr> 554 </tbody> 555 </table> 556 <h3>Site</h3> 557 <table> <thead> 558 <tr> 559 <th>Name</th> 560 <th>Description</th> 561 </tr> 562 </thead> 563 <tbody> 564 <tr> 565 <td><code>site.version</code></td> 566 <td>The version of the website found in the Fes.toml</td> 567 </tr> 568 <tr> 569 <td><code>site.name</code></td> 570 <td>The name of the website found in the Fes.toml</td> 571 </tr> 572 <tr> 573 <td><code>site.authors</code></td> 574 <td>A table of all authors defined in Fes.toml</td> 575 </tr> 576 </tbody> 577 </table> 578 <h3>App</h3> 579 Fes's <code>app</code> module is a special table 580 because it contains user defined functions. These 581 functions are defined in the <code>include/</code> For 582 example if you define a <code>include/hello.lua</code> 583 file with given contents: <pre><code>local hello = {} 584 585 hello.render(std) return std.h1("Hello, World!") end 586 587 return hello</pre></code> This can be called from another with, 588 <code>fes.app.hello.render(fes.std)</code>. Do with this 589 as you will. 590 <h3>Speical Directories</h3> 591 <table> <thead> 592 <tr> 593 <th>Name</th> 594 <th>Description</th> 595 </tr> 596 </thead> 597 <tbody> 598 <tr> 599 <td><code>www/</code></td> 600 <td>The main website is 601 contained here, this is 602 where www/index.lua 603 lives.</td> 604 </tr> 605 <tr> 606 <td><code>static/</code></td> 607 <td>All static content should 608 be placed here and can 609 be accessed at 610 <code>/static/path-to-file</code>.</td> 611 </tr> 612 <tr> 613 <td><code>include/</code></td> 614 <td>Contains lua files that are 615 preloaded and globally 616 accessible.</td> 617 </tr> 618 <tr> 619 <td><code>archive/</code></td> 620 <td>Files here can be viewed in 621 a file browser like 622 format at 623 <code>/archive/path-to-dir</code>.</td> 624 </tr> 625 </tbody> 626 </table> 627 </section> 628 629 <footer> 630 <p>Last updated: 2025-12-27</p> 631 </footer> 632 </main> 633 </body> 634 </html>