您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

351 行
13KB

  1. <!--
  2. # @name: base.html
  3. # @version: 0.1
  4. # @creation_date: 2021-10-20
  5. # @license: The MIT License <https://opensource.org/licenses/MIT>
  6. # @author: Simon Bowie <ad7588@coventry.ac.uk>
  7. # @purpose: Basic layout for all pages
  8. # @acknowledgements:
  9. # https://www.digitalocean.com/community/tutorials/how-to-make-a-web-application-using-flask-in-python-3
  10. # Bootstrap 5.1.3: https://getbootstrap.com/
  11. # Flask-Moment: https://flask-moment.readthedocs.io/en/latest/
  12. # Boostrap select: https://stackoverflow.com/questions/67942546/bootstrap-5-select-dropdown-with-the-multiple-attribute-collapsed
  13. -->
  14. {% macro relationships_links(resource) %}
  15. {% if resource.tools %}
  16. <div class="">
  17. <div class="px-4">
  18. Tools
  19. </div>
  20. {% for tool in resource.tools %}
  21. <div class="cell">
  22. {{ resource_lead(tool,size=2) }}
  23. </div>
  24. {% endfor %}
  25. </div>
  26. {% endif %}
  27. {% if resource.books %}
  28. <div class="">
  29. <div class="px-4">
  30. Books
  31. </div>
  32. {% for book in resource.books %}
  33. <div class="cell">
  34. {{ resource_lead(book,size=2) }}
  35. </div>
  36. {% endfor %}
  37. </div>
  38. {% endif %}
  39. {% if resource.practices %}
  40. <div class="">
  41. <div class="px-4">
  42. Practices
  43. </div>
  44. {% for practice in resource.practices %}
  45. <div class="cell">
  46. {{ resource_lead(practice,size=2) }}
  47. </div>
  48. {% endfor %}
  49. </div>
  50. {% endif %}
  51. {% endmacro %}
  52. {% macro resource_with_related(resource, loop, show_number=true) %}
  53. <div class="w-full border-b-2 border-black fade-right">
  54. <div class="content w-full py-8 overflow-x-auto">
  55. <div class="grid lg:grid-rows-[auto,auto,auto] grid-flow-col w-fit pr-40 " >
  56. <div class=" related ">
  57. {% if show_number %}
  58. <p>{{loop.index}} / {{count}}</p>
  59. {% else %}
  60. <p class="capitalize">{{ resource['type'] }}</p>
  61. {% endif %}
  62. </div>
  63. <div class="cell w-[32rem] row-start-1 row-span-3">
  64. {{ resource_lead(resource) }}
  65. </div>
  66. {% if resource.tools %}
  67. <div class="grid grid-rows-1 grid-flow-col w-fit h-fit">
  68. <div class="related">
  69. Related<br>Tools
  70. </div>
  71. {% for tool in resource.tools %}
  72. <div class="cell w-[30rem]">
  73. {{ resource_lead(tool,size=2) }}
  74. </div>
  75. {% endfor %}
  76. </div>
  77. {% endif %}
  78. {% if resource.books %}
  79. <div class="grid grid-rows-1 grid-flow-col w-fit h-fit">
  80. <div class="related">
  81. Related<br>Books
  82. </div>
  83. {% for book in resource.books %}
  84. <div class="cell w-[35rem]">
  85. {{ resource_lead(book,size=2) }}
  86. </div>
  87. {% endfor %}
  88. </div>
  89. {% endif %}
  90. {% if resource.practices %}
  91. <div class="grid grid-rows-1 grid-flow-col w-fit h-fit">
  92. <div class="related">
  93. Related<br>Practices
  94. </div>
  95. {% for practice in resource.practices %}
  96. <div class="cell w-[25rem]">
  97. {{ resource_lead(practice,size=2) }}
  98. </div>
  99. {% endfor %}
  100. </div>
  101. {% endif %}
  102. </div>
  103. </div>
  104. </div>
  105. {% endmacro %}
  106. {% macro popup_link(title,url) %}
  107. <a href="{{ url }}" class="nav-link">
  108. {{ title }}
  109. </a>
  110. {% endmacro %}
  111. {% macro resource_lead(resource,size=1) %}
  112. <a
  113. class="block h-full hover:opacity-60 transition-opacity cursor-pointer size-{{ size }}"
  114. {% if resource['type'] == 'book' %}
  115. href="{{ url_for('book.show_book', book_id=resource['id']) }}"
  116. {% endif %}
  117. {% if resource['type'] == 'tool' %}
  118. href="{{ url_for('tool.show_tool', tool_id=resource['id']) }}"
  119. {% endif %}
  120. {% if resource['type'] == 'practice' %}
  121. href="{{ url_for('practice.show_practice', practice_id=resource['id']) }}"
  122. {% endif %}
  123. hx-target="#modal-content"
  124. hx-select="main"
  125. hx-swap="innerHTML"
  126. @click="openModal()"
  127. >
  128. {% if (resource['type'] == 'book') %}
  129. <img class="w-20 h-20 object-contain float-right m-4 grayscale rotate-[15deg]" src="https://dummyimage.com/4:5x70" alt="cover for {{ resource['name'] }}">
  130. {% endif %}
  131. <h2 class="{{ resource['type'] }} {% if size==1 %} big-title {% else %} small-title {% endif %} mb-2">{{ resource['name'] }}</h2>
  132. {% if resource['year'] %}
  133. <div class="text-sm">
  134. {{ resource['year'] }}{% if resource['author'] %}, {{ resource['author'] }}{% endif%}
  135. </div>
  136. {% endif %}
  137. <div class="{% if size==1 %} big-text {% else %} small-text {% endif %} mb-[1em]">
  138. {{ resource['description'] | truncate(150) }}
  139. </div>
  140. </a>
  141. {% if current_user.is_authenticated %}
  142. <div class="">
  143. {% if resource['type'] == 'tool' %}
  144. <a href="{{ url_for('tool.edit_tool', tool_id=resource['id']) }}">
  145. <span class="absolute top-0 left-0 text-xs">Edit</span>
  146. </a>
  147. {% elif resource['type'] == 'practice' %}
  148. <a href="{{ url_for('practice.edit_practice', practice_id=resource['id']) }}">
  149. <span class="absolute top-0 left-0 text-xs">Edit</span>
  150. </a>
  151. {% elif resource['type'] == 'book' %}
  152. <a href="{{ url_for('book.edit_book', book_id=resource['id']) }}">
  153. <span class="absolute top-0 left-0 text-xs">Edit</span>
  154. </a>
  155. {% endif %}
  156. </div>
  157. {% endif %}
  158. {% endmacro %}
  159. <!DOCTYPE html>
  160. <html>
  161. <head>
  162. {{ moment.include_moment() }}
  163. <meta charset="utf-8">
  164. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  165. <meta name="viewport" content="width=device-width, initial-scale=1">
  166. <script src="https://unpkg.com/htmx.org@1.8.6"></script>
  167. <script src="//unpkg.com/alpinejs" defer></script>
  168. <title>Experimental Publishing Compendium</title>
  169. <link href="{{ url_for('static',filename='styles/main.css') }}" rel="stylesheet">
  170. <script>
  171. // htmx.on('htmx:beforeRequest', e=> {
  172. // console.log(e)
  173. // })
  174. // htmx.logAll()
  175. function base() {
  176. return {
  177. menuOpen: false,
  178. modalOpen: false,
  179. showRelated: false,
  180. home: '/',
  181. hideIfBase() {
  182. let str = document.location.toString();
  183. str = str.replace('http://', '');
  184. str = str.replace('https://', '');
  185. let l = str.split('/').length - 1;
  186. if (l < 2) {
  187. this.modalOpen = false;
  188. }
  189. return l;
  190. },
  191. init() {
  192. this.$watch('document.location', (value, oldValue) => {
  193. console.log('new url', value);
  194. });
  195. window.addEventListener('popstate', e => {
  196. this.hideIfBase();
  197. });
  198. },
  199. hideOverlay() {
  200. this.modalOpen = false;
  201. // window.history.pushState({}, '', this.home);
  202. },
  203. openModal() {
  204. // this.$refs.modal.innerHTML = '';
  205. this.modalOpen = true;
  206. let mc = document.querySelector('#modal-content');
  207. mc.scrollTo(0, 0);
  208. }
  209. }
  210. }
  211. </script>
  212. </head>
  213. <body
  214. class="text-base overflow-y-scroll"
  215. x-data="base()"
  216. hx-boost="true"
  217. hx-select="#all"
  218. hx-target="#all"
  219. hx-swap="outerHTML"
  220. hx-indicator="body"
  221. >
  222. <div id="loading" class="loading pointer-events-none ">
  223. <!-- <div class="bg-white fixed top-0 left-0 w-full h-screen z-20"></div> -->
  224. <div class="bg fixed top-0 left-0 w-full h-screen z-30"></div>
  225. <div class="spinner fixed top-0 left-0 w-full h-screen z-[60] flex justify-center items-center">
  226. <div class="inner bg-black rounded-full px-8 py-6 text-white text-center">
  227. Loading...
  228. </div>
  229. </div>
  230. </div>
  231. <div id="all">
  232. <header class="sticky top-0 z-10 bg-white border-b-[2px] border-black">
  233. <nav class=" lg:flex justify-center items-stretch">
  234. <a class="menuitem w-48 " href="{{ url_for('main.index') }}"><span>Experimental Publishing Compendium <span class="ml-3 inline-block -rotate-12 italic text-[#f52d2d]" style="text-shadow: 0 0 0.4rem white">beta</span></span></a>
  235. <a href="{{ url_for('tool.get_tools') }}" class="{{ 'active' if request.path == url_for('tool.get_tools') }} menuitem tool medium-title ">
  236. Tools
  237. </a>
  238. <a href="{{ url_for('practice.get_practices') }}" class="{{ 'active' if request.path == url_for('practice.get_practices') }} menuitem practice medium-title">
  239. Practices
  240. </a>
  241. <a href="{{ url_for('book.get_books') }}" class="{{ 'active' if request.path == url_for('book.get_books') }} menuitem medium-title book">
  242. Books
  243. </a>
  244. <a href="{{ url_for('main.about') }}" class="{{ 'active' if request.path == url_for('main.about') }} menuitem mr-auto">
  245. About / <br> Contact
  246. </a>
  247. <!-- <div class="ml-auto mr-2">
  248. {% if current_user.is_authenticated %}
  249. <a href="{{ url_for('create.create_resource') }}" class="block link">
  250. Add resource
  251. </a>
  252. {% endif %}
  253. {% if current_user.is_authenticated %}
  254. <a href="{{ url_for('main.profile') }}" class="block link">
  255. Profile
  256. </a>
  257. {% endif %}
  258. {% if not current_user.is_authenticated %}
  259. <a href="{{ url_for('auth.login') }}" class="block link">
  260. Login
  261. </a>
  262. <a href="{{ url_for('auth.signup') }}" class="block link">
  263. Sign Up
  264. </a>
  265. {% endif %}
  266. {% if current_user.is_authenticated %}
  267. <a href="{{ url_for('auth.logout') }}" class="block link">
  268. Logout
  269. </a>
  270. {% endif %}
  271. </div> -->
  272. <input class=" text-center text-base border-l-2 border-black pl-1 " type="text" placeholder="Search">
  273. </nav>
  274. </header>
  275. <!-- Begin page content -->
  276. <main>
  277. {% with messages = get_flashed_messages() %}
  278. {% if messages %}
  279. <div class="alert alert-danger">
  280. {{ messages[0] }}
  281. </div>
  282. {% endif %}
  283. {% endwith %}
  284. {% block content %}
  285. {% endblock %}
  286. </main>
  287. </div>
  288. <div id="modal" x-show="modalOpen" class="modal h-screen w-full fixed top-0 z-50 p-4 bg overscroll-none">
  289. <div class="cross cursor-pointer absolute top-10 right-10 w-10 h-10" @click="hideOverlay()">
  290. <svg width="100%" height="100%" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
  291. <path d="M2 2L18 18M18 2L2 18" stroke="black" stroke-width="1"></path>
  292. </svg>
  293. </div>
  294. <div id="modal-content" @click.outside="hideOverlay()" x-ref="modal" class="content w-full overflow-y-auto h-full bg-white " >
  295. </div>
  296. </div>
  297. <!-- Sticky footer-->
  298. <footer class="std-margin mt-20 text-sm">
  299. <div class="container">
  300. <span class="">© 2022–{{ moment().format('YYYY') }} <a href="https://copim.ac.uk/">COPIM</a> and licensed under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License (CC BY 4.0)</a>.</span>
  301. </div>
  302. </footer>
  303. <!-- JavaScript -->
  304. <!-- jQuery first, then Popper JS, then Bootstrap JS -->
  305. <script src="{{ url_for('static',filename='js/main.js') }}"></script>
  306. </body>
  307. </html>