Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

249 lignes
7.2 KiB

  1. # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. from __future__ import unicode_literals
  4. import frappe
  5. from frappe.utils import now
  6. from frappe.model.document import Document
  7. from frappe.model.naming import append_number_if_name_exists
  8. from frappe.website.utils import cleanup_page_name, get_home_page
  9. from frappe.website.render import clear_cache
  10. from frappe.modules import get_module_name
  11. from frappe.website.router import get_page_route
  12. class WebsiteGenerator(Document):
  13. website = frappe._dict(
  14. page_title_field = "name"
  15. )
  16. def autoname(self):
  17. if self.meta.autoname != "hash":
  18. self.name = self.get_page_name()
  19. append_number_if_name_exists(self)
  20. def onload(self):
  21. self.get("__onload").update({
  22. "is_website_generator": True,
  23. "website_route": self.get_route(),
  24. "published": self.website_published()
  25. })
  26. def validate(self):
  27. self.set_parent_website_route()
  28. if not self.page_name:
  29. self.page_name = self.make_page_name()
  30. if self.meta.get_field("page_name") and not self.get("__islocal"):
  31. current_route = self.get_route()
  32. current_page_name = self.page_name
  33. # page name changed, rename everything
  34. if current_page_name and current_page_name != self.page_name:
  35. self.update_routes_of_descendants(current_route)
  36. def on_update(self):
  37. clear_cache(self.get_route())
  38. if getattr(self, "save_versions", False):
  39. frappe.add_version(self)
  40. def get_route(self, doc = None):
  41. self.get_page_name()
  42. return make_route(self)
  43. def clear_cache(self):
  44. clear_cache(self.get_route())
  45. def get_page_name(self):
  46. return self.get_or_make_page_name()
  47. def get_or_make_page_name(self):
  48. page_name = self.get("page_name")
  49. if not page_name:
  50. page_name = self.make_page_name()
  51. self.set("page_name", page_name)
  52. return page_name
  53. def make_page_name(self):
  54. return cleanup_page_name(self.get(self.page_title_field))
  55. def before_rename(self, oldname, name, merge):
  56. self._local = self.get_route()
  57. self.clear_cache()
  58. def after_rename(self, olddn, newdn, merge):
  59. if getattr(self, "_local"):
  60. self.update_routes_of_descendants(self._local)
  61. self.clear_cache()
  62. def on_trash(self):
  63. clear_cache(self.get_route())
  64. def website_published(self):
  65. if self.website.condition_field:
  66. return self.get(self.website.condition_field) and True or False
  67. else:
  68. return True
  69. def set_parent_website_route(self):
  70. parent_website_route_field = self.website.parent_website_route_field
  71. if parent_website_route_field:
  72. field = self.meta.get_field(parent_website_route_field)
  73. parent = self.get(parent_website_route_field)
  74. if parent:
  75. self.parent_website_route = frappe.get_doc(field.options,
  76. parent).get_route()
  77. def update_routes_of_descendants(self, old_route = None):
  78. if not self.is_new() and self.meta.get_field("parent_website_route"):
  79. if not old_route:
  80. old_route = frappe.get_doc(self.doctype, self.name).get_route()
  81. if old_route and old_route != self.get_route():
  82. # clear cache of old routes
  83. old_routes = frappe.get_all(self.doctype, fields=["parent_website_route", "page_name"],
  84. filters={"parent_website_route": ("like", old_route + "%")})
  85. if old_routes:
  86. for old_route in old_routes:
  87. clear_cache(make_route(old_route))
  88. frappe.db.sql("""update `tab{0}` set
  89. parent_website_route = replace(parent_website_route, %s, %s),
  90. modified = %s
  91. modified_by = %s
  92. where parent_website_route like %s""".format(self.doctype),
  93. (old_route, self.get_route(), now(), frappe.session.user, old_route + "%"))
  94. def get_website_route(self):
  95. route = frappe._dict()
  96. route.update({
  97. "doc": self,
  98. "page_or_generator": "Generator",
  99. "ref_doctype":self.doctype,
  100. "idx": self.idx,
  101. "docname": self.name,
  102. "page_name": self.get_page_name(),
  103. "controller": get_module_name(self.doctype, self.meta.module),
  104. })
  105. route.update(self.website)
  106. if not route.page_title:
  107. route.page_title = self.get(self.website.page_title_field)
  108. self.update_permissions(route)
  109. return route
  110. def update_permissions(self, route):
  111. if self.meta.get_field("public_read"):
  112. route.public_read = self.public_read
  113. route.public_write = self.public_write
  114. else:
  115. route.public_read = 1
  116. def get_parents(self, context):
  117. # already set
  118. if context.parents:
  119. return context.parents
  120. # home_page = get_home_page()
  121. parents = []
  122. me = self
  123. while me:
  124. _parent_field = me.website.parent_website_route_field
  125. _parent_val = me.get(_parent_field) if _parent_field else None
  126. # if no parent and not home page, then parent is home page
  127. # if not _parent_val and me.get_route() != home_page:
  128. # _parent_val = home_page
  129. if _parent_val:
  130. df = me.meta.get_field(_parent_field)
  131. if not df:
  132. break
  133. parent_doc = frappe.get_doc(df.options, _parent_val)
  134. if not parent_doc.website_published():
  135. break
  136. if parent_doc:
  137. parent_info = frappe._dict(name = parent_doc.get_route(),
  138. title= parent_doc.get(parent_doc.website.page_title_field or "name"))
  139. else:
  140. parent_info = frappe._dict(name=self.parent_website_route,
  141. title=self.parent_website_route.replace("_", " ").title())
  142. if parent_info.name in [p.name for p in parents]:
  143. raise frappe.ValidationError, "Recursion in parent link"
  144. parents.append(parent_info)
  145. me = parent_doc
  146. else:
  147. # parent route is a page e.g. "blog"
  148. if me.get("parent_website_route"):
  149. page_route = get_page_route(me.parent_website_route)
  150. if page_route:
  151. parents.append(frappe._dict(name = page_route.name,
  152. title=page_route.page_title))
  153. me = None
  154. parents.reverse()
  155. return parents
  156. def get_parent(self):
  157. parent_website_route_field = self.website.parent_website_route_field
  158. if parent_website_route_field:
  159. return self.get(parent_website_route_field)
  160. def get_children(self, context=None):
  161. children = []
  162. route = self.get_route()
  163. if route==get_home_page():
  164. children = frappe.db.sql("""select url as name, label as page_title,
  165. 1 as public_read from `tabTop Bar Item` where parentfield='sidebar_items'
  166. order by idx""", as_dict=True)
  167. route = ""
  168. if not children and self.meta.get_field("parent_website_route"):
  169. children = self.get_children_of(route)
  170. if not children and self.parent_website_route:
  171. children = self.get_children_of(self.parent_website_route)
  172. return children
  173. def get_children_of(self, route):
  174. children = frappe.db.sql("""select name, page_name,
  175. parent_website_route, {title_field} as title from `tab{doctype}`
  176. where ifnull(parent_website_route,'')=%s
  177. order by {order_by}""".format(
  178. doctype = self.doctype,
  179. title_field = self.website.page_title_field or "name",
  180. order_by = self.website.order_by or "idx asc"
  181. ), route, as_dict=True)
  182. for c in children:
  183. c.name = make_route(c)
  184. return children
  185. def get_next(self):
  186. if self.meta.get_field("parent_website_route") and self.parent_website_route:
  187. route = self.get_route()
  188. siblings = frappe.get_doc(self.doctype, self.get_parent()).get_children()
  189. for i, r in enumerate(siblings):
  190. if i < len(siblings) - 1:
  191. if route==r.name:
  192. return siblings[i+1]
  193. else:
  194. return frappe._dict()
  195. def make_route(doc):
  196. parent = doc.get("parent_website_route", "")
  197. return ((parent + "/") if parent else "") + doc.page_name