Alex | b78191f | 2021-11-02 16:35:46 -0500 | [diff] [blame] | 1 | # https://github.com/myusko/falcon-jinja |
| 2 | import falcon |
| 3 | from falcon.response import Response |
| 4 | from jinja2 import Environment, FileSystemLoader |
| 5 | from jinja2.exceptions import TemplateNotFound |
| 6 | |
| 7 | __all__ = ['FalconTemplate'] |
| 8 | |
| 9 | |
| 10 | class FalconTemplateNotFound(Exception): |
| 11 | pass |
| 12 | |
| 13 | |
| 14 | class FalconTemplate: |
| 15 | """ |
| 16 | Args: |
| 17 | path (str): Name of an directory where HTML files defined. |
| 18 | Attributes: |
| 19 | _env (jinja2.Environment): Jinja component which shared |
| 20 | variables like configuration and etc. |
| 21 | template_path (str): Name of folder where all |
| 22 | HTML files are defined. |
| 23 | loader (jinja2.FileSystemLoader): Jinja2 class which loaded |
| 24 | HTML template from filesystem. |
| 25 | """ |
| 26 | |
| 27 | BASE_FOLDER = 'templates' |
| 28 | |
| 29 | def __init__(self, path: str = None): |
| 30 | self.template_path = path or self.BASE_FOLDER |
| 31 | self.loader = FileSystemLoader(self.template_path) |
| 32 | self._env = Environment(loader=self.loader) |
| 33 | |
| 34 | @staticmethod |
| 35 | def __get_response(objects: tuple): |
| 36 | """Retrieve falcon's Response object |
| 37 | Args: |
| 38 | objects (tuple): An list with falcon.Request, |
| 39 | falcon.Response, and other arguments. |
| 40 | Returns: |
| 41 | An falcon.Response object if it there |
| 42 | otherwise False. |
| 43 | """ |
| 44 | for response in objects: |
| 45 | if isinstance(response, Response): |
| 46 | return response |
| 47 | return False |
| 48 | |
| 49 | def _make_template(self, template: str, context: dict): |
| 50 | """Makes a jinja template, and rendered passed context |
| 51 | Args: |
| 52 | template (str): Name of HTML file which will be rendered. |
| 53 | context (dict): An dictionary with |
| 54 | a response context. |
| 55 | Returns: |
| 56 | A string representation of HTML content |
| 57 | """ |
| 58 | try: |
| 59 | template = self._env.get_template(template) |
| 60 | except TemplateNotFound: |
| 61 | raise FalconTemplateNotFound( |
| 62 | 'Template {} not found ' |
| 63 | 'in {} folder'.format(template, self.template_path) |
| 64 | ) |
| 65 | return template.render(**context) |
| 66 | |
| 67 | def render(self, template: str): |
| 68 | """Decorator which renders HTML content |
| 69 | Args: |
| 70 | template (str): HTML file for which will |
| 71 | be rendered HTML content |
| 72 | """ |
| 73 | def render_template(func): |
| 74 | def wrapper(*args, **kwargs): |
| 75 | |
| 76 | response = self.__get_response(args) |
| 77 | func(*args, **kwargs) |
| 78 | |
| 79 | response.content_type = falcon.MEDIA_HTML |
| 80 | response.status = falcon.HTTP_200 |
| 81 | response.body = self._make_template( |
| 82 | template, response.context |
| 83 | ) |
| 84 | return wrapper |
| 85 | return render_template |