Skip to content
ted_996 edited this page Apr 30, 2017 · 7 revisions

Frequently Asked Questions / How to do X

Preliminaries:

  • The site_root is the directory in which krait is run.
  • The site_root should contain a directory named .config and, for MVC sites, additionally, one usually named .view and directories named .ctrl and / or .py (I recommend no .ctrl, only .py)
  • The routable pages/files are the routes' targets (the files that the URL requested by the client resolve to). These are different from both Python scripts inside .py or views, or, in the context of a specific request, source files other than the original page that is run.

How to do X

  1. How to create a simple non-MVC page or css/js/png/etc file?
    You just drop any file inside site_root or any directory and it will be served, as long as there is no directory (or file) in its path with a leading dot (these pages will just 404 - use this to hide pages, such as scripts, from clients).

  2. How can I access the request from Python / the controller / etc.

    • Starting from v0.2, Krait exposes all these variables (with the exception of ctrl) in the krait module. Previously, you had to be in a routable page to access them, but now your code can be much cleaner: just import krait and use them.
    • Krait exposes the following variables in the krait module:
      • krait.request contains information about the client's request. Commonly used attributes / methods: headers, body, query, get_post_form() (but others exist)
      • ctrl is the controller assigned in MVC pages. This is available only in MVC views., and is a global variable (not in in the krait module).
      • krait.site_root is the path to the site root. It may be absolute or relative, depending on how krait was run.
      • krait.response: set it to something other than None to override the server's response from Python code.
      • krait.extra_headers: set it to something other than None to add response headers from Python code (for example, cookies, without overriding the entire response)
      • krait.content_type: set with krait.set_content_type(raw='...') or krait.set_content_type(ext='...') to change the Content-Type header from Python code (raw, or from file extension, respectively).
      • modules krait and mvc are already imported (but only in routable pages, not in your modules).
  3. How to create a simple MVC page?
    Let's say you're trying to create an MVC page at /folder/page. Obviously, a folder is not necessary, or there cand be more (like /parent/child/page)

    • First, create directories site_root/folder, site_root/.py/ctrl/folder and site_root/.view/folder if they don't exist.
    • Then, let's create the controller. Create a file named site_root/.py/ctrl/folder/page.py that contains the following code:
       import mvc
       
       class PageController(mvc.CtrlBase):
       	def __init__(self, arg1, arg2):  # args: whatever your controller needs to know to show on the page
       		self.attr1 = arg1  # set controller attributes to your arguments
       		self.attr2 = arg2
       		self.attr3 = arg1.attr3  # obviously not only arguments
       		# you can also query the DB here, anything that the controller needs to expose to the view
       	
       	def get_view(self):
       		return ".view/folder/page.html"
      
      Make get_view return whatever view you want your controller to use.
    • Then let's create the routable page. Create a file named site_root/folder/page.py that contains the following code:
       from ctrl.folder import page
       import mvc
      
       mvc.set_init_ctrl(page.PageController(arg1, arg2))  # arguments are whaterver the controller expects (for example, the request)
      
    • Then, let's create the view. Create a file named site_root/.view/folder/page.html (or whatever your controller's get_view() returns). This is an usual HTML page that can also reference variables in the controller. See the pyml syntax available here for details. The variable ctrl references the object given as an argument to mvc.set_init_ctrl() in the routable page (use like @ctrl.attr1).
      IMPORTANT: The view must set its content-type. This is achieved with the following code:
       @{krait.set_content_type(ext="html")}
      
      Add this, for example, in the <head>...</head> part.
  4. How to create a page/script accessible via POST?
    Let's say the page you are trying to access via POST is /folder/page. Add a route to .config/routes.json like this:

    [
    	... other routes ...
    	{
    		"verb": "POST",
    		"url": "/folder/page"
    	},
    	... other routes ...
    ]
    

    If the last route (entry in the JSON array) is not {} or {"verb": "GET"}, you might want to add it. This will make all your normal pages accessible (this is a default route, because it has no url or regex, it automatically matches all GET requests.)

  5. How to create a simple Python script (no client output or redirect)?
    Let's say you are trying to create a Python script at /folder/script. Just drop a file named script.py in site_root/folder and it will run anytime a client requests /folder/script. The client will receive a empty response (after HTTP headers), so this may only be useful in the context of AJAX requests.

  6. How to create a simple Python script (redirect after execution)?
    Let's say you are trying to create a Python script at /folder/script. In a file named script.py placed in the appropriate directory, run krait.response = krait.ResponseRedirect('your_destination_url') along with any scripts you'd like to run.

  7. How to create a Python script with output?
    Just create a .pyml file with a large @{ ... } block and an @expression statement at the end. If you can't change the extension, don't forget to call set_content_type(). Alternatively, instead of the @{ ... } block you can @import a Python script from a hidden folder, like .py (like this: @import ".py/subdirectory/script.py").

  8. How to use form data?

    • You use the krait.request variable set by the server.
    • For GET forms, the form is in krait.request.query. This is a Python dict, so use krait.request.query["name"] if you're sure it exists or krait.request.query.get("name") if it might not exist.
    • For POST forms, the form data is saved in the request body and must be parsed. For normal forms, use krait.request.get_post_form() (this is a dict too). For multipart forms, use krait.request.get_multipart_form() (this is a list of objects with the following fields: name, filename, content_type and data)

Clone this wiki locally