| 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 |