j1-template 2022.5.2 → 2022.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (358) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/layouts/content_generator_news_panel_posts.html +61 -40
  3. data/_includes/themes/j1/layouts/content_generator_page.html +22 -22
  4. data/_includes/themes/j1/layouts/content_generator_post.html +1 -1
  5. data/_includes/themes/j1/layouts/layout_metadata_generator.html +13 -79
  6. data/_includes/themes/j1/{blocks → procedures/blocks}/footer/boxes/about_box.proc +0 -0
  7. data/_includes/themes/j1/{blocks → procedures/blocks}/footer/boxes/contacts_box.proc +0 -0
  8. data/_includes/themes/j1/{blocks → procedures/blocks}/footer/boxes/issue.proc +0 -0
  9. data/_includes/themes/j1/{blocks → procedures/blocks}/footer/boxes/legal_statements.proc +0 -0
  10. data/_includes/themes/j1/{blocks → procedures/blocks}/footer/boxes/links_box.proc +0 -0
  11. data/_includes/themes/j1/{blocks → procedures/blocks}/footer/boxes/news_box.proc +0 -0
  12. data/_includes/themes/j1/{blocks → procedures/blocks}/footer/boxes/social_media_icons.proc +0 -0
  13. data/_includes/themes/j1/procedures/blocks/get_wave.proc +211 -0
  14. data/_includes/themes/j1/procedures/collections/create_collection_article_preview.proc +1 -1
  15. data/_includes/themes/j1/procedures/global/create_word_cloud.proc +1 -1
  16. data/_includes/themes/j1/procedures/posts/collate_timeline.proc +2 -2
  17. data/_includes/themes/j1/procedures/posts/pager.proc +9 -10
  18. data/_layouts/default.html +5 -1
  19. data/apps/private/README.txt +1 -0
  20. data/apps/protected/README.txt +1 -0
  21. data/apps/public/README.txt +1 -0
  22. data/assets/data/banner.html +38 -8
  23. data/assets/data/footer.html +31 -11
  24. data/assets/data/panel.html +118 -27
  25. data/assets/themes/j1/adapter/js/attic.js +4 -4
  26. data/assets/themes/j1/adapter/js/comments.js +18 -7
  27. data/assets/themes/j1/adapter/js/waves.js +227 -0
  28. data/assets/themes/j1/core/css/icon-fonts/fontawesome.min.css +1 -1
  29. data/assets/themes/j1/core/css/icon-fonts/mdi.min.css +1 -1
  30. data/assets/themes/j1/core/css/icon-fonts/mdil.min.css +1 -1
  31. data/assets/themes/j1/core/css/themes/bootstrap/bootstrap.css +92 -74
  32. data/assets/themes/j1/core/css/themes/bootstrap/bootstrap.min.css +5 -3
  33. data/assets/themes/j1/core/css/themes/theme_vapor/bootstrap.css +92 -74
  34. data/assets/themes/j1/core/css/themes/theme_vapor/bootstrap.min.css +5 -3
  35. data/assets/themes/j1/core/css/themes/unodark/bootstrap.css +105 -138
  36. data/assets/themes/j1/core/css/themes/unodark/bootstrap.min.css +5 -3
  37. data/assets/themes/j1/core/css/themes/unolight/bootstrap.css +457 -262
  38. data/assets/themes/j1/core/css/themes/unolight/bootstrap.min.css +26 -15
  39. data/assets/themes/j1/core/css/vendor.css +11 -8
  40. data/assets/themes/j1/core/css/vendor.min.css +1 -1
  41. data/assets/themes/j1/core/fonts/fontawesome_5/LICENSE.txt +34 -0
  42. data/assets/themes/j1/core/fonts/material_design_icons/LICENSE.txt +97 -0
  43. data/assets/themes/j1/core/fonts/material_design_icons_light/LICENSE.txt +92 -0
  44. data/assets/themes/j1/core/fonts/roboto/LICENSE.txt +11 -0
  45. data/assets/themes/j1/core/js/template.js +419 -746
  46. data/assets/themes/j1/core/js/template.min.js.map +1 -1
  47. data/assets/themes/j1/modules/backstretch/js/backstretch.js +1 -1
  48. data/assets/themes/j1/modules/backstretch/js/backstretch.min.js +1 -1
  49. data/assets/themes/j1/modules/bokeh/LICENSE.txt +28 -0
  50. data/assets/themes/j1/modules/jquery/js/extensions/hasClass.js +17 -0
  51. data/assets/themes/j1/modules/jquery/js/extensions/hasClass.min.js +17 -0
  52. data/assets/themes/j1/modules/jquery/js/extensions/removeClass.js +18 -0
  53. data/assets/themes/j1/modules/jquery/js/extensions/removeClass.min.js +17 -0
  54. data/assets/themes/j1/modules/later/LICENSE.txt +21 -0
  55. data/assets/themes/j1/modules/log4javascript/license.txt +201 -0
  56. data/assets/themes/j1/modules/lunr/stopwords/de.txt +229 -0
  57. data/assets/themes/j1/modules/lunr/stopwords/en.txt +119 -0
  58. data/assets/themes/j1/modules/masterslider/LICENSE.txt +621 -0
  59. data/assets/themes/j1/modules/masterslider/README.txt +531 -0
  60. data/assets/themes/j1/modules/msDropdown/LICENSE.txt +20 -0
  61. data/assets/themes/j1/modules/nbinteract-core/LICENSE.txt +60 -0
  62. data/assets/themes/j1/modules/rouge/css/themes.txt +46 -0
  63. data/assets/themes/j1/modules/vega/LICENSE.txt +27 -0
  64. data/lib/j1/version.rb +1 -1
  65. data/lib/starter_web/Gemfile +11 -7
  66. data/lib/starter_web/README.md +5 -5
  67. data/lib/starter_web/_config.yml +199 -135
  68. data/lib/starter_web/_data/blocks/banner.yml +18 -2
  69. data/lib/starter_web/_data/blocks/defaults/footer.yml +3 -1
  70. data/lib/starter_web/_data/blocks/defaults/panel.yml +4 -0
  71. data/lib/starter_web/_data/blocks/footer.yml +12 -1
  72. data/lib/starter_web/_data/blocks/panel.yml +88 -19
  73. data/lib/starter_web/_data/j1_config.yml +2 -2
  74. data/lib/starter_web/_data/layouts/collection.yml +0 -9
  75. data/lib/starter_web/_data/layouts/home.yml +21 -30
  76. data/lib/starter_web/_data/layouts/news_panel_posts.yml +0 -9
  77. data/lib/starter_web/_data/layouts/page.yml +0 -9
  78. data/lib/starter_web/_data/layouts/post.yml +0 -9
  79. data/lib/starter_web/_data/modules/blog_navigator.yml +6 -0
  80. data/lib/starter_web/_data/modules/defaults/blog_navigator.yml +15 -8
  81. data/lib/starter_web/_data/modules/defaults/cookieconsent.yml +5 -4
  82. data/lib/starter_web/_data/modules/defaults/navigator.yml +1 -1
  83. data/lib/starter_web/_data/modules/defaults/waves.yml +32 -0
  84. data/lib/starter_web/_data/modules/navigator_menu.yml +48 -120
  85. data/lib/starter_web/_data/modules/waves.yml +32 -0
  86. data/lib/starter_web/_data/plugins/defaults/feed.yml +82 -0
  87. data/lib/starter_web/_data/plugins/defaults/seo-tags.yml +65 -0
  88. data/lib/starter_web/_data/plugins/defaults/sitemap.yml +66 -0
  89. data/lib/starter_web/_data/plugins/feed.yml +35 -0
  90. data/lib/starter_web/_data/plugins/seo-tags.yml +30 -0
  91. data/lib/starter_web/_data/plugins/sitemap.yml +30 -0
  92. data/lib/starter_web/_data/resources.yml +22 -0
  93. data/lib/starter_web/_data/templates/feed.xml +191 -0
  94. data/lib/starter_web/_data/templates/robots.txt +1 -0
  95. data/lib/starter_web/_data/templates/seo-tags.html +140 -0
  96. data/lib/starter_web/_data/templates/sitemap.xml +36 -0
  97. data/lib/starter_web/_includes/attributes.asciidoc +49 -47
  98. data/lib/starter_web/_includes/custom/static/bs5_accordion.html +84 -0
  99. data/lib/starter_web/_includes/custom/templates/bs5_accordion.html +103 -0
  100. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/admonition-block-answer.rb +0 -0
  101. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/admonition-block-question.rb +0 -0
  102. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/banner.rb +0 -0
  103. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/callout.rb +0 -0
  104. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/carousel-block.rb +0 -0
  105. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/conum.rb +0 -0
  106. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/fab-icon-inline.rb +0 -0
  107. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/fas-icon-inline.rb +0 -0
  108. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/flag-icon-inline.rb +0 -0
  109. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/gallery-block.rb +0 -0
  110. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/gist-block.rb +0 -0
  111. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/iconify-icon-inline.rb +0 -0
  112. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/lightbox-block.rb +0 -0
  113. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/lorem_inline.rb +0 -0
  114. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/masterslider-block.rb +0 -0
  115. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/mdi-icon-inline.rb +0 -0
  116. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/panel.rb +0 -0
  117. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/range-slider-block.rb +0 -0
  118. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/shout-block.rb +0 -0
  119. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/textbook-block.rb +0 -0
  120. data/lib/starter_web/_plugins/{asciidoctor-extensions → asciidoctor}/twitter-emoji-inline.rb +0 -0
  121. data/lib/starter_web/_plugins/{debug.rb → filter/debug.rb} +0 -0
  122. data/lib/starter_web/_plugins/{encodeBase64.rb → filter/encodeBase64.rb} +0 -0
  123. data/lib/starter_web/_plugins/{encryptAES.rb → filter/encryptAES.rb} +0 -0
  124. data/lib/starter_web/_plugins/{filters.rb → filter/filters.rb} +11 -0
  125. data/lib/starter_web/_plugins/{minifyJS.rb → filter/minifyJS.rb} +0 -0
  126. data/lib/starter_web/_plugins/{minifyJSON.rb → filter/minifyJSON.rb} +0 -0
  127. data/lib/starter_web/_plugins/{prettify.rb → filter/prettify.rb} +0 -0
  128. data/lib/starter_web/_plugins/filter/xml_prettify.rb +36 -0
  129. data/lib/starter_web/_plugins/{symlink_watcher.rb → helper/symlink_watcher.rb} +0 -0
  130. data/lib/starter_web/_plugins/{date-i18n.rb → i18n/date.rb} +1 -1
  131. data/lib/starter_web/_plugins/{lunr_index.rb → index/lunr.rb} +38 -35
  132. data/lib/starter_web/_plugins/seo/j1-feed.rb +268 -0
  133. data/lib/starter_web/_plugins/seo/j1-seo-tags.rb +717 -0
  134. data/lib/starter_web/_plugins/seo/j1-sitemap.rb +140 -0
  135. data/lib/starter_web/assets/images/banner/scalable/wave.svg +13 -0
  136. data/lib/starter_web/assets/images/blocks/waves/scalable/1280x100/wave-1.svg +63 -0
  137. data/lib/starter_web/assets/images/blocks/waves/scalable/1280x100/wave-2.svg +60 -0
  138. data/lib/starter_web/assets/images/blocks/waves/scalable/1280x100/wave-3.svg +64 -0
  139. data/lib/starter_web/assets/images/blocks/waves/scalable/1280x100/wave-4.svg +62 -0
  140. data/lib/starter_web/assets/images/blocks/waves/scalable/1920x100/wave-1.svg +64 -0
  141. data/lib/starter_web/assets/images/blocks/waves/scalable/1920x100/wave-2.svg +60 -0
  142. data/lib/starter_web/assets/images/blocks/waves/scalable/1920x100/wave-3.svg +65 -0
  143. data/lib/starter_web/assets/images/blocks/waves/scalable/1920x100/wave-4.svg +62 -0
  144. data/lib/starter_web/assets/images/collections/blog/featured/dynamic-web-access.png +0 -0
  145. data/lib/starter_web/assets/images/collections/blog/featured/jamstack-generators.png +0 -0
  146. data/lib/starter_web/assets/images/collections/blog/featured/static-web-access.png +0 -0
  147. data/lib/starter_web/assets/images/icons/jekyll/logo-2x.png +0 -0
  148. data/lib/starter_web/assets/images/icons/jekyll/octojekyll.png +0 -0
  149. data/lib/starter_web/assets/images/modules/attics/1280x800/j1-template.png +0 -0
  150. data/lib/starter_web/assets/images/modules/attics/1280x800/jekyll-generator.png +0 -0
  151. data/lib/starter_web/assets/images/modules/attics/1280x800jekyll-generator.jpg +0 -0
  152. data/lib/starter_web/assets/images/modules/attics/1920x1280/_ben-kolde.jpg +0 -0
  153. data/lib/starter_web/assets/images/modules/attics/1920x1280/_moritz-kindler.jpg +0 -0
  154. data/lib/starter_web/assets/images/modules/attics/1920x1280/alina-grubnyak.jpg +0 -0
  155. data/lib/starter_web/assets/images/modules/attics/1920x1280/andrea-badino.jpg +0 -0
  156. data/lib/starter_web/assets/images/modules/attics/1920x1280/brad-neathery.jpg +0 -0
  157. data/lib/starter_web/assets/images/modules/attics/1920x1280/bruno-figueiredo.jpg +0 -0
  158. data/lib/starter_web/assets/images/modules/attics/1920x1280/fly-d.jpg +0 -0
  159. data/lib/starter_web/assets/images/modules/attics/1920x1280/guillaume-bolduc.jpg +0 -0
  160. data/lib/starter_web/assets/images/modules/attics/1920x1280/melanie-deziel.jpg +0 -0
  161. data/lib/starter_web/assets/images/modules/attics/1920x1280/milad-fakurian.jpg +0 -0
  162. data/lib/starter_web/assets/images/modules/attics/1920x1280/quino-al-2.jpg +0 -0
  163. data/lib/starter_web/assets/images/modules/attics/lunr-1280x800.jpg +0 -0
  164. data/lib/starter_web/assets/images/modules/attics/no-time-1920x1280.jpg +0 -0
  165. data/lib/starter_web/assets/images/modules/gallery/mega_cities/author.txt +75 -0
  166. data/lib/starter_web/assets/images/pages/egrid/bg.png +0 -0
  167. data/lib/starter_web/assets/images/pages/egrid/black_denim.png +0 -0
  168. data/lib/starter_web/assets/images/pages/egrid/explanation.png +0 -0
  169. data/lib/starter_web/assets/images/pages/egrid/html_markup.png +0 -0
  170. data/lib/starter_web/assets/images/pages/egrid/large/1.jpg +0 -0
  171. data/lib/starter_web/assets/images/pages/egrid/large/10.jpg +0 -0
  172. data/lib/starter_web/assets/images/pages/egrid/large/11.jpg +0 -0
  173. data/lib/starter_web/assets/images/pages/egrid/large/12.jpg +0 -0
  174. data/lib/starter_web/assets/images/pages/egrid/large/13.jpg +0 -0
  175. data/lib/starter_web/assets/images/pages/egrid/large/14.jpg +0 -0
  176. data/lib/starter_web/assets/images/pages/egrid/large/15.jpg +0 -0
  177. data/lib/starter_web/assets/images/pages/egrid/large/16.jpg +0 -0
  178. data/lib/starter_web/assets/images/pages/egrid/large/17.jpg +0 -0
  179. data/lib/starter_web/assets/images/pages/egrid/large/18.jpg +0 -0
  180. data/lib/starter_web/assets/images/pages/egrid/large/19.jpg +0 -0
  181. data/lib/starter_web/assets/images/pages/egrid/large/2.jpg +0 -0
  182. data/lib/starter_web/assets/images/pages/egrid/large/20.jpg +0 -0
  183. data/lib/starter_web/assets/images/pages/egrid/large/3.jpg +0 -0
  184. data/lib/starter_web/assets/images/pages/egrid/large/4.jpg +0 -0
  185. data/lib/starter_web/assets/images/pages/egrid/large/5.jpg +0 -0
  186. data/lib/starter_web/assets/images/pages/egrid/large/6.jpg +0 -0
  187. data/lib/starter_web/assets/images/pages/egrid/large/7.jpg +0 -0
  188. data/lib/starter_web/assets/images/pages/egrid/large/8.jpg +0 -0
  189. data/lib/starter_web/assets/images/pages/egrid/large/9.jpg +0 -0
  190. data/lib/starter_web/assets/images/pages/egrid/loading.gif +0 -0
  191. data/lib/starter_web/assets/images/pages/egrid/loading_dark.gif +0 -0
  192. data/lib/starter_web/assets/images/pages/egrid/nav-icon.png +0 -0
  193. data/lib/starter_web/assets/images/pages/egrid/nav.png +0 -0
  194. data/lib/starter_web/assets/images/pages/egrid/small/1.jpg +0 -0
  195. data/lib/starter_web/assets/images/pages/egrid/small/10.jpg +0 -0
  196. data/lib/starter_web/assets/images/pages/egrid/small/11.jpg +0 -0
  197. data/lib/starter_web/assets/images/pages/egrid/small/12.jpg +0 -0
  198. data/lib/starter_web/assets/images/pages/egrid/small/13.jpg +0 -0
  199. data/lib/starter_web/assets/images/pages/egrid/small/14.jpg +0 -0
  200. data/lib/starter_web/assets/images/pages/egrid/small/15.jpg +0 -0
  201. data/lib/starter_web/assets/images/pages/egrid/small/16.jpg +0 -0
  202. data/lib/starter_web/assets/images/pages/egrid/small/17.jpg +0 -0
  203. data/lib/starter_web/assets/images/pages/egrid/small/18.jpg +0 -0
  204. data/lib/starter_web/assets/images/pages/egrid/small/19.jpg +0 -0
  205. data/lib/starter_web/assets/images/pages/egrid/small/1a.jpg +0 -0
  206. data/lib/starter_web/assets/images/pages/egrid/small/2.jpg +0 -0
  207. data/lib/starter_web/assets/images/pages/egrid/small/20.jpg +0 -0
  208. data/lib/starter_web/assets/images/pages/egrid/small/3.jpg +0 -0
  209. data/lib/starter_web/assets/images/pages/egrid/small/4.jpg +0 -0
  210. data/lib/starter_web/assets/images/pages/egrid/small/5.jpg +0 -0
  211. data/lib/starter_web/assets/images/pages/egrid/small/6.jpg +0 -0
  212. data/lib/starter_web/assets/images/pages/egrid/small/7.jpg +0 -0
  213. data/lib/starter_web/assets/images/pages/egrid/small/8.jpg +0 -0
  214. data/lib/starter_web/assets/images/pages/egrid/small/9.jpg +0 -0
  215. data/lib/starter_web/assets/images/pages/roundtrip/500_themes/themes-menu-1280x800.jpg +0 -0
  216. data/lib/starter_web/assets/images/promo/home/screenshot.jpg +0 -0
  217. data/lib/starter_web/assets/images/promo/jekyll/jekyll-generator.png +0 -0
  218. data/lib/starter_web/assets/images/promo/jekyll/jekyll-og.png +0 -0
  219. data/lib/starter_web/collections/asciidoc_skeletons/simple-post/_posts/yyyy-mm-dd-your-post-name.asciidoc +13 -10
  220. data/lib/starter_web/collections/posts/public/featured/_posts/0000-00-00-welcome-to-j1.adoc.erb +8 -3
  221. data/lib/starter_web/collections/posts/public/featured/_posts/2021-01-01-about-cookies.adoc +11 -6
  222. data/lib/starter_web/collections/posts/public/featured/_posts/2021-02-01-site-generators.adoc +13 -10
  223. data/lib/starter_web/collections/posts/public/featured/_posts/2022-02-01-about-j1.adoc +12 -9
  224. data/lib/starter_web/collections/posts/public/featured/_posts/_includes/attributes.asciidoc +2 -2
  225. data/lib/starter_web/collections/posts/public/series/_posts/2020-01-01-post-wiki-series.adoc +13 -5
  226. data/lib/starter_web/collections/posts/public/series/_posts/2020-01-02-post-wiki-series.adoc +13 -6
  227. data/lib/starter_web/collections/posts/public/series/_posts/2020-01-03-post-wiki-series.adoc +13 -6
  228. data/lib/starter_web/index.html +85 -60
  229. data/lib/starter_web/package.json +1 -1
  230. data/lib/starter_web/pages/public/about/features.adoc +15 -7
  231. data/lib/starter_web/pages/public/about/reporting_issues.adoc +13 -5
  232. data/lib/starter_web/pages/public/about/site.adoc +2 -6
  233. data/lib/starter_web/pages/public/asciidoc_skeletons/documentation/000_intro.adoc +14 -7
  234. data/lib/starter_web/pages/public/asciidoc_skeletons/documentation/100_converter.adoc +15 -7
  235. data/lib/starter_web/pages/public/asciidoc_skeletons/documentation/200_themes.adoc +14 -6
  236. data/lib/starter_web/pages/public/asciidoc_skeletons/documentation/_includes/documents/100_converter/111_about_the_converter.asciidoc +15 -10
  237. data/lib/starter_web/pages/public/asciidoc_skeletons/documentation/documentation.adoc +9 -8
  238. data/lib/starter_web/pages/public/asciidoc_skeletons/multi-document/multi.adoc +9 -8
  239. data/lib/starter_web/pages/public/asciidoc_skeletons/simple-document/simple.adoc +9 -8
  240. data/lib/starter_web/pages/public/blog/navigator/{archive.html → archive/allview.html} +53 -26
  241. data/lib/starter_web/pages/public/blog/navigator/archive/categoryview.html +45 -20
  242. data/lib/starter_web/pages/public/blog/navigator/archive/dateview.html +49 -19
  243. data/lib/starter_web/pages/public/blog/navigator/archive/tagview.html +57 -53
  244. data/lib/starter_web/pages/public/blog/navigator/index.html +212 -35
  245. data/lib/starter_web/pages/public/features/general.adoc +12 -30
  246. data/lib/starter_web/pages/public/features/template.adoc +9 -33
  247. data/lib/starter_web/pages/public/learn/quickstart.adoc +10 -8
  248. data/lib/starter_web/pages/public/learn/roundtrip/_includes/attributes.asciidoc +0 -7
  249. data/lib/starter_web/pages/public/learn/roundtrip/_includes/documents/410_table_bs_modal_examples.asciidoc +2 -2
  250. data/lib/starter_web/pages/public/learn/roundtrip/_includes/documents/themes_bootstrap.asciidoc +51 -0
  251. data/lib/starter_web/pages/public/learn/roundtrip/_includes/documents/themes_rouge.asciidoc +110 -0
  252. data/lib/starter_web/pages/public/learn/roundtrip/asciidoc_extensions.adoc +11 -9
  253. data/lib/starter_web/pages/public/learn/roundtrip/bootstrap_themes.adoc +80 -0
  254. data/lib/starter_web/pages/public/learn/roundtrip/icon_fonts.adoc +9 -7
  255. data/lib/starter_web/pages/public/learn/roundtrip/{quicksearch.adoc → lunr_search.adoc} +23 -18
  256. data/lib/starter_web/pages/public/learn/roundtrip/{bs_modals_extentions.adoc → modal_extentions.adoc} +23 -24
  257. data/lib/starter_web/pages/public/learn/roundtrip/present_images.adoc +12 -11
  258. data/lib/starter_web/pages/public/learn/roundtrip/present_videos.adoc +14 -10
  259. data/lib/starter_web/pages/public/learn/roundtrip/{responsive_tables_extensions.adoc → responsive_tables.adoc} +16 -13
  260. data/lib/starter_web/pages/public/learn/roundtrip/{typography.adoc → template_typography.adoc} +8 -7
  261. data/lib/starter_web/pages/public/learn/where_to_go.adoc +12 -29
  262. data/lib/starter_web/pages/public/legal/de/100_copyright.adoc +1 -1
  263. data/lib/starter_web/pages/public/legal/de/100_impress.adoc +1 -1
  264. data/lib/starter_web/pages/public/legal/de/300_privacy.adoc +1 -1
  265. data/lib/starter_web/pages/public/legal/de/400_comment_policy.adoc +3 -1
  266. data/lib/starter_web/pages/public/legal/en/100_copyright.adoc +7 -5
  267. data/lib/starter_web/pages/public/legal/en/200_impress.adoc +7 -5
  268. data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +7 -5
  269. data/lib/starter_web/pages/public/legal/en/400_comment_policy.adoc +9 -5
  270. data/lib/starter_web/pages/public/panels/intro_panel/panel.adoc +11 -10
  271. data/lib/starter_web/pages/public/plans/plans.adoc +8 -5
  272. data/lib/starter_web/pages/public/previewer/preview_bootstrap_theme.adoc +15 -38
  273. data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
  274. data/lib/starter_web/utilsrv/package.json +1 -1
  275. metadata +170 -128
  276. data/_includes/themes/j1/blocks/footer/generator.html +0 -151
  277. data/_includes/themes/j1/layouts/content_generator_app.html +0 -32
  278. data/_includes/themes/j1/layouts/content_generator_article_navigator.html +0 -176
  279. data/_includes/themes/j1/layouts/content_generator_blog_archive.html +0 -251
  280. data/_layouts/app.html +0 -65
  281. data/_layouts/article_navigator.html +0 -66
  282. data/_layouts/blog_archive.html +0 -64
  283. data/assets/data/article_navigator/index.html +0 -51
  284. data/lib/starter_web/_data/layouts/app.yml +0 -172
  285. data/lib/starter_web/_data/layouts/article_navigator.yml +0 -173
  286. data/lib/starter_web/_data/layouts/blog_archive.yml +0 -191
  287. data/lib/starter_web/_includes/custom/static/custom_teaser.html +0 -64
  288. data/lib/starter_web/assets/images/banner/scalable/readme +0 -0
  289. data/lib/starter_web/assets/images/collections/blog/featured/dynamic-web-access.jpg +0 -0
  290. data/lib/starter_web/assets/images/collections/blog/featured/jamstack-generators-2.jpg +0 -0
  291. data/lib/starter_web/assets/images/collections/blog/featured/markus-spiske-2.jpg +0 -0
  292. data/lib/starter_web/assets/images/collections/blog/featured/static-web-access.jpg +0 -0
  293. data/lib/starter_web/assets/images/collections/blog/featured/welcome-to-j1-template.jpg +0 -0
  294. data/lib/starter_web/assets/images/collections/blog/featured/what-is-a-baseurl.jpg +0 -0
  295. data/lib/starter_web/assets/images/collections/blog/series/j1_using_docker/j1_docker_banner.1280x500.png +0 -0
  296. data/lib/starter_web/assets/images/collections/blog/series/j1_using_docker/kinematic_alpha.1280x600.png +0 -0
  297. data/lib/starter_web/assets/images/collections/blog/series/j1_using_docker/kinematic_j1.1280x300.png +0 -0
  298. data/lib/starter_web/assets/images/collections/blog/series/j1_using_docker/windows_docker_banner.1280x500.png +0 -0
  299. data/lib/starter_web/assets/images/modules/attics/1920x1280/moritz-kindler.jpg +0 -0
  300. data/lib/starter_web/assets/videos/gallery/dailymotion/meditation.jpg +0 -0
  301. data/lib/starter_web/assets/videos/gallery/dailymotion/pilates.jpg +0 -0
  302. data/lib/starter_web/assets/videos/gallery/html5/video1.mp4 +0 -0
  303. data/lib/starter_web/assets/videos/gallery/html5/video2.mp4 +0 -0
  304. data/lib/starter_web/assets/videos/gallery/kick-it-old-school-poster.jpg +0 -0
  305. data/lib/starter_web/assets/videos/gallery/nye-party-shop-poster.jpg +0 -0
  306. data/lib/starter_web/assets/videos/gallery/stay-colorful-poster.jpg +0 -0
  307. data/lib/starter_web/assets/videos/gallery/video1-poster.jpg +0 -0
  308. data/lib/starter_web/assets/videos/gallery/video1-thumb.jpg +0 -0
  309. data/lib/starter_web/assets/videos/gallery/video2-poster.jpg +0 -0
  310. data/lib/starter_web/assets/videos/gallery/video2-thumb.jpg +0 -0
  311. data/lib/starter_web/assets/videos/gallery/video_adele-poster.jpg +0 -0
  312. data/lib/starter_web/assets/videos/gallery/video_gaga-poster.jpg +0 -0
  313. data/lib/starter_web/assets/videos/gallery/video_gwen-poster.jpg +0 -0
  314. data/lib/starter_web/assets/videos/gallery/video_michelle-poster.jpg +0 -0
  315. data/lib/starter_web/assets/videos/gallery/vk/hai.jpg +0 -0
  316. data/lib/starter_web/assets/videos/gallery/vk/otter.jpg +0 -0
  317. data/lib/starter_web/assets/videos/gallery/voice_kids_de_2021/battle.jpg +0 -0
  318. data/lib/starter_web/assets/videos/gallery/voice_kids_de_2021/ben.jpg +0 -0
  319. data/lib/starter_web/assets/videos/gallery/voice_kids_de_2021/constance.jpg +0 -0
  320. data/lib/starter_web/assets/videos/gallery/voice_kids_de_2021/elisa.jpg +0 -0
  321. data/lib/starter_web/assets/videos/headers/present_videos/still/underground-broadway.jpg +0 -0
  322. data/lib/starter_web/assets/videos/headers/present_videos/underground-broadway.mp4 +0 -0
  323. data/lib/starter_web/assets/videos/tiktok/einhorn.jpg +0 -0
  324. data/lib/starter_web/assets/videos/tiktok/waluschka.jpg +0 -0
  325. data/lib/starter_web/pages/public/jupyter/examples/distributed/j1-circular-times-table.adoc +0 -142
  326. data/lib/starter_web/pages/public/jupyter/examples/distributed/j1-common-used-widgets.adoc +0 -232
  327. data/lib/starter_web/pages/public/jupyter/examples/distributed/j1-odes-in-python.adoc +0 -115
  328. data/lib/starter_web/pages/public/jupyter/examples/localized/j1_climate-change-forecast.adoc +0 -109
  329. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_circular_times_table.ipynb +0 -12382
  330. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_climate_change_forecast.ipynb +0 -1058
  331. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_docs_example_dynamic.ipynb +0 -14478
  332. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_interactive_widgets.ipynb +0 -442
  333. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_nbi_widgets.ipynb +0 -523
  334. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_nbi_widgets_bar_chart.ipynb +0 -89
  335. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_nbi_widgets_hist_chart.ipynb +0 -87
  336. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_nbi_widgets_line_chart.ipynb +0 -90
  337. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_nbi_widgets_question_multiple_choice.ipynb +0 -64
  338. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_nbi_widgets_question_short_answer.ipynb +0 -122
  339. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_nbi_widgets_scatter_chart.ipynb +0 -89
  340. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_nbi_widgets_scatter_drag_chart.ipynb +0 -87
  341. data/lib/starter_web/pages/public/jupyter/notebooks/j1/j1_odes_in_python.ipynb +0 -15227
  342. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_circular_times_table.html +0 -747
  343. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_climate_change_forecast.html +0 -1250
  344. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_docs_example_dynamic.html +0 -186
  345. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_interactive_widgets.html +0 -512
  346. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_nbi_widgets.html +0 -629
  347. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_nbi_widgets_bar_chart.html +0 -95
  348. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_nbi_widgets_hist_chart.html +0 -93
  349. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_nbi_widgets_line_chart.html +0 -96
  350. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_nbi_widgets_question_multiple_choice.html +0 -70
  351. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_nbi_widgets_question_short_answer.html +0 -156
  352. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_nbi_widgets_scatter_chart.html +0 -95
  353. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_nbi_widgets_scatter_drag_chart.html +0 -93
  354. data/lib/starter_web/pages/public/jupyter/notebooks/textbooks/j1_odes_in_python.html +0 -955
  355. data/lib/starter_web/pages/public/jupyter/where_to_go.adoc +0 -232
  356. data/lib/starter_web/pages/public/learn/roundtrip/_includes/google-ad.js +0 -130
  357. data/lib/starter_web/pages/public/learn/roundtrip/themes.adoc +0 -253
  358. data/lib/starter_web/pages/public/se/se-fake.adoc +0 -48
