Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
Katalis
https://github.com/zendbit/katalis
Admin
Katalis is nim lang micro web framework
Tokens:
8,515
Snippets:
44
Trust Score:
8.6
License:
MIT
Update:
1 year ago
Context
Chat
Benchmark
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Install Katalis from GitHub URL Source: https://github.com/zendbit/katalis/blob/main/README.md Installs the Katalis framework directly from its GitHub repository URL using Nimble. ```bash nimble install https://github.com/zendbit/katalis ``` -------------------------------- ### Install Katalis using Nimble Source: https://github.com/zendbit/katalis/blob/main/README.md Installs the Katalis framework using the default Nimble package directory. ```bash nimble install katalis ``` -------------------------------- ### Defining Katalis App Structure and Routes (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Shows the basic structure of a Katalis application using the @!App macro, including optional blocks like @!EndPoint, @!Before, @!After, @!OnReply, @!Cleanup, and examples of defining routes using HTTP method macros (@!Post, @!Get, @![Get, Post]). ```Nim @!App: ## endpoint optional, this endpoint prefix path will append to each route path request ## this is optional, and should be define before all other pipeline @!EndPoint "/test/api" ## before route block @!Before: ## code here ## after route block @!After: ## code here ## on reply block @!OnReply: ## code here ## cleanup block @!Cleanup: ## code here ## routing ## available method @!Get, @!Post, @!Put, @!Delete, @!Patch, @!Head, @!Connect, @!Options, @!Trace @!Post "/register": ## code here @!Get "/home": ## code here ## also support for multiple method on routing @![Get, Post] "/login": ## code here ``` -------------------------------- ### Creating Directory Structure for Static Files (Bash) Source: https://github.com/zendbit/katalis/blob/main/README.md Provides Bash commands to create the necessary directory structure (servestatic-example and static) for serving static files in the example. ```Bash mkdir servestatic-example cd servestatic-example mkdir static ``` -------------------------------- ### Compile and Run Katalis with Threads (Bash) Source: https://github.com/zendbit/katalis/blob/main/README.md Explains how to compile and run the `app.nim` file using the Nim compiler, enabling thread support with `--threads:on` and running it directly with `-r`. This is the standard way to start the application. ```bash nim c -r --threads:on app.nim ``` -------------------------------- ### Configuring Katalis Settings (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Demonstrates how to configure global application settings in Katalis using the @!Settings macro, showing examples for setting the address and port. It also lists available settings with their default values. ```Nim @!Settings.address = "0.0.0.0" ## default @!Settings.port = Port(8000) ## default ``` -------------------------------- ### Creating Middleware with Before/After Pipelines in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Provides an example of implementing middleware logic by defining a separate procedure (middlewareHandler) and calling it from the @!Before or @!After pipeline blocks to perform checks (like authentication/authorization) before or after route handling. ```Nim proc middlewareHandler(ctx: HttpContext, env: Environment): Future[bool] {.async.} = ## \ ## ## return bool: ## return true if something happend and want to skip all process ## ## ctx == @!Context ## env == @!Env ## ## for example we want to check if user already login or not ## if not login then just skip all process with return true if ($ @!Req.uri).contains("/admin") and not checkIfUserIsLoginAndIsAdmin: ## if request path start with /admin , and user is not admin we need to denied the access ## then redirect to login page await @!Context.replyRedirect("/login") ## don't forget to return true to make sure rest of route not accessible and break the route pipeline ## for unwanted access result = true @!App: ## you can do in @!Before or @!After @!Before: ## ## this block will always execute and check before route process ## you can check every thing here ## ## you can call here await @!Context.middlewareHandler(@!Env) @!After: ## ## this block will always execute and check after route process ## right before execute POST, GET ## you can check every thing here ## or you can also call here await @!Context.middlewareHandler(@!Env) ``` -------------------------------- ### Defining Katalis Routes and Handlers (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Demonstrates how to define routes using @!App and @!Get, set endpoint prefixes with @!EndPoint, capture URL segments and query strings, handle multiple HTTP methods, process form data, and reply with content or rendered templates using the Katalis framework. ```Nim import katalis/katalisApp import katalis/plugins/nimMustache @!Settings.enableServeStatic = true @!Settings.enableKeepAlive = true @!App: ## we can also create prefix for all routes @!EndPoint "/admin" ## \ ## all routes will prefixed with /admin/ ## get request for default / ## in this case, because we already set @!EndPoint to "/admin" ## so the route url will be http://localhost:8000/admin @!Get "/": await @!Context.reply(Http200, "<h1>This is admin the root page!") ## another get example ## http://localhost:8000/hello @!Get "/hello": await @!Context.reply(Http200, "<h1>world!</h1>") ## mapping route, retrieve segment to variable @!Get "/birthdate/:month/:day/:year": ## this will retrieve segments ## as variable month, day, and year ## http://localhost/admin/birthdate/may/22/2000 let birthdate = [@!Segment["month"], @!Segment["day"], @!Segment["year"]].join("/") await @!Context.reply( Http200, &"<h3>Birthdate</h3> <p>{birthdate}</p>" ) ## mapping route, retrieve query string to variable @!Get "/birthdate": ## this will retrieve query string ## as variable month, day, and year ## http://localhost/admin/birthdate?month=may&day=22&year=2000 let birthdate = [@!Query.getOrDefault("month"), @!Query.getOrDefault("day"), @!Query.getOrDefault("year")].join("/") await @!Context.reply( Http200, &"<h3>Birthdate</h3> <p>{birthdate}</p>" ) ## mapping route, retrieve segment as regex pattern @!Get "/birthdate/re<:month([a-zA-Z]+)_:day([0-9]+)_:year([0-9]+)>": ## this will retrieve query string ## as variable month, day, and year ## http://localhost/admin/birthdate/may_22_2000 let birthdate = [@!Segment.getOrDefault("month"), @!Segment.getOrDefault("day"), @!Segment.getOrDefault("year")].join("/") await @!Context.reply( Http200, &"<h3>Birthdate</h3> <p>{birthdate}</p>" ) ## we also can have multiple method ## in one route definition @![Get, Post] "/login": ## we can use validation to check fields ## but for validation details we will discuss in other section ## about validation ## let get form data username, password ## if method http post validate the form data let username = @!Form.data.getOrDefault("username") let password = @!Form.data.getOrDefault("password") var errorMsg = "" if @!Req.httpMethod == HttpPost: if username == "" or password == "": errorMsg = "username or password is required!" ## ## katalis come with mustache template engine ## for template engine we will explain later ## let tpl = """ <html> <head> <title>example</title> </head> <body> <h3>Login</h3> <form method="POST"> <input type="text" name="username" placeholder="username" value="{{username}}"> <br> <input type="password" name="password" placeholder="password" value="{{password}}"> <br> <input type="submit" value="Login"> </form> <h4>{{errorMsg}}</h4> </body> </html> """ let m = newMustache() m.data["errorMsg"] = errorMsg m.data["username"] = username m.data["password"] = password @!Context.reply(Http200, m.render(tpl)) ## we can have multiple @!App for routes separation @!App: ## let definde endpoint for users @!EndPoint "/user" ## the user root page ## http://localhost:8000/user @!Get "/": await @!Context.reply(Http200, "<h1>This is user root page</h1>") @!Emit ``` -------------------------------- ### Handle Reply Message - Katalis - Nim Source: https://github.com/zendbit/katalis/blob/main/README.md This example shows how to use the universal response message feature in Katalis. It defines a GET route that replies with a structured JSON response using `newReplyMsg`, setting the HTTP status code, success status, data payload, and an empty error object. ```Nim @!App: @!Get "/test-replymsg": ## see core katalis/core/replyMsg.nim @!Context.reply(newReplyMsg( httpCode = Http200, success = true, data = %*{ "username": "tian", "address": "Guangdong" }, error = %*{} )) ``` -------------------------------- ### Default Katalis Server Output (Bash) Source: https://github.com/zendbit/katalis/blob/main/README.md Shows the default output message displayed in the console when the Katalis application successfully starts, indicating the network interface and port it is listening on for incoming HTTP connections. ```bash Listening non secure (plain) on http://0.0.0.0:8000 ``` -------------------------------- ### Implementing Mustache Rendering Route in Nim Source: https://github.com/zendbit/katalis/blob/main/README.md Sets up a GET route '/test-mustache' in the Katalis application. It initializes a Mustache engine, populates data using a JsonNode, and renders the 'index.mustache' template, sending the result as an HTTP 200 response. ```Nim @!App: @!Get "/test-mustache": let m = newMustache() m.data["post"] = %*{"title": "This is katalis", "article": "This is just simple micro framework but powerfull!"} ## call the index.mustache in the templates folder await @!Context.reply(Http200, m.render("index")) ``` -------------------------------- ### Implementing Server-Sent Events (SSE) Routes in Nim Source: https://github.com/zendbit/katalis/blob/main/README.md Sets up two GET routes for SSE: '/test-sse' serves an HTML page with embedded JavaScript to initiate an SSE connection, and '/test-sse-event' provides the actual event stream, sending messages to connected clients. ```Nim ## test sse @!Get "/test-sse": ## \ ## page template for html sse example let tpl = """ <html> <head> <title>example sse</title> </head> <body> <h4>Test sse</h4> </body> <ul id="list"> </ul> <script> document.addEventListener("DOMContentLoaded", function(e) { const evtSource = new EventSource( "/test-sse-event" ) evtSource.onmessage = (event) => { const newElement = document.createElement("li") const eventList = document.getElementById("list") newElement.textContent = `message: ${event.data}` eventList.appendChild(newElement) } }) </script> </html> """ let v = newMustache() @!Context.reply(Http200, v.render(tpl)) @!Get "/test-sse-event": ## \ ## this is event listen by sse event await @!Context.replyEventStream(Http200, "message from server..") ## default sse using message as default event name ## if you want to using custom name event pass the event name ## ## await @!Context.replyEventStream(Http200, "message from server..", event: "data") ## ``` -------------------------------- ### Handling Query String Request with Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Demonstrates how to handle query string parameters in a GET request using Katalis. It retrieves 'city' and 'province' parameters from the URL using `@!Query.getOrDefault` and includes them in the HTTP response. Requires the `katalisApp` module. ```Nim import katalis/katalisApp @!Settings.enableServeStatic = true @!Settings.enableKeepAlive = true @!App: @!Get "/test-qs": ## lets do query string test ## http://localhost:8000/test-qs?city=ngawi&province=surabaya with get method let city = @!Query.getOrDefault("city") let province = @!Query.getOrDefault("province") @!Context.reply(Http200, &"<h3>Welcome to {province}, {city}.</h3>") ``` -------------------------------- ### Implement Request Validation - Katalis - Nim Source: https://github.com/zendbit/katalis/blob/main/README.md This snippet demonstrates how to use the built-in validation plugin in Katalis. It defines a route that handles both GET and POST requests, renders an HTML form using Mustache, and on POST, validates the 'username' and 'password' fields using various rules like `isRequired`, `minLength`, `maxLength`, and `matchWith` (regex). It then populates the Mustache template context with validation results. ```Nim @!App: @![Get, Post] "/test-validation": ## validation is plugins on katalis ## see katalis/plugins/validation.nim let tpl = """ <html> <head><title>validation test</title></head> <body> <form method="POST"> <label>Username<label> <span>{{username.msg}}</span> <br> <input type="text" name="username" value="{{username.value}}"> <br> <br> <label>Password</label> <span>{{password.msg}}</span> <br> <input type="password" name="password" value="{{password.value}}"> <br> <br> <input type="submit" value="Register"> </form> </body> </html> """ ## mustache template let m = newMustache() if @!Req.httpMethod == HttpPost: ## parameter can be Form, JsonNode or Table[string, string] type let v = newValidation(@!Form) v.withField("username"). isRequired(failedMsg = "Username is empty."). ## we can add custom failedMsg minLength(8). ## minimum length of field value is 8 char length maxLength(50). ## maximum length of field value is 50 char length matchWith("([a-zA-Z0-9_]+)$", failedMsg = "Only a-z A-Z 0-9 _ are allowed") ## check with regex, only allow a-z A-Z 0-9 _ v.withField("password"). isRequired(failedMsg = "Password is empty."). ## we can add custom failedMsg minLength(8). ## minimum length 8 char length maxLength(254) ## maximum length 254 char length ## we can check validation result for each field ## lets print to console echo "username " & v.fields["username"].msg & " -> " & $v.fields["username"].isValid echo "password " & v.fields["password"].msg & " -> " & $v.fields["password"].isValid ## set mustache context send data to template for fieldName, fieldData in v.fields: m.data[fieldName] = %fieldData @!Context.reply(Http200, m.render(tpl)) ``` -------------------------------- ### Create a Simple Katalis 'Hello World' App Source: https://github.com/zendbit/katalis/blob/main/README.md Demonstrates a basic Katalis application with configuration settings and a root route ('/') that replies with 'Hello World!'. It uses Katalis's DSL macros prefixed with `@!`. ```nim import katalis/katalisApp ## lets do some basics configuration @!Settings.enableServeStatic = true @!Settings.enableKeepAlive = true ## we also can use custom port #@!Settings.port = Port(8080) ## lets start simple app @!App: @!Get "/": @!Context.reply(Http200, "<h1>Hello World!.</h1>") ``` -------------------------------- ### Create and Navigate to Application Directory Source: https://github.com/zendbit/katalis/blob/main/README.md Creates a new directory for the application and changes the current directory to it. ```bash mkdir simpleapp cd simpleapp ``` -------------------------------- ### Serving Individual Static Files (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Shows how to serve specific files as responses to individual routes within a Katalis application using the @!Context.replySendFile macro. ```Nim @!App: @!Get "/my-picture-profile": @!Context.replySendFile("my-profile-image.png".Path) @!Get "/my-funny-video": @!Context.replySendFile("funny-video.mp4".Path) ``` -------------------------------- ### Compile and Run Katalis with Chronos Backend (Bash) Source: https://github.com/zendbit/katalis/blob/main/README.md Explains how to compile and run the `app.nim` file using the Nim compiler, enabling thread support and specifying the `chronos` async backend using `-d:asyncBackend=chronos`. This option is used when integrating with the chronos async/await framework. ```bash nim c -r --thread:on -d:asyncBackend=chronos app.nim ``` -------------------------------- ### Creating Templates Directory in Bash Source: https://github.com/zendbit/katalis/blob/main/README.md Uses the bash command 'mkdir' to create a directory named 'templates' in the project root, which is typically used to store template files. ```Bash mkdir templates ``` -------------------------------- ### Enabling Global Static File Serving (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Shows the minimal Katalis application code required to enable serving static files from the designated static directory by setting @!Settings.enableServeStatic to true and including the @!Emit macro. ```Nim import katalis/katalisApp ## enable static file service @!Settings.enableServeStatic = true @!Settings.enableKeepAlive = true @!Emit ``` -------------------------------- ### Compiling and Running Katalis App (Bash) Source: https://github.com/zendbit/katalis/blob/main/README.md Provides the Bash command to compile and run the Katalis application written in Nim using the Nim compiler. ```Bash nim c -r app.nim ``` -------------------------------- ### Implementing WebSocket Route in Nim Source: https://github.com/zendbit/katalis/blob/main/README.md Sets up a WebSocket route '/ws' in the Katalis application. It demonstrates handling incoming text and binary messages, checking for continuation frames, and sending a text reply back to the client. ```Nim @!App: ## it will accessed with ws://localhost:8000/ws @!WebSocket "/ws": if @!WebSocket.isOpen: if @!WebSocket.isRecvText: if not @!WebSocket.isRecvContinuation: ## \ ## handle msg without continuation flag echo @!WebSocket.recvMsg ## \ ## recieve message from client await @!WebSocket.replyText("This is from end point.") ## \ ## send message to client ## for continuation text use ## await @!WebSocket.replyTextContinuation("data") ## \ ## for send binary use ## await @!WebSocket.replyBinary("data") ## for send binary continuation use ## await @!WebSocket.replyBinaryContinuation("data") else: ## \ ## handle msg with continuation flag echo @!WebSocket.recvMsg echo "handle with continuation message here" if @!WebSocket.isRecvBinary: ## \ ## recv binary msg if not @!WebSocket.isRecvContinuation: ## \ ## handle msg without continuation flag echo @!WebSocket.recvMsg else: ## \ ## handle msg with continuation flag echo @!WebSocket.recvMsg echo "handle with continuation message here" if @!WebSocket.isClose: if @!WebSocket.isError: echo @!WebSocket.errMsg echo "Closed" ``` -------------------------------- ### Implementing OnReply Pipeline for Compression in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Shows how to use the @!OnReply pipeline in Katalis to modify the response before it's sent to the client, specifically demonstrating how to check for client gzip support and compress the response body using the zippy library. ```Nim ## ## katalis framework ## This framework if free to use and to modify ## License: MIT ## Author: Amru Rosyada ## Email: amru.rosyada@gmail.com, amru.rosyada@amscloud.co.id ## Git: https://github.com/zendbit/katalis ## ## ## add pipeline on onreply ## check if client support compression then compress ## import zippy import ../../core/routes, ../../macros/sugar, ../../core/environment @!App: @!OnReply: # if client support gzip # and enableCompression enabled if "gzip" in @!Req.headers.getValues("accept-encoding") and @!Settings.enableCompression: @!Res.headers["content-encoding"] = "gzip" @!Res.body = compress(@!Res.body, BestSpeed, dfGzip) ``` -------------------------------- ### Compiling Katalis App for CGI (Bash) Source: https://github.com/zendbit/katalis/blob/main/README.md This bash command shows how to compile a Katalis application specifically for deployment on shared hosting environments that support the Common Gateway Interface (CGI). The `-d:cgiapp` flag enables the CGI compilation mode. ```bash nnim c app.nim ``` -------------------------------- ### Import Katalis Application Module Source: https://github.com/zendbit/katalis/blob/main/README.md Imports the main Katalis application module (`katalisApp`) required to build web applications. ```nim import katalis/katalisApp ``` -------------------------------- ### Defining Stand-alone Route Handlers in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Illustrates how to create separate Nim procedures to handle route logic, improving code organization. It shows how handlers can accept the HttpContext, the Environment, or custom parameters, and how to call these handlers from within the @!App block. ```Nim proc testHandler(ctx: HttpContext) {.async.} = ## ctx == @!Context await @!Context.reply(Http200, "hello") ## if you want to pass environment to handler you can add more option to it proc testHandler(ctx: HttpContext, env: Environment) {.async.} = ## ctx == @!Context ## env == @!Env await @!Context.reply(Http200, "handler with env") ## pass other param is also straight forward proc testHandler(ctx: HttpContext, myCarsBrand: seq[string]) {.async.} = ## ctx == @!Context await @!Context.reply(Http200, "handler with custom param") @!App: @!Get "/test-handler": await @!Context.testHandler @!Get "/test-handler-1": await @!Context.testHandler(@!Env) @!Get "/test-handler-2": await @!Context.testHandler(@["Toyota", "Ferrari", "Ford"]) ``` -------------------------------- ### Implementing Before Pipeline in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Shows how to define a @!Before pipeline block in Katalis, which executes before route processing and static file serving, allowing for checks or actions that can halt the request pipeline by returning true. ```Nim @!App: @!Before: ## your code here if something_wrong: @!Context.reply(Http403, "Anauthorized access!") ## by returning true, will skip all process and return the error message, this is simplify for checking return true ``` -------------------------------- ### Handling Redirects in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Demonstrates various methods for implementing HTTP redirects in the Katalis framework, including setting the 'Location' header manually and using built-in helper functions for temporary (307) and permanent (308) redirects. ```Nim @!App: @!Get "/home": @!Context.reply(Http200, "<h3>Welcome home!</h3>") @!Get "/test-redirect-custom": @!Res.headers["Location"] = "/home" # # Http302, Http301, Http308, Http303, Http307 # see https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Redirections # @!Context.reply(Http307, "") @!Get "/test-redirect-temporary": # http code 307 @!Context.replyRedirect("/home") @!Get "/test-redirect-permanent": ## http code 308 @!Context.replyPermanentRedirect("/home") ``` -------------------------------- ### Configuring SSL Settings in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md This snippet demonstrates how to configure SSL settings within a Katalis application using the `sslSettings` object. It shows how to specify the certificate and key file paths, set the port, and control certificate verification. ```nim @!Settings.sslSettings = newSslSettings( certFile = "domain.crt".Path, keyFile = "domain.key".Path, port = Port(8443), ## default value enableVerify = false ## set to true if using production and valid ssl certificate ) ``` -------------------------------- ### Global Katalis DSL Macros (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Lists the Katalis Domain Specific Language (DSL) macros that are available for use outside of the `@!App` block. These macros provide simplified access to core Katalis components like settings, routes, and environment. ```nim ## available on global ## @!Settings ## @!Emit -> Should called after @!App block ## @!Route ## @!Katalis ## @!Environment ## @!SharedEnv ## @!Trace ``` -------------------------------- ### Handling File Uploads with Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Shows how to handle file uploads using multipart form data in Katalis. The route serves an HTML form for uploads and processes submitted files via `@!Form.files`, printing their info and moving them to an 'uploaded' directory. Requires the `katalisApp` module and Nim's `os` stdlib for file operations. ```Nim import katalis/katalisApp import std/os @!Settings.enableServeStatic = true @!Settings.enableKeepAlive = true @!App: @![Get, Post] "/test-upload": ## lets do upload multipart data ## katalis come with mustache template engine ## for template engine we will explain later ## let tpl = """ <html> <head> <title>upload test</title> </head> <body> <h3>Upload files</h3> <form method="POST" enctype="multipart/form-data"> Upload Single <br> <input name="onefile" type="file" /> <br> <br> Upload Multiple <br> <input name="multiplefiles[]" type="file" multiple /> <br> <br> <button type="submit">Upload</button> </form> </body> </html> """ if @!Req.httpMethod == HttpPost: ## test show uploaded file info to console if @!Form.files.len != 0: for name, files in @!Form.files: echo name for file in files: echo file.path echo file.mimetype echo file.isAccessible echo file.name ## create directory uploaded if not exist if not "uploaded".dirExists: "uploaded".createDir ## check if files exists if "onefile" in @!Form.files: let onefile = @!Form.files["onefile"][0] ## move files to uploaded dir onefile.path.moveFile("uploaded".Path/onefile.Path) if "multiplefiles" in @!Form.files: let multiplefiles = @!Form.files["multiplefiles"] for file in multiplefiles: ## move files to uploaded dir file.path.moveFile("uploaded"/file.name.Path) let m = newMustache() @!Context.reply(Http200, m.render(tpl)) ``` -------------------------------- ### Implementing After Pipeline in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Demonstrates how to define an @!After pipeline block in Katalis, which executes after route processing and static file serving, allowing for post-processing actions or checks that can modify the response or halt further processing by returning true. ```Nim @!App: @!After: ## your code here if something_wrong: @!Res.headers["Location"] = "/home" @!Context.reply(Http307, "") ## return true for skip all routing definition return true ``` -------------------------------- ### Defining Mustache Index Template with Partials Source: https://github.com/zendbit/katalis/blob/main/README.md Defines the main HTML structure for the index page. It demonstrates data binding using `{{tag}}` and includes the 'header' and 'footer' partials using `{{> partial_name}}`. ```Mustache <html> <head><title>mustache example</title></head> <body> <div> {{> header}} <div> <h3>This is content section<h3> <h3>{{post.title}}</h3> <p>{{post.article}}</p> </div> {{> footer}} </div> </body> </html> ``` -------------------------------- ### Managing Cookie Sessions in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Illustrates how to initialize and interact with cookie-based sessions in Katalis, showing how to add, retrieve, and manage session data, emphasizing that session values must be JsonNode types. ```Nim @!App: ## init cookie session @!Before: await @!Context.initCookieSession() @!Get "/hello": await @!Context.addCookieSession("name", %"Tian Long") ## \ ## addCookieSession value must JsonNode ## example ## addCookieSession("profile", %*{"username": "tianlong", "email": "tianlong@mail.com"}) ## addCookieSession("brand", %["Toyota", "Ford", "BYD"]) ## addCookieSession("counter", %0) ## addCookieSession("temperature", %0.5) ## etc ## let name = await @!Context.getCookieSession("name") ## remove individual session with @!Context.deleteCookieSession("name") ## destroy all session value with @!Context.destroyCookieSession() await @!Context.reply(Http200, &"Hello {name}!") ``` -------------------------------- ### Defining CGI Routes and Conditional Code (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md This Nim snippet illustrates how routing works in Katalis when compiled for CGI (`-d:cgiapp`). Routes are mapped using the `?uri=` query parameter. It also shows how to use the `when not CgiApp:` compile-time check to exclude features like WebSockets that are not supported in CGI mode. ```nim @!App: ## this mean we need to call using ?uri=/admin ## for full url example https://mydomain/cgi/app?uri=/admin @!Get "/admin": CODE_GOES_HERE ## this mean we need to call using ?uri=/user ## for full url example https://mydomain/cgi/app?uri=/user @!Get "/user": CODE_GOES_HERE ## this mean we need to call using ?uri=/user/add ## for full url example https://mydomain/cgi/app?uri=/user/add @!Get "/user/add": CODE_GOES_HERE ## if your code implementation not supported in CgiApp mode ## then use CgiApp as compile time checking to discard the code on compile time when not CgiApp: ## thi only work on katlais full framework @!WebSocket "/chatbots": CODE_GOES_HERE @Emit ``` -------------------------------- ### Logging Messages and Conditional Compilation in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md This snippet illustrates how to log messages to the Katalis log file using the `putLog` procedure, showing both async (`await`) and non-async (`waitFor`) usage. It also demonstrates using the `IsReleaseMode` constant for conditional compilation based on the `-d:release` flag. ```Nim import katalis/utils/debug ## add to debug log file await putLog("your message log") ## or for non async use waitFor waitFor putLog("your message log") ## also you can use switcher for debugging and production level ## by passing -d:release on compile time ## and we can use IsReleaseMode for selector import katalis/core/constants when IsReleaseMode: AVAILABLE_ON_RELEASE_MODE else: AVAILABLE_ON_DEBUG_MODE ``` -------------------------------- ### Handling XML Data with Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Demonstrates how Katalis parses incoming XML request bodies into Nim's `XmlNode` via `@!Xml`. The code accesses the parsed XML, adds a 'Country' element using `newElement` and `newText`, and replies with the modified XML data using `replyXml`. Requires the `katalisApp` module and relies on Nim's `xmltree` stdlib. ```Nim import katalis/katalisApp @!Settings.enableServeStatic = true @!Settings.enableKeepAlive = true @!App: @!Post "/test-xml": ## lets do xml test ## http://localhost:8000/test-xml with post method let data = @!Xml ## \ ## xml data from client request ## all data will convert to nim stdlib XmlNode ## see https://nim-lang.org/docs/xmltree.html ## ## Try to send data using this xml format ## <Address> ## <City>Ngawi</City> ## <Province>Surabaya</Province> ## </Address> ## ## lets modify the data add country let country = newElement("Country") country.add(newText("Indonesia")) data.add(country) ## katalis will automatic response as xml if we pass XmlNode ## lets pass XmlNode from client and we modify it await @!Context.replyXml(Http200, data) ## this is also valid will automatic handle XmlNode ## await @!Context.reply(Http200, data) ``` -------------------------------- ### Defining Mustache Footer Partial Source: https://github.com/zendbit/katalis/blob/main/README.md Defines a simple HTML structure for a footer section. This file ('footer.mustache') is intended to be included as a partial in other Mustache templates. ```Mustache <div> <h3>This is footer section<h3> </div> ``` -------------------------------- ### Importing Mustache Plugin in Nim Source: https://github.com/zendbit/katalis/blob/main/README.md Imports the necessary Katalis plugin for using the Mustache template engine, allowing access to its functions and types. ```Nim import katalis/plugins/nimMustache ``` -------------------------------- ### Enable Debug Trace in Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md This snippet shows how to enable the trace debugging feature in Katalis by setting the `enableTrace` flag in the `Settings` object to `true`. This allows for more detailed output during development. ```Nim @!Settings.enableTrace = true ``` -------------------------------- ### Defining Mustache Header Partial Source: https://github.com/zendbit/katalis/blob/main/README.md Defines a simple HTML structure for a header section. This file ('header.mustache') is intended to be included as a partial in other Mustache templates. ```Mustache <div> <h3>This is header section<h3> </div> ``` -------------------------------- ### Handling Form Data with Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Shows how to process form data submitted via a POST request in Katalis. It accesses 'city' and 'province' fields from the form data using `@!Form.data.getOrDefault` and uses them in the HTTP response. Requires the `katalisApp` module. ```Nim import katalis/katalisApp @!Settings.enableServeStatic = true @!Settings.enableKeepAlive = true @!App: @!Post "/test-form": ## lets do form test ## http://localhost:8000/test-form with post method let city = @!Form.data.getOrDefault("city") let province = @!Form.data.getOrDefault("province") @!Context.reply(Http200, &"<h3>Welcome to {province}, {city}.</h3>") ``` -------------------------------- ### Cleanup Request Cache - Katalis - Nim Source: https://github.com/zendbit/katalis/blob/main/README.md This code snippet demonstrates how to implement a cleanup routine within the Katalis framework. It checks for and removes temporary files associated with the request body and uploaded files in form data, finally clearing the HTTP context. ```Nim @!App: @!Cleanup: if @!Req.body.fileExists: @!Req.body.removeFile if @!Req.param.form.files.len != 0: ## remove file after file uploaded ## uploaded file should be move after finished ## file uploaded before cleanup present for _, files in @!Req.param.form.files: for file in files: if not file.isAccessible or not file.path.fileExists: continue file.path.removeFile ## clear http context @!Context.clear ``` -------------------------------- ### Handling JSON Data with Katalis (Nim) Source: https://github.com/zendbit/katalis/blob/main/README.md Illustrates how Katalis automatically parses incoming JSON request bodies into Nim's `JsonNode` via `@!Json`. The snippet accesses the parsed JSON, adds a 'country' field, and replies with the modified JSON data using `replyJson`. Requires the `katalisApp` module and relies on Nim's `json` stdlib. ```Nim import katalis/katalisApp @!Settings.enableServeStatic = true @!Settings.enableKeepAlive = true @!App: @!Post "/test-json": ## lets do json test ## http://localhost:8000/test-json with post method let data = @!Json ## \ ## json data from client request ## all data will convert to nim stdlib JsonNode ## see https://nim-lang.org/docs/json.html ## lets modify the data add country to json data["country"] = %"indonesia" ## katalis will automatic response as json if we pass JsonNode ## lets pass JsonNode from client and we modify it await @!Context.replyJson(Http200, data) ## this is also valid will automatic handle JsonNode ## await @!Context.reply(Http200, data) ```