wagtailsettings_models.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. """
  2. Custom wagtail settings used by CodeRed CMS.
  3. Settings are user-configurable on a per-site basis (multisite).
  4. Global project or developer settings should be defined in coderedcms.settings.py .
  5. """
  6. import json
  7. from django.db import models
  8. from django.utils.translation import ugettext_lazy as _
  9. from wagtail.admin.edit_handlers import HelpPanel, FieldPanel, MultiFieldPanel
  10. from wagtail.images.edit_handlers import ImageChooserPanel
  11. from wagtail.contrib.settings.models import BaseSetting, register_setting
  12. from coderedcms.settings import cr_settings
  13. @register_setting(icon='fa-facebook-official')
  14. class SocialMediaSettings(BaseSetting):
  15. """
  16. Social media accounts.
  17. """
  18. class Meta:
  19. verbose_name = _('Social Media')
  20. facebook = models.URLField(
  21. blank=True,
  22. verbose_name=_('Facebook'),
  23. help_text=_('Your Facebook page URL'),
  24. )
  25. twitter = models.URLField(
  26. blank=True,
  27. verbose_name=_('Twitter'),
  28. help_text=_('Your Twitter page URL'),
  29. )
  30. instagram = models.CharField(
  31. max_length=255,
  32. blank=True,
  33. verbose_name=_('Instagram'),
  34. help_text=_('Your Instagram username, without the @'),
  35. )
  36. youtube = models.URLField(
  37. blank=True,
  38. verbose_name=_('YouTube'),
  39. help_text=_('Your YouTube channel or user account URL'),
  40. )
  41. linkedin = models.URLField(
  42. blank=True,
  43. verbose_name=_('LinkedIn'),
  44. help_text=_('Your LinkedIn page URL'),
  45. )
  46. googleplus = models.URLField(
  47. blank=True,
  48. verbose_name=_('Google'),
  49. help_text=_('Your Google+ page or Google business listing URL'),
  50. )
  51. @property
  52. def twitter_handle(self):
  53. """
  54. Gets the handle of the twitter account from a URL.
  55. """
  56. return self.twitter.strip().strip('/').split('/')[-1]
  57. @property
  58. def social_json(self):
  59. """
  60. Returns non-blank social accounts as a JSON list.
  61. """
  62. socialist = [
  63. self.facebook,
  64. self.twitter,
  65. self.instagram,
  66. self.youtube,
  67. self.linkedin,
  68. self.googleplus,
  69. ]
  70. socialist = list(filter(None, socialist))
  71. return json.dumps(socialist)
  72. panels = [
  73. MultiFieldPanel(
  74. [
  75. FieldPanel('facebook'),
  76. FieldPanel('twitter'),
  77. FieldPanel('instagram'),
  78. FieldPanel('youtube'),
  79. FieldPanel('linkedin'),
  80. FieldPanel('googleplus'),
  81. ],
  82. _('Social Media Accounts'),
  83. )
  84. ]
  85. @register_setting(icon='fa-desktop')
  86. class LayoutSettings(BaseSetting):
  87. """
  88. Branding, navbar, and theme settings.
  89. """
  90. class Meta:
  91. verbose_name = _('Layout')
  92. logo = models.ForeignKey(
  93. 'wagtailimages.Image',
  94. null=True,
  95. blank=True,
  96. on_delete=models.SET_NULL,
  97. related_name='+',
  98. verbose_name=_('Logo'),
  99. help_text=_('Brand logo used in the navbar and throughout the site')
  100. )
  101. favicon = models.ForeignKey(
  102. 'wagtailimages.Image',
  103. null=True,
  104. blank=True,
  105. on_delete=models.SET_NULL,
  106. related_name='favicon',
  107. verbose_name=_('Favicon'),
  108. )
  109. navbar_color_scheme = models.CharField(
  110. blank=True,
  111. max_length=50,
  112. choices=cr_settings['FRONTEND_NAVBAR_COLOR_SCHEME_CHOICES'],
  113. default=cr_settings['FRONTEND_NAVBAR_COLOR_SCHEME_DEFAULT'],
  114. verbose_name=_('Navbar color scheme'),
  115. help_text=_('Optimizes text and other navbar elements for use with light or dark backgrounds.'),
  116. )
  117. navbar_class = models.CharField(
  118. blank=True,
  119. max_length=255,
  120. default=cr_settings['FRONTEND_NAVBAR_CLASS_DEFAULT'],
  121. verbose_name=_('Navbar CSS class'),
  122. help_text=_('Custom classes applied to navbar e.g. "bg-light", "bg-dark", "bg-primary".'),
  123. )
  124. navbar_fixed = models.BooleanField(
  125. default=False,
  126. verbose_name=_('Fixed navbar'),
  127. help_text=_('Fixed navbar will remain at the top of the page when scrolling.'),
  128. )
  129. navbar_wrapper_fluid = models.BooleanField(
  130. default=True,
  131. verbose_name=_('Full width navbar'),
  132. help_text=_('The navbar will fill edge to edge.'),
  133. )
  134. navbar_content_fluid = models.BooleanField(
  135. default=False,
  136. verbose_name=_('Full width navbar contents'),
  137. help_text=_('Content within the navbar will fill edge to edge.'),
  138. )
  139. navbar_collapse_mode = models.CharField(
  140. blank=True,
  141. max_length=50,
  142. choices=cr_settings['FRONTEND_NAVBAR_COLLAPSE_MODE_CHOICES'],
  143. default=cr_settings['FRONTEND_NAVBAR_COLLAPSE_MODE_DEFAULT'],
  144. verbose_name=_('Collapse navbar menu'),
  145. help_text=_('Control on what screen sizes to show and collapse the navbar menu links.'),
  146. )
  147. navbar_format = models.CharField(
  148. blank=True,
  149. max_length=50,
  150. choices=cr_settings['FRONTEND_NAVBAR_FORMAT_CHOICES'],
  151. default=cr_settings['FRONTEND_NAVBAR_FORMAT_DEFAULT'],
  152. verbose_name=_('Navbar format'),
  153. )
  154. navbar_search = models.BooleanField(
  155. default=True,
  156. verbose_name=_('Search box'),
  157. help_text=_('Show search box in navbar')
  158. )
  159. frontend_theme = models.CharField(
  160. blank=True,
  161. max_length=50,
  162. choices=cr_settings['FRONTEND_THEME_CHOICES'],
  163. default=cr_settings['FRONTEND_THEME_DEFAULT'],
  164. verbose_name=_('Theme variant'),
  165. help_text=cr_settings['FRONTEND_THEME_HELP'],
  166. )
  167. panels = [
  168. MultiFieldPanel(
  169. [
  170. ImageChooserPanel('logo'),
  171. ImageChooserPanel('favicon'),
  172. ],
  173. heading=_('Branding')
  174. ),
  175. MultiFieldPanel(
  176. [
  177. FieldPanel('navbar_color_scheme'),
  178. FieldPanel('navbar_class'),
  179. FieldPanel('navbar_fixed'),
  180. FieldPanel('navbar_wrapper_fluid'),
  181. FieldPanel('navbar_content_fluid'),
  182. FieldPanel('navbar_collapse_mode'),
  183. FieldPanel('navbar_format'),
  184. FieldPanel('navbar_search'),
  185. ],
  186. heading=_('Site Navbar Layout')
  187. ),
  188. MultiFieldPanel(
  189. [
  190. FieldPanel('frontend_theme'),
  191. ],
  192. heading=_('Theming')
  193. ),
  194. ]
  195. @register_setting(icon='fa-google')
  196. class AnalyticsSettings(BaseSetting):
  197. """
  198. Tracking and Google Analytics.
  199. """
  200. class Meta:
  201. verbose_name = _('Tracking')
  202. ga_tracking_id = models.CharField(
  203. blank=True,
  204. max_length=255,
  205. verbose_name=_('GA Tracking ID'),
  206. help_text=_('Your Google Analytics tracking ID (begins with "UA-")'),
  207. )
  208. ga_track_button_clicks = models.BooleanField(
  209. default=False,
  210. verbose_name=_('Track button clicks'),
  211. help_text=_('Track all button clicks using Google Analytics event tracking. Event tracking details can be specified in each button’s advanced settings options.'),
  212. )
  213. panels = [
  214. MultiFieldPanel(
  215. [
  216. FieldPanel('ga_tracking_id'),
  217. FieldPanel('ga_track_button_clicks'),
  218. ],
  219. heading=_('Google Analytics')
  220. )
  221. ]
  222. @register_setting(icon='fa-universal-access')
  223. class ADASettings(BaseSetting):
  224. """
  225. Accessibility related options.
  226. """
  227. class Meta:
  228. verbose_name = 'Accessibility'
  229. skip_navigation = models.BooleanField(
  230. default=False,
  231. verbose_name=_('Show skip navigation link'),
  232. help_text=_('Shows a "Skip Navigation" link above the navbar that takes you directly to the main content.'),
  233. )
  234. panels = [
  235. MultiFieldPanel(
  236. [
  237. FieldPanel('skip_navigation'),
  238. ],
  239. heading=_('Accessibility')
  240. )
  241. ]
  242. @register_setting(icon='cog')
  243. class GeneralSettings(BaseSetting):
  244. """
  245. Various site-wide settings. A good place to put
  246. one-off settings that don't belong anywhere else.
  247. """
  248. default_robot = """User-agent: *
  249. Disallow: /admin/
  250. User-agent: *
  251. Disallow: /django-admin/
  252. User-agent: *
  253. Allow: /
  254. Sitemap: /sitemap.xml"""
  255. from_email_address = models.EmailField(
  256. blank=True,
  257. max_length=255,
  258. verbose_name=_('From email address'),
  259. help_text=_('The default email address this site uses to send emails.'),
  260. )
  261. search_num_results = models.PositiveIntegerField(
  262. default=10,
  263. verbose_name=_('Number of results per page'),
  264. )
  265. robots = models.TextField(
  266. blank=True,
  267. default=default_robot,
  268. verbose_name=_('robots.txt'),
  269. help_text=_('Enter the contents of a robots.txt file.'),
  270. )
  271. panels = [
  272. MultiFieldPanel(
  273. [
  274. FieldPanel('from_email_address'),
  275. ],
  276. _('Email')
  277. ),
  278. MultiFieldPanel(
  279. [
  280. FieldPanel('search_num_results'),
  281. ],
  282. _('Search Settings')
  283. ),
  284. MultiFieldPanel(
  285. [
  286. FieldPanel('robots'),
  287. ],
  288. _('Robots.txt')
  289. ),
  290. MultiFieldPanel(
  291. [
  292. HelpPanel(template='coderedcms/includes/wagtailadmin_cache.html',),
  293. ],
  294. _('Performance')
  295. )
  296. ]
  297. class Meta:
  298. verbose_name = _('General')
  299. @register_setting(icon='fa-line-chart')
  300. class SeoSettings(BaseSetting):
  301. """
  302. Additional search engine optimization and meta tags
  303. that can be turned on or off.
  304. """
  305. class Meta:
  306. verbose_name = _('SEO')
  307. og_meta = models.BooleanField(
  308. default=True,
  309. verbose_name=_('Use OpenGraph Markup'),
  310. help_text=_('Show an optimized preview when linking to this site on Facebook, Linkedin, Twitter, and others. See http://ogp.me/.'),
  311. )
  312. twitter_meta = models.BooleanField(
  313. default=True,
  314. verbose_name=_('Use Twitter Markup'),
  315. help_text=_('Shows content as a "card" when linking to this site on Twitter. See https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards.'),
  316. )
  317. struct_meta = models.BooleanField(
  318. default=True,
  319. verbose_name=_('Use Structured Data'),
  320. help_text=_('Optimizes information about your organization for search engines. See https://schema.org/.'),
  321. )
  322. amp_pages = models.BooleanField(
  323. default=True,
  324. verbose_name=_('Use AMP Pages'),
  325. help_text=_('Generates an alternate AMP version of Article pages that are preferred by search engines. See https://www.ampproject.org/'),
  326. )
  327. panels = [
  328. MultiFieldPanel(
  329. [
  330. FieldPanel('og_meta'),
  331. FieldPanel('twitter_meta'),
  332. FieldPanel('struct_meta'),
  333. FieldPanel('amp_pages'),
  334. HelpPanel(content=_('If these settings are enabled, the corresponding values in each page’s SEO tab are used.')),
  335. ],
  336. heading=_('Search Engine Optimization')
  337. )
  338. ]