@@ -0,0 +1,717 @@
1
+ # ------------------------------------------------------------------------------
2
+ # ~/_plugins/j1-seo-tags.rb
3
+ # Generate SEO tags for posts and pages of a site
4
+ #
5
+ # Product/Info:
6
+ # http://jekyll.one
7
+ #
8
+ # Copyright (C) 2022 Ben Balter and Contributors
9
+ # Copyright (C) 2022 Juergen Adams
10
+ #
11
+ # J1 Template is licensed under the MIT License.
12
+ # See: https://github.com/jekyll-one-org/J1 Template/blob/master/LICENSE
13
+ # ------------------------------------------------------------------------------
14
+ # frozen_string_literal: true
15
+
16
+ require "jekyll"
17
+
18
+ module Jekyll
19
+ class SeoTag < Liquid::Tag
20
+ attr_accessor :context
21
+
22
+ @project_path = File.join(File.dirname(__FILE__)).sub('_plugins/seo', '')
23
+ @module_data_path = File.join(File.join(@project_path, '_data'))
24
+ @module_config_path = File.join(File.join(@module_data_path, 'plugins'))
25
+ @module_template_path = File.join(File.join(@module_data_path, 'templates'))
26
+ @module_config_default = YAML::load(File.open(File.join(@module_config_path, 'defaults', 'seo-tags.yml')))
27
+ @module_config_user = YAML::load(File.open(File.join(@module_config_path, 'seo-tags.yml')))
28
+
29
+ @module_config_default_settings = @module_config_default['defaults']
30
+ @module_config_user_settings = @module_config_user['settings']
31
+ @module_config = @module_config_default_settings.merge!(@module_config_user_settings)
32
+
33
+ # Matches all whitespace that follows either
34
+ # 1. A '}', which closes a Liquid tag
35
+ # 2. A '{', which opens a JSON block
36
+ # 3. A '>' followed by a newline, which closes an XML tag or
37
+ # 4. A ',' followed by a newline, which ends a JSON line
38
+ # We will strip all of this whitespace to minify the template
39
+ # We will not strip any whitespace if the next character is a '-'
40
+ # so that we do not interfere with the HTML comment at the
41
+ # very beginning
42
+ MINIFY_REGEX = %r!(?<=[{}]|[>,]\n)\s+(?\!-)!.freeze
43
+
44
+ def initialize(_tag_name, text, _tokens)
45
+ super
46
+ @text = text
47
+ end
48
+
49
+ def render(context)
50
+ @context = context
51
+ SeoTag.template.render!(payload, info)
52
+ end
53
+
54
+ private
55
+
56
+ def options
57
+ {
58
+ "title" => title?,
59
+ }
60
+ end
61
+
62
+ def payload
63
+ # site_payload is an instance of UnifiedPayloadDrop. See https://github.com/jekyll/jekyll/blob/22f2724a1f117a94cc16d18c499a93d5915ede4f/lib/jekyll/site.rb#L261-L276
64
+ context.registers[:site].site_payload.tap do |site_payload|
65
+ site_payload["page"] = context.registers[:page]
66
+ site_payload["paginator"] = context["paginator"]
67
+ site_payload["seo_tag"] = drop
68
+ end
69
+ end
70
+
71
+ def drop
72
+ if context.registers[:site].liquid_renderer.respond_to?(:cache)
73
+ Jekyll::SeoTag::Drop.new(@text, @context)
74
+ else
75
+ @drop ||= Jekyll::SeoTag::Drop.new(@text, @context)
76
+ end
77
+ end
78
+
79
+ def info
80
+ {
81
+ :registers => context.registers,
82
+ :filters => [Jekyll::Filters],
83
+ }
84
+ end
85
+
86
+ class << self
87
+ def template
88
+ @template ||= Liquid::Template.parse template_contents
89
+ end
90
+
91
+ private
92
+
93
+ def template_contents
94
+ @template_contents ||= begin
95
+ File.read(template_path).gsub(MINIFY_REGEX, "")
96
+ end
97
+ end
98
+
99
+ def template_path
100
+ @template_path ||= File.expand_path @module_config['template_name'], @module_template_path
101
+ end
102
+ end
103
+
104
+ end
105
+ end
106
+
107
+ Liquid::Template.register_tag("seo", Jekyll::SeoTag)
108
+
109
+ module Jekyll
110
+ class SeoTag
111
+ # A drop representing the current page's author
112
+ #
113
+ # Author name will be pulled from:
114
+ #
115
+ # 1. The page's `author` key
116
+ # 2. The first author in the page's `authors` key
117
+ # 3. The `author` key in the site config
118
+ #
119
+ # If the result from the name search is a string, we'll also check
120
+ # for additional author metadata in `site.data.authors`
121
+ class AuthorDrop < Jekyll::Drops::Drop
122
+ # Initialize a new AuthorDrop
123
+ #
124
+ # page - The page hash (e.g., Page#to_liquid)
125
+ # site - The Jekyll::Drops::SiteDrop
126
+ def initialize(page: nil, site: nil)
127
+ raise ArgumentError unless page && site
128
+
129
+ @mutations = {}
130
+ @page = page
131
+ @site = site
132
+ end
133
+
134
+ # AuthorDrop#to_s should return name, allowing the author drop to safely
135
+ # replace `page.author`, if necessary, and remain backwards compatible
136
+ def name
137
+ author_hash["name"]
138
+ end
139
+ alias_method :to_s, :name
140
+
141
+ def twitter
142
+ return @twitter if defined? @twitter
143
+
144
+ twitter = author_hash["twitter"] || author_hash["name"]
145
+ @twitter = twitter.is_a?(String) ? twitter.sub(%r!^@!, "") : nil
146
+ end
147
+
148
+ private
149
+
150
+ attr_reader :site, :page
151
+
152
+ # Finds the page author in the page.author, page.authors, or site.author
153
+ #
154
+ # Returns a string or hash representing the author
155
+ def resolved_author
156
+ return @resolved_author if defined? @resolved_author
157
+
158
+ sources = [page["author"]]
159
+ sources << page["authors"].first if page["authors"].is_a?(Array)
160
+ sources << site["author"]
161
+ @resolved_author = sources.find { |s| !s.to_s.empty? }
162
+ end
163
+
164
+ # If resolved_author is a string, attempts to find corresponding author
165
+ # metadata in `site.data.authors`
166
+ #
167
+ # Returns a hash representing additional metadata or an empty hash
168
+ def site_data_hash
169
+ @site_data_hash ||= begin
170
+ return {} unless resolved_author.is_a?(String)
171
+ return {} unless site.data["authors"].is_a?(Hash)
172
+
173
+ author_hash = site.data["authors"][resolved_author]
174
+ author_hash.is_a?(Hash) ? author_hash : {}
175
+ end
176
+ end
177
+
178
+ # Returns the normalized author hash representing the page author,
179
+ # including site-wide metadata if the author is provided as a string,
180
+ # or an empty hash, if the author cannot be resolved
181
+ def author_hash
182
+ @author_hash ||= begin
183
+ case resolved_author
184
+ when Hash
185
+ resolved_author
186
+ when String
187
+ { "name" => resolved_author }.merge!(site_data_hash)
188
+ else
189
+ {}
190
+ end
191
+ end
192
+ end
193
+
194
+ # Since author_hash is aliased to fallback_data, any values in the hash
195
+ # will be exposed via the drop, allowing support for arbitrary metadata
196
+ alias_method :fallback_data, :author_hash
197
+ end
198
+ end
199
+ end
200
+
201
+
202
+ module Jekyll
203
+ class SeoTag
204
+
205
+ module UrlHelper
206
+ private
207
+
208
+ # Determines if the given string is an absolute URL
209
+ #
210
+ # Returns true if an absolute URL
211
+ # Returns false if it's a relative URL
212
+ # Returns nil if it is not a string or can't be parsed as a URL
213
+ def absolute_url?(string)
214
+ return unless string
215
+
216
+ Addressable::URI.parse(string).absolute?
217
+ rescue Addressable::URI::InvalidURIError
218
+ nil
219
+ end
220
+ end
221
+
222
+ class Drop < Jekyll::Drops::Drop
223
+ include Jekyll::SeoTag::UrlHelper
224
+
225
+ TITLE_SEPARATOR = " | "
226
+ FORMAT_STRING_METHODS = [
227
+ :markdownify, :strip_html, :normalize_whitespace, :escape_once,
228
+ ].freeze
229
+ HOMEPAGE_OR_ABOUT_REGEX = %r!^/(about/)?(index.html?)?$!.freeze
230
+
231
+ EMPTY_READ_ONLY_HASH = {}.freeze
232
+ private_constant :EMPTY_READ_ONLY_HASH
233
+
234
+ def initialize(text, context)
235
+ @obj = EMPTY_READ_ONLY_HASH
236
+ @mutations = {}
237
+ @text = text
238
+ @context = context
239
+ end
240
+
241
+ def version
242
+ Jekyll::SeoTag::VERSION
243
+ end
244
+
245
+ # Should the `<title>` tag be generated for this page?
246
+ def title?
247
+ return false unless title
248
+ return @display_title if defined?(@display_title)
249
+
250
+ @display_title = (@text !~ %r!title=false!i)
251
+ end
252
+
253
+ def site_title
254
+ @site_title ||= format_string(site["title"] || site["name"])
255
+ end
256
+
257
+ def site_tagline
258
+ @site_tagline ||= format_string site["tagline"]
259
+ end
260
+
261
+ def site_description
262
+ @site_description ||= format_string site["description"]
263
+ end
264
+
265
+ # Page title without site title or description appended
266
+ def page_title
267
+ @page_title ||= format_string(page["title"]) || site_title
268
+ end
269
+
270
+ def site_tagline_or_description
271
+ site_tagline || site_description
272
+ end
273
+
274
+ # Page title with site title or description appended
275
+ # rubocop:disable Metrics/CyclomaticComplexity
276
+ def title
277
+ @title ||= begin
278
+ if site_title && page_title != site_title
279
+ page_title + TITLE_SEPARATOR + site_title
280
+ elsif site_description && site_title
281
+ site_title + TITLE_SEPARATOR + site_tagline_or_description
282
+ else
283
+ page_title || site_title
284
+ end
285
+ end
286
+
287
+ return page_number + @title if page_number
288
+
289
+ @title
290
+ end
291
+ # rubocop:enable Metrics/CyclomaticComplexity
292
+
293
+ def name
294
+ return @name if defined?(@name)
295
+
296
+ @name = if seo_name
297
+ seo_name
298
+ elsif !homepage_or_about?
299
+ nil
300
+ elsif site_social["name"]
301
+ format_string site_social["name"]
302
+ elsif site_title
303
+ site_title
304
+ end
305
+ end
306
+
307
+ def description
308
+ @description ||= begin
309
+ format_string(page["description"] || page["excerpt"]) || site_description
310
+ end
311
+ end
312
+
313
+ # A drop representing the page author
314
+ def author
315
+ @author ||= AuthorDrop.new(:page => page, :site => site)
316
+ end
317
+
318
+ # A drop representing the JSON-LD output
319
+ def json_ld
320
+ @json_ld ||= JSONLDDrop.new(self)
321
+ end
322
+
323
+ # Returns a Drop representing the page's image
324
+ # Returns nil if the image has no path, to preserve backwards compatability
325
+ def image
326
+ @image ||= ImageDrop.new(:page => page, :context => @context)
327
+ @image if @image.path
328
+ end
329
+
330
+ def date_modified
331
+ @date_modified ||= begin
332
+ date = page_seo["date_modified"] || page["last_modified_at"].to_liquid || page["date"]
333
+ filters.date_to_xmlschema(date) if date
334
+ end
335
+ end
336
+
337
+ def date_published
338
+ @date_published ||= filters.date_to_xmlschema(page["date"]) if page["date"]
339
+ end
340
+
341
+ def type
342
+ @type ||= begin
343
+ if page_seo["type"]
344
+ page_seo["type"]
345
+ elsif homepage_or_about?
346
+ "WebSite"
347
+ elsif page["date"]
348
+ "BlogPosting"
349
+ else
350
+ "WebPage"
351
+ end
352
+ end
353
+ end
354
+
355
+ def links
356
+ @links ||= begin
357
+ if page_seo["links"]
358
+ page_seo["links"]
359
+ elsif homepage_or_about? && site_social["links"]
360
+ site_social["links"]
361
+ end
362
+ end
363
+ end
364
+
365
+ def logo
366
+ @logo ||= begin
367
+ return unless site["logo"]
368
+
369
+ if absolute_url? site["logo"]
370
+ filters.uri_escape site["logo"]
371
+ else
372
+ filters.uri_escape filters.absolute_url site["logo"]
373
+ end
374
+ end
375
+ end
376
+
377
+ def page_lang
378
+ @page_lang ||= page["lang"] || site["lang"] || "en_US"
379
+ end
380
+
381
+ def page_locale
382
+ @page_locale ||= (page["locale"] || site["locale"] || page_lang).tr("-", "_")
383
+ end
384
+
385
+ def canonical_url
386
+ @canonical_url ||= begin
387
+ if page["canonical_url"].to_s.empty?
388
+ filters.absolute_url(page["url"]).to_s.gsub(%r!/index\.html$!, "/")
389
+ else
390
+ page["canonical_url"]
391
+ end
392
+ end
393
+ end
394
+
395
+ private
396
+
397
+ def filters
398
+ @filters ||= Jekyll::SeoTag::Filters.new(@context)
399
+ end
400
+
401
+ def page
402
+ @page ||= @context.registers[:page].to_liquid
403
+ end
404
+
405
+ def site
406
+ @site ||= @context.registers[:site].site_payload["site"].to_liquid
407
+ end
408
+
409
+ def homepage_or_about?
410
+ page["url"] =~ HOMEPAGE_OR_ABOUT_REGEX
411
+ end
412
+
413
+ def page_number
414
+ return unless @context["paginator"] && @context["paginator"]["page"]
415
+
416
+ current = @context["paginator"]["page"]
417
+ total = @context["paginator"]["total_pages"]
418
+ paginator_message = site["seo_paginator_message"] || "Page %<current>s of %<total>s for "
419
+
420
+ format(paginator_message, :current => current, :total => total) if current > 1
421
+ end
422
+
423
+ attr_reader :context
424
+
425
+ def fallback_data
426
+ @fallback_data ||= {}
427
+ end
428
+
429
+ def format_string(string)
430
+ string = FORMAT_STRING_METHODS.reduce(string) do |memo, method|
431
+ filters.public_send(method, memo)
432
+ end
433
+
434
+ string unless string.empty?
435
+ end
436
+
437
+ def seo_name
438
+ @seo_name ||= format_string(page_seo["name"]) if page_seo["name"]
439
+ end
440
+
441
+ def page_seo
442
+ @page_seo ||= sub_hash(page, "seo")
443
+ end
444
+
445
+ def site_social
446
+ @site_social ||= sub_hash(site, "social")
447
+ end
448
+
449
+ # Safely returns a sub hash
450
+ #
451
+ # hash - the parent hash
452
+ # key - the key in the parent hash
453
+ #
454
+ # Returns the sub hash or an empty hash, if it does not exist
455
+ def sub_hash(hash, key)
456
+ if hash[key].is_a?(Hash)
457
+ hash[key]
458
+ else
459
+ EMPTY_READ_ONLY_HASH
460
+ end
461
+ end
462
+ end
463
+ end
464
+ end
465
+
466
+
467
+ module Jekyll
468
+ class SeoTag
469
+ class Filters
470
+ include Jekyll::Filters
471
+ include Liquid::StandardFilters
472
+
473
+ def initialize(context)
474
+ @context = context
475
+ end
476
+ end
477
+ end
478
+ end
479
+
480
+
481
+ module Jekyll
482
+ class SeoTag
483
+ # A drop representing the page image
484
+ # The image path will be pulled from:
485
+ #
486
+ # 1. The `image` key if it's a string
487
+ # 2. The `image.path` key if it's a hash
488
+ # 3. The `image.facebook` key
489
+ # 4. The `image.twitter` key
490
+ class ImageDrop < Jekyll::Drops::Drop
491
+ include Jekyll::SeoTag::UrlHelper
492
+
493
+ # Initialize a new ImageDrop
494
+ #
495
+ # page - The page hash (e.g., Page#to_liquid)
496
+ # context - the Liquid::Context
497
+ def initialize(page: nil, context: nil)
498
+ raise ArgumentError unless page && context
499
+
500
+ @mutations = {}
501
+ @page = page
502
+ @context = context
503
+ end
504
+
505
+ # Called path for backwards compatability, this is really
506
+ # the escaped, absolute URL representing the page's image
507
+ # Returns nil if no image path can be determined
508
+ def path
509
+ @path ||= filters.uri_escape(absolute_url) if absolute_url
510
+ end
511
+ alias_method :to_s, :path
512
+
513
+ private
514
+
515
+ attr_accessor :page, :context
516
+
517
+ # The normalized image hash with a `path` key (which may be nil)
518
+ def image_hash
519
+ @image_hash ||= begin
520
+ image_meta = page["image"]
521
+
522
+ case image_meta
523
+ when Hash
524
+ { "path" => nil }.merge!(image_meta)
525
+ when String
526
+ { "path" => image_meta }
527
+ else
528
+ { "path" => nil }
529
+ end
530
+ end
531
+ end
532
+ alias_method :fallback_data, :image_hash
533
+
534
+ def raw_path
535
+ @raw_path ||= begin
536
+ image_hash["path"] || image_hash["facebook"] || image_hash["twitter"]
537
+ end
538
+ end
539
+
540
+ def absolute_url
541
+ return unless raw_path
542
+ @absolute_url ||= build_absolute_path
543
+ end
544
+
545
+ def build_absolute_path
546
+ return raw_path unless raw_path.is_a?(String) && absolute_url?(raw_path) == false
547
+ return filters.absolute_url(raw_path) if raw_path.start_with?("/")
548
+
549
+ page_dir = @page["url"]
550
+ page_dir = File.dirname(page_dir) unless page_dir.end_with?("/")
551
+
552
+ filters.absolute_url File.join(page_dir, raw_path)
553
+ end
554
+
555
+ def filters
556
+ @filters ||= Jekyll::SeoTag::Filters.new(context)
557
+ end
558
+ end
559
+ end
560
+ end
561
+
562
+
563
+ module Jekyll
564
+ class SeoTag
565
+ class JSONLDDrop < Jekyll::Drops::Drop
566
+ extend Forwardable
567
+
568
+ def_delegator :page_drop, :name, :name
569
+ def_delegator :page_drop, :description, :description
570
+ def_delegator :page_drop, :canonical_url, :url
571
+ def_delegator :page_drop, :page_title, :headline
572
+ def_delegator :page_drop, :date_modified, :dateModified
573
+ def_delegator :page_drop, :date_published, :datePublished
574
+ def_delegator :page_drop, :links, :sameAs
575
+ def_delegator :page_drop, :logo, :logo
576
+ def_delegator :page_drop, :type, :type
577
+
578
+ # Expose #type and #logo as private methods and #@type as a public method
579
+ alias_method :@type, :type
580
+ private :type, :logo
581
+
582
+ VALID_ENTITY_TYPES = %w(BlogPosting CreativeWork).freeze
583
+ VALID_AUTHOR_TYPES = %w(Organization Person).freeze
584
+ private_constant :VALID_ENTITY_TYPES, :VALID_AUTHOR_TYPES
585
+
586
+ # page_drop should be an instance of Jekyll::SeoTag::Drop
587
+ def initialize(page_drop)
588
+ @mutations = {}
589
+ @page_drop = page_drop
590
+ end
591
+
592
+ def fallback_data
593
+ @fallback_data ||= {
594
+ "@context" => "https://schema.org",
595
+ }
596
+ end
597
+
598
+ def author
599
+ return unless page_drop.author["name"]
600
+
601
+ author_type = page_drop.author["type"]
602
+ return if author_type && !VALID_AUTHOR_TYPES.include?(author_type)
603
+
604
+ hash = {
605
+ "@type" => author_type || "Person",
606
+ "name" => page_drop.author["name"],
607
+ }
608
+
609
+ author_url = page_drop.author["url"]
610
+ hash["url"] = author_url if author_url
611
+
612
+ hash
613
+ end
614
+
615
+ def image
616
+ return unless page_drop.image
617
+ return page_drop.image.path if page_drop.image.keys.length == 1
618
+
619
+ hash = page_drop.image.to_h
620
+ hash["url"] = hash.delete("path")
621
+ hash["@type"] = "imageObject"
622
+ hash
623
+ end
624
+
625
+ def publisher
626
+ return unless logo
627
+
628
+ output = {
629
+ "@type" => "Organization",
630
+ "logo" => {
631
+ "@type" => "ImageObject",
632
+ "url" => logo,
633
+ },
634
+ }
635
+ output["name"] = page_drop.author.name if page_drop.author.name
636
+ output
637
+ end
638
+
639
+ def main_entity
640
+ return unless VALID_ENTITY_TYPES.include?(type)
641
+
642
+ {
643
+ "@type" => "WebPage",
644
+ "@id" => page_drop.canonical_url,
645
+ }
646
+ end
647
+ alias_method :mainEntityOfPage, :main_entity
648
+ private :main_entity
649
+
650
+ # Returns a JSON-encoded object containing the JSON-LD data.
651
+ # Keys are sorted.
652
+ def to_json(state = nil)
653
+ keys.sort.each_with_object({}) do |(key, _), result|
654
+ v = self[key]
655
+ result[key] = v unless v.nil?
656
+ end.to_json(state)
657
+ end
658
+
659
+ private
660
+
661
+ attr_reader :page_drop
662
+ end
663
+ end
664
+ end
665
+
666
+ # module Jekyll
667
+ # class SeoTag
668
+ # # This module is deprecated, but is included in the Gem to avoid a breaking
669
+ # # change and should be removed at the next major version bump
670
+ # module JSONLD
671
+ # METHODS_KEYS = {
672
+ # :json_context => "@context",
673
+ # :type => "@type",
674
+ # :name => "name",
675
+ # :page_title => "headline",
676
+ # :json_author => "author",
677
+ # :json_image => "image",
678
+ # :date_published => "datePublished",
679
+ # :date_modified => "dateModified",
680
+ # :description => "description",
681
+ # :publisher => "publisher",
682
+ # :main_entity => "mainEntityOfPage",
683
+ # :links => "sameAs",
684
+ # :canonical_url => "url",
685
+ # }.freeze
686
+ #
687
+ # # Self should be a Jekyll::SeoTag::Drop instance (when extending the module)
688
+ # def json_ld
689
+ # Jekyll.logger.warn "Jekyll::SeoTag::JSONLD is deprecated"
690
+ # @json_ld ||= JSONLDDrop.new(self)
691
+ # end
692
+ # end
693
+ # end
694
+ # end
695
+
696
+
697
+ # module Jekyll
698
+ # class SeoTag
699
+ # # Mixin to share common URL-related methods between class
700
+ # module UrlHelper
701
+ # private
702
+ #
703
+ # # Determines if the given string is an absolute URL
704
+ # #
705
+ # # Returns true if an absolute URL
706
+ # # Returns false if it's a relative URL
707
+ # # Returns nil if it is not a string or can't be parsed as a URL
708
+ # def absolute_url?(string)
709
+ # return unless string
710
+ #
711
+ # Addressable::URI.parse(string).absolute?
712
+ # rescue Addressable::URI::InvalidURIError
713
+ # nil
714
+ # end
715
+ # end
716
+ # end
717
+ # end