index.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. {% extends "_common/base.html" %}
  2. {% block css %}
  3. {% load avatar_tags %}
  4. {% load day_util %}
  5. {% load page_tag %}
  6. {% endblock %}
  7. {% block container %}
  8. <div class="ui grid stackable container">
  9. <div class="row" id="article">
  10. <div class="eleven wide column">
  11. <div class="ui feed">
  12. <h2>动态</h2>
  13. <div class="ui divider"></div>
  14. {% for item in articles_new %}
  15. {% if item.status == 1 %}
  16. {% if item.type == 1 %}
  17. <div class="event">
  18. <div class="label">
  19. <img src="/user_avatar/{{ item.user_id }}">
  20. </div>
  21. <div class="content">
  22. <div class="date"
  23. style="font-size: 1.1em">{{ item.created_time | days_until }}</div>
  24. <div class="summary"><a>
  25. {{ item.user__first_name }}{{ item.user__last_name }}</a>
  26. 发布了{{ item.category__name }}:<a
  27. href="/article/{{ item.id }}.html">{{ item.title }}</a></div>
  28. <div class="extra text">{{ item.intro }}
  29. &nbsp;&nbsp;&nbsp;Tags:
  30. {% for tag in item.tags %}
  31. <a href="/tag/{{ tag }}?page=1"><span
  32. class="label label-success">{{ tag }}</span></a>
  33. {% endfor %}</div>
  34. </div>
  35. </div>
  36. {% elif item.type == 2 %}
  37. <div class="event">
  38. <div class="label">
  39. <img src="/user_avatar/{{ item.user_id }}">
  40. </div>
  41. <div class="content">
  42. <div class="date"
  43. style="font-size: 1.1em">{{ item.created_time | days_until }}</div>
  44. <div class="summary"><a>
  45. {{ item.user__first_name }}{{ item.user__last_name }}</a>
  46. 发布了{{ item.category__name }}:<a
  47. href="/article/{{ item.id }}.html">{{ item.title }}</a></div>
  48. {% if '<iframe' in item.intro %}
  49. {% autoescape off %}
  50. <div class="extra images">
  51. {{ item.intro }}
  52. </div>
  53. {% endautoescape %}
  54. {% else %}
  55. {% autoescape off %}
  56. <div class="extra images">
  57. {{ item.html_text }}
  58. </div>
  59. {% endautoescape %}
  60. {% endif %}
  61. </div>
  62. </div>
  63. {% endif %}
  64. {% endif %}
  65. {% endfor %}
  66. {% if is_login %}
  67. <h3>发布动态</h3>
  68. <div class="ui divider"></div>
  69. <form class="ui reply form">
  70. {% csrf_token %}
  71. <div class="field">
  72. <!-- 编辑器 DOM -->
  73. <input placeholder="文字" name="title" class="ui input">
  74. <div style="border: 1px solid #ccc;margin-top: 5px">
  75. <div id="editor-toolbar" style="border-bottom: 1px solid #ccc;"></div>
  76. <div id="editor-text-area"></div>
  77. </div>
  78. </div>
  79. <div onclick="submit()" style="float: right" class="ui primary submit labeled icon button">
  80. <i class="icon send"></i> 发布
  81. </div>
  82. </form>
  83. {% endif %}
  84. </div>
  85. </div>
  86. <div class="four wide right floated column">
  87. <h4 class="ui header">搜索</h4>
  88. <div id="search" class="ui category search">
  89. <div class="ui icon input">
  90. <input class="prompt" type="text" placeholder="搜索">
  91. <i class="search icon"></i>
  92. </div>
  93. </div>
  94. <h4 class="ui header">归档</h4>
  95. <div class="ui list">
  96. {% for record in records %}
  97. <a class="item" href="/date/{{ record.datetime }}?page=1">{{ record.datetime }}
  98. ({{ record.count }})</a>
  99. {% endfor %}
  100. </div>
  101. <h4 class="ui header">Top</h4>
  102. <div class="ui list">
  103. {% for tag in tags %}
  104. <a class="item" href="/tag/{{ tag.name }}?page=1">{{ tag.name }} ({{ tag.count }})</a>
  105. {% endfor %}
  106. </div>
  107. </div>
  108. </div>
  109. </div>
  110. {% endblock %}
  111. {% block js %}
  112. {% if is_login %}
  113. <script src="https://unpkg.com/@wangeditor/editor@latest/dist/index.js"></script>
  114. <script>
  115. const E = window.wangEditor
  116. // 切换语言
  117. const LANG = location.href.indexOf('lang=en') > 0 ? 'en' : 'zh-CN'
  118. E.i18nChangeLanguage(LANG)
  119. const imageToHtmlConf = {
  120. type: 'image',
  121. elemToHtml: function imageToHtml(elemNode) {
  122. const {src, alt, href = '', style = {}, width, height} = elemNode || {}
  123. return `<a data-pswp-width="${alt.split(',')[0]}" data-pswp-height="${alt.split(',')[1]}" href="${src}"><img data-magnify="gallery" data-src="${src}" src="${src}" data-href="${href}" "/></a>`
  124. }
  125. };
  126. const editorConfig = {
  127. placeholder: 'Type here...',
  128. scroll: false, // 禁止编辑器滚动
  129. MENU_CONF: {
  130. uploadImage: {
  131. server: '/management/files/upload',
  132. // form-data fieldName ,默认值 'wangeditor-uploaded-image'
  133. fieldName: 'file',
  134. // 单个文件的最大体积限制,默认为 2M
  135. maxFileSize: 10 * 1024 * 1024, // 1M
  136. // 最多可上传几个文件,默认为 100
  137. maxNumberOfFiles: 10,
  138. // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
  139. allowedFileTypes: ['image/*'],
  140. // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
  141. meta: {
  142. csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val()
  143. },
  144. // 将 meta 拼接到 url 参数中,默认 false
  145. metaWithUrl: false,
  146. // 自定义增加 http header
  147. // 跨域是否传递 cookie ,默认为 false
  148. withCredentials: true,
  149. // 超时时间,默认为 10 秒
  150. timeout: 5 * 1000, // 5 秒
  151. }
  152. },
  153. onChange(editor) {
  154. const html = editor.getHtml()
  155. $('#title').val($('#page_title').val())
  156. }
  157. }
  158. E.Boot.registerElemToHtml(imageToHtmlConf);
  159. // 先创建 editor
  160. const editor = E.createEditor({
  161. selector: '#editor-text-area',
  162. content: [],
  163. // html: '',
  164. config: editorConfig
  165. })
  166. // 创建 toolbar
  167. const toolbar = E.createToolbar({
  168. editor,
  169. mode: 'simple',
  170. selector: '#editor-toolbar',
  171. config: {
  172. excludeKeys: ['blockquote', 'header1', 'header2', 'header3', '|', 'bold', 'underline', 'italic', 'through', 'color', 'bgColor', 'clearStyle', '|', 'bulletedList', 'numberedList', 'todo', 'justifyLeft', 'justifyRight', 'justifyCenter', '|', 'insertLink', 'insertVideo', 'insertTable', 'codeBlock', '|', 'undo', 'redo', '|', 'fullScreen']
  173. }
  174. })
  175. </script>
  176. {% endif %}
  177. <script>
  178. function submit() {
  179. let formData = new FormData()
  180. formData.append('title', $("input[name='title']").val())
  181. formData.append('intro', editor.getText())
  182. formData.append('category', 6)
  183. formData.append('html', editor.getHtml())
  184. formData.append('markdown', editor.getText())
  185. formData.append('type', 2)
  186. formData.append('tags', '')
  187. formData.append('status', 1)
  188. formData.append('is_top', 1)
  189. formData.append('csrfmiddlewaretoken', $("input[name='csrfmiddlewaretoken']").val())
  190. $.ajax('/management/article/add_article', {
  191. method: 'post',
  192. data: formData,
  193. contentType: false,
  194. processData: false,
  195. success: function (res) {
  196. window.location.href = '/'
  197. },
  198. error: function (err) {
  199. }
  200. })
  201. }
  202. </script>
  203. {% endblock %}
  204. {% load static %}