templates.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. """Templates to use in the reflex compiler."""
  2. from jinja2 import Environment, FileSystemLoader, Template
  3. from reflex import constants
  4. from reflex.utils.format import format_state_name, json_dumps
  5. class ReflexJinjaEnvironment(Environment):
  6. """The template class for jinja environment."""
  7. def __init__(self) -> None:
  8. """Set default environment."""
  9. from reflex.state import (
  10. FrontendEventExceptionState,
  11. OnLoadInternalState,
  12. State,
  13. UpdateVarsInternalState,
  14. )
  15. extensions = ["jinja2.ext.debug"]
  16. super().__init__(
  17. extensions=extensions,
  18. trim_blocks=True,
  19. lstrip_blocks=True,
  20. )
  21. self.filters["json_dumps"] = json_dumps
  22. self.filters["react_setter"] = lambda state: f"set{state.capitalize()}"
  23. self.filters["var_name"] = format_state_name
  24. self.loader = FileSystemLoader(constants.Templates.Dirs.JINJA_TEMPLATE)
  25. self.globals["const"] = {
  26. "socket": constants.CompileVars.SOCKET,
  27. "result": constants.CompileVars.RESULT,
  28. "router": constants.CompileVars.ROUTER,
  29. "event_endpoint": constants.Endpoint.EVENT.name,
  30. "events": constants.CompileVars.EVENTS,
  31. "state": constants.CompileVars.STATE,
  32. "final": constants.CompileVars.FINAL,
  33. "processing": constants.CompileVars.PROCESSING,
  34. "initial_result": {
  35. constants.CompileVars.STATE: None,
  36. constants.CompileVars.EVENTS: [],
  37. constants.CompileVars.FINAL: True,
  38. constants.CompileVars.PROCESSING: False,
  39. },
  40. "color_mode": constants.ColorMode.NAME,
  41. "resolved_color_mode": constants.ColorMode.RESOLVED_NAME,
  42. "toggle_color_mode": constants.ColorMode.TOGGLE,
  43. "set_color_mode": constants.ColorMode.SET,
  44. "use_color_mode": constants.ColorMode.USE,
  45. "hydrate": constants.CompileVars.HYDRATE,
  46. "main_state_name": State.get_name(),
  47. "on_load_internal": f"{OnLoadInternalState.get_name()}.on_load_internal",
  48. "update_vars_internal": f"{UpdateVarsInternalState.get_name()}.update_vars_internal",
  49. "frontend_exception_state": FrontendEventExceptionState.get_full_name(),
  50. }
  51. def get_template(name: str) -> Template:
  52. """Get render function that work with a template.
  53. Args:
  54. name: The template name. "/" is used as the path separator.
  55. Returns:
  56. A render function.
  57. """
  58. return ReflexJinjaEnvironment().get_template(name=name)
  59. def rxconfig():
  60. """Template for the Reflex config file.
  61. Returns:
  62. Template: The template for the Reflex config file.
  63. """
  64. return get_template("app/rxconfig.py.jinja2")
  65. def document_root():
  66. """Code to render a NextJS Document root.
  67. Returns:
  68. Template: The template for the NextJS Document root.
  69. """
  70. return get_template("web/pages/_document.js.jinja2")
  71. def app_root():
  72. """Code to render NextJS App root.
  73. Returns:
  74. Template: The template for the NextJS App root.
  75. """
  76. return get_template("web/pages/_app.js.jinja2")
  77. def theme():
  78. """Template for the theme file.
  79. Returns:
  80. Template: The template for the theme file.
  81. """
  82. return get_template("web/utils/theme.js.jinja2")
  83. def context():
  84. """Template for the context file.
  85. Returns:
  86. Template: The template for the context file.
  87. """
  88. return get_template("web/utils/context.js.jinja2")
  89. def tailwind_config():
  90. """Template for Tailwind config.
  91. Returns:
  92. Template: The template for the Tailwind config
  93. """
  94. return get_template("web/tailwind.config.js.jinja2")
  95. def component():
  96. """Template to render a component tag.
  97. Returns:
  98. Template: The template for the component tag.
  99. """
  100. return get_template("web/pages/component.js.jinja2")
  101. def page():
  102. """Code to render a single NextJS page.
  103. Returns:
  104. Template: The template for the NextJS page.
  105. """
  106. return get_template("web/pages/index.js.jinja2")
  107. def components():
  108. """Code to render the custom components page.
  109. Returns:
  110. Template: The template for the custom components page.
  111. """
  112. return get_template("web/pages/custom_component.js.jinja2")
  113. def stateful_component():
  114. """Code to render Component instances as part of StatefulComponent.
  115. Returns:
  116. Template: The template for the StatefulComponent.
  117. """
  118. return get_template("web/pages/stateful_component.js.jinja2")
  119. def stateful_components():
  120. """Code to render StatefulComponent to an external file to be shared.
  121. Returns:
  122. Template: The template for the StatefulComponent.
  123. """
  124. return get_template("web/pages/stateful_components.js.jinja2")
  125. def sitemap_config():
  126. """Sitemap config file.
  127. Returns:
  128. Template: The template for the sitemap config file.
  129. """
  130. return "module.exports = {config}".format
  131. def style():
  132. """Code to render the root stylesheet.
  133. Returns:
  134. Template: The template for the root stylesheet
  135. """
  136. return get_template("web/styles/styles.css.jinja2")
  137. def package_json():
  138. """Code that generate the package json file.
  139. Returns:
  140. Template: The template for the package json file
  141. """
  142. return get_template("web/package.json.jinja2")
  143. def custom_components_pyproject_toml():
  144. """Code that generate the pyproject.toml file for custom components.
  145. Returns:
  146. Template: The template for the pyproject.toml file
  147. """
  148. return get_template("custom_components/pyproject.toml.jinja2")
  149. def custom_components_readme():
  150. """Code that generates the README file for custom components.
  151. Returns:
  152. Template: The template for the README file
  153. """
  154. return get_template("custom_components/README.md.jinja2")
  155. def custom_components_source():
  156. """Code that generates the source file for custom components.
  157. Returns:
  158. Template: The template for the source file
  159. """
  160. return get_template("custom_components/src.py.jinja2")
  161. def custom_components_init():
  162. """Code that generates the init file for custom components.
  163. Returns:
  164. Template: The template for the init file
  165. """
  166. return get_template("custom_components/__init__.py.jinja2")
  167. def custom_components_demo_app():
  168. """Code that generates the demo app main py file for testing custom components.
  169. Returns:
  170. Template: The template for the demo app main py file
  171. """
  172. return get_template("custom_components/demo_app.py.jinja2")