postnhost 0.0.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/{LICENSE.txt → LICENSE} +6 -6
  4. data/README.md +343 -15
  5. data/Rakefile +66 -6
  6. data/app/assets/builds/postnhost/application.css +2 -0
  7. data/app/assets/builds/postnhost/application.js +50190 -0
  8. data/app/assets/config/postnhost_manifest.js +2 -0
  9. data/app/assets/images/postnhost/demo.webp +0 -0
  10. data/app/assets/images/postnhost/icons/alert-circle.svg +3 -0
  11. data/app/assets/images/postnhost/icons/arrow-left-long.svg +3 -0
  12. data/app/assets/images/postnhost/icons/arrow-left.svg +3 -0
  13. data/app/assets/images/postnhost/icons/arrow-right-end-on-rectangle.svg +3 -0
  14. data/app/assets/images/postnhost/icons/arrow-right-long.svg +3 -0
  15. data/app/assets/images/postnhost/icons/arrow-right.svg +3 -0
  16. data/app/assets/images/postnhost/icons/bars.svg +3 -0
  17. data/app/assets/images/postnhost/icons/bluesky.svg +3 -0
  18. data/app/assets/images/postnhost/icons/check-circle.svg +3 -0
  19. data/app/assets/images/postnhost/icons/chevron-down-small.svg +3 -0
  20. data/app/assets/images/postnhost/icons/chevron-down.svg +3 -0
  21. data/app/assets/images/postnhost/icons/chevron-left.svg +3 -0
  22. data/app/assets/images/postnhost/icons/chevron-right.svg +3 -0
  23. data/app/assets/images/postnhost/icons/clock.svg +3 -0
  24. data/app/assets/images/postnhost/icons/close.svg +3 -0
  25. data/app/assets/images/postnhost/icons/code-bracket.svg +3 -0
  26. data/app/assets/images/postnhost/icons/document-text.svg +3 -0
  27. data/app/assets/images/postnhost/icons/drag-handle.svg +8 -0
  28. data/app/assets/images/postnhost/icons/edit.svg +3 -0
  29. data/app/assets/images/postnhost/icons/external-link.svg +3 -0
  30. data/app/assets/images/postnhost/icons/eye.svg +4 -0
  31. data/app/assets/images/postnhost/icons/facebook.svg +3 -0
  32. data/app/assets/images/postnhost/icons/folder.svg +3 -0
  33. data/app/assets/images/postnhost/icons/image.svg +3 -0
  34. data/app/assets/images/postnhost/icons/info-circle.svg +3 -0
  35. data/app/assets/images/postnhost/icons/instagram.svg +3 -0
  36. data/app/assets/images/postnhost/icons/language.svg +3 -0
  37. data/app/assets/images/postnhost/icons/layers.svg +3 -0
  38. data/app/assets/images/postnhost/icons/lightning.svg +3 -0
  39. data/app/assets/images/postnhost/icons/linkedin.svg +3 -0
  40. data/app/assets/images/postnhost/icons/logout.svg +3 -0
  41. data/app/assets/images/postnhost/icons/magnifying-glass.svg +3 -0
  42. data/app/assets/images/postnhost/icons/mastodon.svg +3 -0
  43. data/app/assets/images/postnhost/icons/menu.svg +3 -0
  44. data/app/assets/images/postnhost/icons/plus.svg +3 -0
  45. data/app/assets/images/postnhost/icons/schedule.svg +3 -0
  46. data/app/assets/images/postnhost/icons/settings.svg +4 -0
  47. data/app/assets/images/postnhost/icons/sparkles.svg +3 -0
  48. data/app/assets/images/postnhost/icons/spinner.svg +4 -0
  49. data/app/assets/images/postnhost/icons/threads.svg +3 -0
  50. data/app/assets/images/postnhost/icons/tiktok.svg +3 -0
  51. data/app/assets/images/postnhost/icons/tiptap/align-center.svg +3 -0
  52. data/app/assets/images/postnhost/icons/tiptap/align-left.svg +3 -0
  53. data/app/assets/images/postnhost/icons/tiptap/align-right.svg +3 -0
  54. data/app/assets/images/postnhost/icons/tiptap/apply-link.svg +3 -0
  55. data/app/assets/images/postnhost/icons/tiptap/blockquote.svg +3 -0
  56. data/app/assets/images/postnhost/icons/tiptap/bold.svg +3 -0
  57. data/app/assets/images/postnhost/icons/tiptap/bullet-list.svg +3 -0
  58. data/app/assets/images/postnhost/icons/tiptap/code-block.svg +3 -0
  59. data/app/assets/images/postnhost/icons/tiptap/code.svg +3 -0
  60. data/app/assets/images/postnhost/icons/tiptap/heading-2.svg +3 -0
  61. data/app/assets/images/postnhost/icons/tiptap/heading-3.svg +3 -0
  62. data/app/assets/images/postnhost/icons/tiptap/image-add.svg +3 -0
  63. data/app/assets/images/postnhost/icons/tiptap/italic.svg +3 -0
  64. data/app/assets/images/postnhost/icons/tiptap/link.svg +3 -0
  65. data/app/assets/images/postnhost/icons/tiptap/ordered-list.svg +3 -0
  66. data/app/assets/images/postnhost/icons/tiptap/redo.svg +3 -0
  67. data/app/assets/images/postnhost/icons/tiptap/remove-link.svg +3 -0
  68. data/app/assets/images/postnhost/icons/tiptap/strike.svg +3 -0
  69. data/app/assets/images/postnhost/icons/tiptap/table.svg +3 -0
  70. data/app/assets/images/postnhost/icons/tiptap/underline.svg +3 -0
  71. data/app/assets/images/postnhost/icons/tiptap/undo.svg +3 -0
  72. data/app/assets/images/postnhost/icons/tiptap/youtube.svg +4 -0
  73. data/app/assets/images/postnhost/icons/translate.svg +3 -0
  74. data/app/assets/images/postnhost/icons/trash.svg +3 -0
  75. data/app/assets/images/postnhost/icons/user.svg +4 -0
  76. data/app/assets/images/postnhost/icons/users.svg +3 -0
  77. data/app/assets/images/postnhost/icons/warning.svg +3 -0
  78. data/app/assets/images/postnhost/icons/x.svg +3 -0
  79. data/app/assets/images/postnhost/icons/youtube.svg +3 -0
  80. data/app/assets/images/postnhost/logo.webp +0 -0
  81. data/app/assets/images/postnhost/og-image.webp +0 -0
  82. data/app/assets/images/postnhost/sample-docs/08-how-to-control-suggested-articles-and-top-picks-01-discovery-controls.webp +0 -0
  83. data/app/assets/images/postnhost/sample-docs/09-all-about-authors-in-postnhost-01-author-profile.webp +0 -0
  84. data/app/assets/images/postnhost/sample-docs/09-all-about-authors-in-postnhost-02-multiple-authors.webp +0 -0
  85. data/app/assets/images/postnhost/sample-docs/11-how-to-schedule-an-article-for-publication-01-timezone.webp +0 -0
  86. data/app/assets/images/postnhost/sample-docs/11-how-to-schedule-an-article-for-publication-02-scheduled-article.webp +0 -0
  87. data/app/assets/images/postnhost/sample-docs/12-how-article-version-history-and-restores-work-01-version-history.webp +0 -0
  88. data/app/assets/images/postnhost/sample-docs/13-how-to-add-and-manage-languages-01-language-management.webp +0 -0
  89. data/app/assets/images/postnhost/sample-docs/14-how-to-translate-articles-pages-and-categories-01-translation-options.webp +0 -0
  90. data/app/assets/images/postnhost/sample-docs/14-how-to-translate-articles-pages-and-categories-02-ai-language-selection.webp +0 -0
  91. data/app/assets/images/postnhost/sample-docs/16-how-to-add-navigation-links-01-navigation-builder.webp +0 -0
  92. data/app/assets/images/postnhost/sample-docs/16-how-to-add-navigation-links-02-external-link-settings.webp +0 -0
  93. data/app/assets/images/postnhost/sample-docs/17-how-to-add-a-logo-and-default-og-image-01-assets-settings.webp +0 -0
  94. data/app/assets/images/postnhost/sample-docs/19-how-to-customize-public-text-for-each-language-01-i18n-overrides.webp +0 -0
  95. data/app/assets/images/postnhost/sample-docs/20-how-to-configure-structured-data-and-sitemap-seo-01-site-schema.webp +0 -0
  96. data/app/assets/images/postnhost/sample-docs/20-how-to-configure-structured-data-and-sitemap-seo-02-author-schema-defaults.webp +0 -0
  97. data/app/assets/images/postnhost/sample-docs/20-how-to-configure-structured-data-and-sitemap-seo-03-author-schema-advanced-fields.webp +0 -0
  98. data/app/assets/images/postnhost/sample-docs/covers/08-suggested-articles-and-top-picks.webp +0 -0
  99. data/app/assets/images/postnhost/sample-docs/covers/09-authors.webp +0 -0
  100. data/app/assets/images/postnhost/sample-docs/covers/11-scheduling.webp +0 -0
  101. data/app/assets/images/postnhost/sample-docs/covers/12-version-history.webp +0 -0
  102. data/app/assets/images/postnhost/sample-docs/covers/13-languages.webp +0 -0
  103. data/app/assets/images/postnhost/sample-docs/covers/14-translations.webp +0 -0
  104. data/app/assets/images/postnhost/sample-docs/covers/16-navigation-links.webp +0 -0
  105. data/app/assets/images/postnhost/sample-docs/covers/17-logo-and-default-og-image.webp +0 -0
  106. data/app/assets/images/postnhost/sample-docs/covers/19-public-text-for-each-language.webp +0 -0
  107. data/app/assets/images/postnhost/sample-docs/covers/20-structured-data-and-sitemap-seo.webp +0 -0
  108. data/app/assets/stylesheets/application.tailwind.css +347 -0
  109. data/app/assets/stylesheets/postnhost/application.css +15 -0
  110. data/app/assets/xsl/sitemap.xsl +64 -0
  111. data/app/controllers/concerns/postnhost/authentication.rb +59 -0
  112. data/app/controllers/concerns/postnhost/canonical_first_page_redirect.rb +14 -0
  113. data/app/controllers/concerns/postnhost/language_switcher.rb +42 -0
  114. data/app/controllers/concerns/postnhost/onboarding/access_control.rb +57 -0
  115. data/app/controllers/concerns/postnhost/onboarding/step_assignment.rb +55 -0
  116. data/app/controllers/concerns/postnhost/public_footer_data.rb +103 -0
  117. data/app/controllers/concerns/postnhost/public_http_caching.rb +35 -0
  118. data/app/controllers/concerns/postnhost/public_page_size.rb +17 -0
  119. data/app/controllers/concerns/postnhost/public_template_resolvable.rb +44 -0
  120. data/app/controllers/concerns/postnhost/settings/i18n_manageable.rb +61 -0
  121. data/app/controllers/concerns/postnhost/settings/navigation_manageable.rb +118 -0
  122. data/app/controllers/concerns/postnhost/settings/schema_manageable.rb +140 -0
  123. data/app/controllers/concerns/postnhost/users/schema_manageable.rb +119 -0
  124. data/app/controllers/postnhost/application_controller.rb +37 -0
  125. data/app/controllers/postnhost/article_variants_controller.rb +138 -0
  126. data/app/controllers/postnhost/articles/cover_images_controller.rb +35 -0
  127. data/app/controllers/postnhost/articles/images_controller.rb +28 -0
  128. data/app/controllers/postnhost/articles/translations_controller.rb +26 -0
  129. data/app/controllers/postnhost/articles_controller.rb +130 -0
  130. data/app/controllers/postnhost/categories/translations_controller.rb +24 -0
  131. data/app/controllers/postnhost/categories_controller.rb +59 -0
  132. data/app/controllers/postnhost/category_variants_controller.rb +69 -0
  133. data/app/controllers/postnhost/languages_controller.rb +66 -0
  134. data/app/controllers/postnhost/onboarding_controller.rb +70 -0
  135. data/app/controllers/postnhost/page_variants_controller.rb +136 -0
  136. data/app/controllers/postnhost/pages/images_controller.rb +28 -0
  137. data/app/controllers/postnhost/pages/translations_controller.rb +26 -0
  138. data/app/controllers/postnhost/pages_controller.rb +95 -0
  139. data/app/controllers/postnhost/public/articles_controller.rb +135 -0
  140. data/app/controllers/postnhost/public/authors_controller.rb +57 -0
  141. data/app/controllers/postnhost/public/categories_controller.rb +61 -0
  142. data/app/controllers/postnhost/public/static_pages_controller.rb +77 -0
  143. data/app/controllers/postnhost/public_controller.rb +32 -0
  144. data/app/controllers/postnhost/sessions_controller.rb +37 -0
  145. data/app/controllers/postnhost/settings/site_scripts_controller.rb +61 -0
  146. data/app/controllers/postnhost/settings_controller.rb +63 -0
  147. data/app/controllers/postnhost/sitemap_controller.rb +17 -0
  148. data/app/controllers/postnhost/templates_controller.rb +26 -0
  149. data/app/controllers/postnhost/users_controller.rb +112 -0
  150. data/app/helpers/postnhost/application_helper.rb +236 -0
  151. data/app/helpers/postnhost/article_helper.rb +41 -0
  152. data/app/helpers/postnhost/category_helper.rb +52 -0
  153. data/app/helpers/postnhost/common_css_helper.rb +97 -0
  154. data/app/helpers/postnhost/navigation_helper.rb +148 -0
  155. data/app/helpers/postnhost/pagy_helper.rb +103 -0
  156. data/app/helpers/postnhost/public_pages_helper.rb +287 -0
  157. data/app/helpers/postnhost/schema_helper.rb +102 -0
  158. data/app/helpers/postnhost/seo_helper.rb +428 -0
  159. data/app/helpers/postnhost/settings_helper.rb +79 -0
  160. data/app/javascript/application.js +3 -0
  161. data/app/javascript/controllers/ai_translation_controller.js +42 -0
  162. data/app/javascript/controllers/application.js +9 -0
  163. data/app/javascript/controllers/author_manager_controller.js +96 -0
  164. data/app/javascript/controllers/auto_save_controller.js +244 -0
  165. data/app/javascript/controllers/bulk_selection_controller.js +74 -0
  166. data/app/javascript/controllers/burger_controller.js +20 -0
  167. data/app/javascript/controllers/category_manager_controller.js +99 -0
  168. data/app/javascript/controllers/collapsible_sidebar_controller.js +87 -0
  169. data/app/javascript/controllers/cover_image_upload_controller.js +164 -0
  170. data/app/javascript/controllers/dropdown_controller.js +38 -0
  171. data/app/javascript/controllers/editor_mobile_sidebars_controller.js +36 -0
  172. data/app/javascript/controllers/file_auto_submit_controller.js +23 -0
  173. data/app/javascript/controllers/flash_message_controller.js +40 -0
  174. data/app/javascript/controllers/index.js +71 -0
  175. data/app/javascript/controllers/navigation_builder_controller.js +463 -0
  176. data/app/javascript/controllers/public_mobile_nav_controller.js +26 -0
  177. data/app/javascript/controllers/publish_guard_controller.js +47 -0
  178. data/app/javascript/controllers/reading_progress_controller.js +38 -0
  179. data/app/javascript/controllers/schedule_manager_controller.js +87 -0
  180. data/app/javascript/controllers/suggestion_manager_controller.js +99 -0
  181. data/app/javascript/controllers/template_preview_controller.js +34 -0
  182. data/app/javascript/controllers/tiptap_editor_controller.js +812 -0
  183. data/app/javascript/controllers/title_field_controller.js +17 -0
  184. data/app/javascript/helpers/auto_save_state.js +47 -0
  185. data/app/javascript/helpers/code_highlighting.js +48 -0
  186. data/app/javascript/helpers/dom_helpers.js +109 -0
  187. data/app/javascript/helpers/style_helpers.js +168 -0
  188. data/app/jobs/postnhost/application_job.rb +9 -0
  189. data/app/jobs/postnhost/scheduled_article_job.rb +13 -0
  190. data/app/jobs/postnhost/translation/article_variant_job.rb +17 -0
  191. data/app/jobs/postnhost/translation/category_variant_job.rb +17 -0
  192. data/app/jobs/postnhost/translation/page_variant_job.rb +17 -0
  193. data/app/models/concerns/postnhost/article/image_uploadable.rb +11 -0
  194. data/app/models/concerns/postnhost/excerpt_optimizable.rb +57 -0
  195. data/app/models/concerns/postnhost/inline_image_uploadable.rb +40 -0
  196. data/app/models/concerns/postnhost/page/image_uploadable.rb +11 -0
  197. data/app/models/concerns/postnhost/primary_language_guard.rb +18 -0
  198. data/app/models/concerns/postnhost/public_revision_touch.rb +15 -0
  199. data/app/models/concerns/postnhost/schema_localizable.rb +28 -0
  200. data/app/models/postnhost/application_record.rb +5 -0
  201. data/app/models/postnhost/article.rb +142 -0
  202. data/app/models/postnhost/article_author.rb +20 -0
  203. data/app/models/postnhost/article_category.rb +8 -0
  204. data/app/models/postnhost/article_suggestion.rb +19 -0
  205. data/app/models/postnhost/article_variant.rb +28 -0
  206. data/app/models/postnhost/category.rb +34 -0
  207. data/app/models/postnhost/category_variant.rb +24 -0
  208. data/app/models/postnhost/language.rb +38 -0
  209. data/app/models/postnhost/navigation.rb +76 -0
  210. data/app/models/postnhost/navigation_item.rb +100 -0
  211. data/app/models/postnhost/page.rb +63 -0
  212. data/app/models/postnhost/page_variant.rb +26 -0
  213. data/app/models/postnhost/public_site_revision.rb +24 -0
  214. data/app/models/postnhost/published_cover_image.rb +28 -0
  215. data/app/models/postnhost/setting.rb +116 -0
  216. data/app/models/postnhost/site_script.rb +11 -0
  217. data/app/models/postnhost/snapshot/article.rb +142 -0
  218. data/app/models/postnhost/snapshot/article_author.rb +11 -0
  219. data/app/models/postnhost/snapshot/article_category.rb +10 -0
  220. data/app/models/postnhost/snapshot/article_suggestion.rb +11 -0
  221. data/app/models/postnhost/snapshot/article_variant.rb +60 -0
  222. data/app/models/postnhost/snapshot/page.rb +33 -0
  223. data/app/models/postnhost/snapshot/page_variant.rb +41 -0
  224. data/app/models/postnhost/template.rb +20 -0
  225. data/app/models/postnhost/user.rb +63 -0
  226. data/app/models/postnhost/version.rb +7 -0
  227. data/app/services/postnhost/base_service.rb +17 -0
  228. data/app/services/postnhost/constraints/public_locale_constraint.rb +9 -0
  229. data/app/services/postnhost/constraints/public_route_constraint.rb +19 -0
  230. data/app/services/postnhost/onboarding/step_processor.rb +27 -0
  231. data/app/services/postnhost/onboarding/steps/base.rb +52 -0
  232. data/app/services/postnhost/onboarding/steps/choose_languages.rb +66 -0
  233. data/app/services/postnhost/onboarding/steps/complete_post_install_checklist.rb +12 -0
  234. data/app/services/postnhost/onboarding/steps/create_admin_account.rb +28 -0
  235. data/app/services/postnhost/onboarding/steps/finish_setup.rb +27 -0
  236. data/app/services/postnhost/onboarding/steps/set_site_metadata.rb +70 -0
  237. data/app/services/postnhost/public_navigation_targets.rb +67 -0
  238. data/app/services/postnhost/public_request_context.rb +101 -0
  239. data/app/services/postnhost/publishing/article_variants/publish.rb +26 -0
  240. data/app/services/postnhost/publishing/article_variants/publish_many.rb +23 -0
  241. data/app/services/postnhost/publishing/article_variants/snapshot_writer.rb +44 -0
  242. data/app/services/postnhost/publishing/article_variants/unpublish.rb +27 -0
  243. data/app/services/postnhost/publishing/article_variants/unpublish_many.rb +23 -0
  244. data/app/services/postnhost/publishing/articles/publish.rb +25 -0
  245. data/app/services/postnhost/publishing/articles/publish_scheduled.rb +42 -0
  246. data/app/services/postnhost/publishing/articles/snapshot_writer.rb +84 -0
  247. data/app/services/postnhost/publishing/articles/unpublish.rb +26 -0
  248. data/app/services/postnhost/publishing/bulk_transition.rb +63 -0
  249. data/app/services/postnhost/publishing/error.rb +12 -0
  250. data/app/services/postnhost/publishing/page_variants/publish.rb +26 -0
  251. data/app/services/postnhost/publishing/page_variants/publish_many.rb +23 -0
  252. data/app/services/postnhost/publishing/page_variants/snapshot_writer.rb +41 -0
  253. data/app/services/postnhost/publishing/page_variants/unpublish.rb +27 -0
  254. data/app/services/postnhost/publishing/page_variants/unpublish_many.rb +23 -0
  255. data/app/services/postnhost/publishing/pages/publish.rb +25 -0
  256. data/app/services/postnhost/publishing/pages/snapshot_writer.rb +38 -0
  257. data/app/services/postnhost/publishing/pages/unpublish.rb +26 -0
  258. data/app/services/postnhost/publishing/revision.rb +37 -0
  259. data/app/services/postnhost/publishing/route_validator.rb +41 -0
  260. data/app/services/postnhost/publishing/versions/restore_draft.rb +64 -0
  261. data/app/services/postnhost/service_result.rb +7 -0
  262. data/app/services/postnhost/sitemap_builder.rb +395 -0
  263. data/app/services/postnhost/translation/article_variant_translator.rb +102 -0
  264. data/app/services/postnhost/translation/category_variant_translator.rb +92 -0
  265. data/app/services/postnhost/translation/content_translator.rb +119 -0
  266. data/app/services/postnhost/translation/openai_llm_client.rb +30 -0
  267. data/app/services/postnhost/translation/page_variant_translator.rb +55 -0
  268. data/app/uploaders/base_uploader.rb +26 -0
  269. data/app/uploaders/cover_image_uploader.rb +31 -0
  270. data/app/uploaders/postnhost/avatar_uploader.rb +17 -0
  271. data/app/uploaders/postnhost/inline_article_image_uploader.rb +38 -0
  272. data/app/uploaders/postnhost/inline_page_image_uploader.rb +38 -0
  273. data/app/uploaders/postnhost/setting_asset_uploader.rb +18 -0
  274. data/app/views/layouts/postnhost/_favicon.html.erb +6 -0
  275. data/app/views/layouts/postnhost/_footer.html.erb +67 -0
  276. data/app/views/layouts/postnhost/_header.html.erb +89 -0
  277. data/app/views/layouts/postnhost/_sidebar.html.erb +72 -0
  278. data/app/views/layouts/postnhost/application.html.erb +23 -0
  279. data/app/views/layouts/postnhost/articles.html.erb +34 -0
  280. data/app/views/layouts/postnhost/product.html.erb +36 -0
  281. data/app/views/layouts/postnhost/public/templates/default.html.erb +110 -0
  282. data/app/views/layouts/postnhost/public/templates/swiss-editorial.html.erb +213 -0
  283. data/app/views/layouts/postnhost/public/templates/workspace-journal.html.erb +231 -0
  284. data/app/views/layouts/postnhost/public_header/_dashboard_sign_in.html.erb +14 -0
  285. data/app/views/layouts/postnhost/public_header/_language_switcher.html.erb +43 -0
  286. data/app/views/layouts/postnhost/public_header/_logo.html.erb +9 -0
  287. data/app/views/postnhost/article_variants/_variants_list.html.erb +82 -0
  288. data/app/views/postnhost/article_variants/edit.html.erb +48 -0
  289. data/app/views/postnhost/article_variants/index.html.erb +128 -0
  290. data/app/views/postnhost/article_variants/publish.turbo_stream.erb +3 -0
  291. data/app/views/postnhost/article_variants/unpublish.turbo_stream.erb +3 -0
  292. data/app/views/postnhost/article_variants/update.turbo_stream.erb +3 -0
  293. data/app/views/postnhost/articles/_author_manager.html.erb +38 -0
  294. data/app/views/postnhost/articles/_category_manager.html.erb +42 -0
  295. data/app/views/postnhost/articles/_cover_image_upload.html.erb +82 -0
  296. data/app/views/postnhost/articles/_suggestion_manager.html.erb +43 -0
  297. data/app/views/postnhost/articles/_version_snapshot.html.erb +10 -0
  298. data/app/views/postnhost/articles/edit.html.erb +51 -0
  299. data/app/views/postnhost/articles/index.html.erb +132 -0
  300. data/app/views/postnhost/articles/publish.turbo_stream.erb +3 -0
  301. data/app/views/postnhost/articles/unpublish.turbo_stream.erb +3 -0
  302. data/app/views/postnhost/articles/update.turbo_stream.erb +3 -0
  303. data/app/views/postnhost/articles/version_preview.html.erb +17 -0
  304. data/app/views/postnhost/articles/versions.html.erb +68 -0
  305. data/app/views/postnhost/categories/edit.html.erb +77 -0
  306. data/app/views/postnhost/categories/index.html.erb +80 -0
  307. data/app/views/postnhost/categories/new.html.erb +50 -0
  308. data/app/views/postnhost/categories/show.html.erb +99 -0
  309. data/app/views/postnhost/category_variants/_category_variants_list.html.erb +67 -0
  310. data/app/views/postnhost/category_variants/_form.html.erb +29 -0
  311. data/app/views/postnhost/category_variants/edit.html.erb +21 -0
  312. data/app/views/postnhost/category_variants/index.html.erb +82 -0
  313. data/app/views/postnhost/category_variants/new.html.erb +21 -0
  314. data/app/views/postnhost/languages/edit.html.erb +45 -0
  315. data/app/views/postnhost/languages/index.html.erb +86 -0
  316. data/app/views/postnhost/languages/new.html.erb +45 -0
  317. data/app/views/postnhost/languages/show.html.erb +156 -0
  318. data/app/views/postnhost/onboarding/_post_install_checklist.html.erb +40 -0
  319. data/app/views/postnhost/onboarding/_step_1.html.erb +42 -0
  320. data/app/views/postnhost/onboarding/_step_2.html.erb +38 -0
  321. data/app/views/postnhost/onboarding/_step_3.html.erb +62 -0
  322. data/app/views/postnhost/onboarding/_step_4.html.erb +26 -0
  323. data/app/views/postnhost/onboarding/show.html.erb +51 -0
  324. data/app/views/postnhost/page_variants/_variants_list.html.erb +82 -0
  325. data/app/views/postnhost/page_variants/edit.html.erb +50 -0
  326. data/app/views/postnhost/page_variants/index.html.erb +128 -0
  327. data/app/views/postnhost/page_variants/publish.turbo_stream.erb +3 -0
  328. data/app/views/postnhost/page_variants/unpublish.turbo_stream.erb +3 -0
  329. data/app/views/postnhost/page_variants/update.turbo_stream.erb +3 -0
  330. data/app/views/postnhost/pages/edit.html.erb +50 -0
  331. data/app/views/postnhost/pages/index.html.erb +110 -0
  332. data/app/views/postnhost/pages/publish.turbo_stream.erb +3 -0
  333. data/app/views/postnhost/pages/unpublish.turbo_stream.erb +3 -0
  334. data/app/views/postnhost/public/articles/content_for/_index.html.erb +30 -0
  335. data/app/views/postnhost/public/articles/content_for/_preview.html.erb +9 -0
  336. data/app/views/postnhost/public/articles/content_for/_show.html.erb +24 -0
  337. data/app/views/postnhost/public/authors/content_for/_show.html.erb +24 -0
  338. data/app/views/postnhost/public/categories/content_for/_index.html.erb +29 -0
  339. data/app/views/postnhost/public/static_pages/content_for/_show.html.erb +19 -0
  340. data/app/views/postnhost/public/templates/default/articles/_article_card.html.erb +37 -0
  341. data/app/views/postnhost/public/templates/default/articles/_search_form.html.erb +12 -0
  342. data/app/views/postnhost/public/templates/default/articles/_suggestions.html.erb +44 -0
  343. data/app/views/postnhost/public/templates/default/articles/_top_picks.html.erb +42 -0
  344. data/app/views/postnhost/public/templates/default/articles/index.html.erb +53 -0
  345. data/app/views/postnhost/public/templates/default/articles/preview.html.erb +102 -0
  346. data/app/views/postnhost/public/templates/default/articles/show.html.erb +111 -0
  347. data/app/views/postnhost/public/templates/default/authors/_article_card.html.erb +28 -0
  348. data/app/views/postnhost/public/templates/default/authors/_profile_block.html.erb +29 -0
  349. data/app/views/postnhost/public/templates/default/authors/show.html.erb +36 -0
  350. data/app/views/postnhost/public/templates/default/categories/_article_card.html.erb +34 -0
  351. data/app/views/postnhost/public/templates/default/categories/index.html.erb +48 -0
  352. data/app/views/postnhost/public/templates/default/shared/_article_authors.html.erb +24 -0
  353. data/app/views/postnhost/public/templates/default/shared/_author_avatar.html.erb +9 -0
  354. data/app/views/postnhost/public/templates/default/shared/_hero_cover_image.html.erb +11 -0
  355. data/app/views/postnhost/public/templates/default/shared/_pagination.html.erb +35 -0
  356. data/app/views/postnhost/public/templates/default/shared/_thumbnail_cover_image.html.erb +9 -0
  357. data/app/views/postnhost/public/templates/default/static_pages/show.html.erb +22 -0
  358. data/app/views/postnhost/public/templates/swiss-editorial/articles/_article_card.html.erb +28 -0
  359. data/app/views/postnhost/public/templates/swiss-editorial/articles/_search_form.html.erb +19 -0
  360. data/app/views/postnhost/public/templates/swiss-editorial/articles/_suggestions.html.erb +42 -0
  361. data/app/views/postnhost/public/templates/swiss-editorial/articles/_top_picks.html.erb +38 -0
  362. data/app/views/postnhost/public/templates/swiss-editorial/articles/index.html.erb +133 -0
  363. data/app/views/postnhost/public/templates/swiss-editorial/articles/preview.html.erb +42 -0
  364. data/app/views/postnhost/public/templates/swiss-editorial/articles/show.html.erb +100 -0
  365. data/app/views/postnhost/public/templates/swiss-editorial/authors/_article_card.html.erb +27 -0
  366. data/app/views/postnhost/public/templates/swiss-editorial/authors/_profile_block.html.erb +32 -0
  367. data/app/views/postnhost/public/templates/swiss-editorial/authors/show.html.erb +31 -0
  368. data/app/views/postnhost/public/templates/swiss-editorial/categories/_article_card.html.erb +28 -0
  369. data/app/views/postnhost/public/templates/swiss-editorial/categories/index.html.erb +88 -0
  370. data/app/views/postnhost/public/templates/swiss-editorial/shared/_article_authors.html.erb +26 -0
  371. data/app/views/postnhost/public/templates/swiss-editorial/shared/_author_avatar.html.erb +9 -0
  372. data/app/views/postnhost/public/templates/swiss-editorial/shared/_hero_cover_image.html.erb +11 -0
  373. data/app/views/postnhost/public/templates/swiss-editorial/shared/_pagination.html.erb +35 -0
  374. data/app/views/postnhost/public/templates/swiss-editorial/shared/_thumbnail_cover_image.html.erb +9 -0
  375. data/app/views/postnhost/public/templates/swiss-editorial/static_pages/show.html.erb +17 -0
  376. data/app/views/postnhost/public/templates/workspace-journal/articles/_article_card.html.erb +44 -0
  377. data/app/views/postnhost/public/templates/workspace-journal/articles/_search_form.html.erb +19 -0
  378. data/app/views/postnhost/public/templates/workspace-journal/articles/_suggestions.html.erb +49 -0
  379. data/app/views/postnhost/public/templates/workspace-journal/articles/_top_picks.html.erb +34 -0
  380. data/app/views/postnhost/public/templates/workspace-journal/articles/index.html.erb +69 -0
  381. data/app/views/postnhost/public/templates/workspace-journal/articles/preview.html.erb +113 -0
  382. data/app/views/postnhost/public/templates/workspace-journal/articles/show.html.erb +120 -0
  383. data/app/views/postnhost/public/templates/workspace-journal/authors/_article_card.html.erb +1 -0
  384. data/app/views/postnhost/public/templates/workspace-journal/authors/_profile_block.html.erb +32 -0
  385. data/app/views/postnhost/public/templates/workspace-journal/authors/show.html.erb +33 -0
  386. data/app/views/postnhost/public/templates/workspace-journal/categories/_article_card.html.erb +1 -0
  387. data/app/views/postnhost/public/templates/workspace-journal/categories/index.html.erb +58 -0
  388. data/app/views/postnhost/public/templates/workspace-journal/shared/_article_authors.html.erb +27 -0
  389. data/app/views/postnhost/public/templates/workspace-journal/shared/_article_card.html.erb +44 -0
  390. data/app/views/postnhost/public/templates/workspace-journal/shared/_author_avatar.html.erb +9 -0
  391. data/app/views/postnhost/public/templates/workspace-journal/shared/_category_navigation.html.erb +10 -0
  392. data/app/views/postnhost/public/templates/workspace-journal/shared/_hero_cover_image.html.erb +11 -0
  393. data/app/views/postnhost/public/templates/workspace-journal/shared/_pagination.html.erb +35 -0
  394. data/app/views/postnhost/public/templates/workspace-journal/shared/_thumbnail_cover_image.html.erb +9 -0
  395. data/app/views/postnhost/public/templates/workspace-journal/static_pages/show.html.erb +17 -0
  396. data/app/views/postnhost/sessions/new.html.erb +59 -0
  397. data/app/views/postnhost/settings/edit.html.erb +68 -0
  398. data/app/views/postnhost/settings/sections/_assets.html.erb +40 -0
  399. data/app/views/postnhost/settings/sections/_feature_flags.html.erb +43 -0
  400. data/app/views/postnhost/settings/sections/_i18n.html.erb +57 -0
  401. data/app/views/postnhost/settings/sections/_navigation.html.erb +98 -0
  402. data/app/views/postnhost/settings/sections/_schema.html.erb +253 -0
  403. data/app/views/postnhost/settings/sections/_scripts.html.erb +79 -0
  404. data/app/views/postnhost/settings/sections/_site.html.erb +41 -0
  405. data/app/views/postnhost/settings/sections/_timezone.html.erb +19 -0
  406. data/app/views/postnhost/shared/_ai_translation_modal.html.erb +85 -0
  407. data/app/views/postnhost/shared/_flash_messages.html.erb +27 -0
  408. data/app/views/postnhost/shared/_form_errors.html.erb +22 -0
  409. data/app/views/postnhost/shared/_seo_meta_tags.html.erb +70 -0
  410. data/app/views/postnhost/shared/_structured_data.html.erb +5 -0
  411. data/app/views/postnhost/shared/articles/_action_buttons.html.erb +87 -0
  412. data/app/views/postnhost/shared/articles/_cover_image_preview.html.erb +30 -0
  413. data/app/views/postnhost/shared/articles/_editor_column.html.erb +15 -0
  414. data/app/views/postnhost/shared/articles/_editor_column_preview.html.erb +33 -0
  415. data/app/views/postnhost/shared/articles/_error_messages.html.erb +23 -0
  416. data/app/views/postnhost/shared/articles/_meta_sidebar.html.erb +322 -0
  417. data/app/views/postnhost/shared/articles/_meta_sidebar_preview.html.erb +29 -0
  418. data/app/views/postnhost/shared/articles/_post_actions.html.erb +105 -0
  419. data/app/views/postnhost/shared/articles/_schedule_actions.html.erb +51 -0
  420. data/app/views/postnhost/shared/articles/_tiptap_editor.html.erb +225 -0
  421. data/app/views/postnhost/shared/articles/_title_field.html.erb +9 -0
  422. data/app/views/postnhost/shared/articles/_version_action_buttons.html.erb +35 -0
  423. data/app/views/postnhost/shared/elements/_button.html.erb +20 -0
  424. data/app/views/postnhost/shared/elements/_button_link.html.erb +24 -0
  425. data/app/views/postnhost/shared/elements/_empty_state.html.erb +22 -0
  426. data/app/views/postnhost/shared/elements/_error_messages.html.erb +28 -0
  427. data/app/views/postnhost/shared/elements/_form_card.html.erb +10 -0
  428. data/app/views/postnhost/shared/elements/_form_page_header.html.erb +21 -0
  429. data/app/views/postnhost/shared/elements/_icon_button.html.erb +17 -0
  430. data/app/views/postnhost/shared/elements/_page_header.html.erb +40 -0
  431. data/app/views/postnhost/shared/elements/_table_container.html.erb +23 -0
  432. data/app/views/postnhost/shared/pages/_action_buttons.html.erb +84 -0
  433. data/app/views/postnhost/shared/pages/_meta_sidebar.html.erb +132 -0
  434. data/app/views/postnhost/shared/pages/_post_actions.html.erb +69 -0
  435. data/app/views/postnhost/templates/edit.html.erb +83 -0
  436. data/app/views/postnhost/users/_avatar.html.erb +9 -0
  437. data/app/views/postnhost/users/_form.html.erb +160 -0
  438. data/app/views/postnhost/users/edit.html.erb +26 -0
  439. data/app/views/postnhost/users/index.html.erb +91 -0
  440. data/app/views/postnhost/users/new.html.erb +9 -0
  441. data/app/views/postnhost/users/schema_edit.html.erb +175 -0
  442. data/config/locales/de.yml +55 -0
  443. data/config/locales/en.yml +88 -0
  444. data/config/locales/es.yml +58 -0
  445. data/config/locales/fr.yml +55 -0
  446. data/config/locales/ja.yml +55 -0
  447. data/config/locales/ko.yml +55 -0
  448. data/config/locales/pl.yml +55 -0
  449. data/config/locales/pt.yml +55 -0
  450. data/config/locales/ru.yml +55 -0
  451. data/config/routes.rb +112 -0
  452. data/db/migrate/20250822213820_create_users.rb +29 -0
  453. data/db/migrate/20250822214046_create_categories.rb +15 -0
  454. data/db/migrate/20250822214106_create_languages.rb +16 -0
  455. data/db/migrate/20250822214148_create_articles.rb +34 -0
  456. data/db/migrate/20250822214217_create_article_variants.rb +24 -0
  457. data/db/migrate/20250929091137_create_article_categories.rb +12 -0
  458. data/db/migrate/20251013204200_create_versions.rb +40 -0
  459. data/db/migrate/20260106074532_create_article_suggestions.rb +13 -0
  460. data/db/migrate/20260108110506_create_category_variants.rb +15 -0
  461. data/db/migrate/20260308130000_create_settings.rb +23 -0
  462. data/db/migrate/20260323113000_create_pages.rb +19 -0
  463. data/db/migrate/20260414100000_create_article_authors.rb +14 -0
  464. data/db/migrate/20260512100000_create_templates.rb +9 -0
  465. data/db/migrate/20260520110001_create_navigations.rb +9 -0
  466. data/db/migrate/20260520110002_create_navigation_items.rb +22 -0
  467. data/db/migrate/20260528000002_create_page_variants.rb +20 -0
  468. data/db/migrate/20260709090000_create_snapshots.rb +154 -0
  469. data/db/migrate/20260726130000_create_site_scripts.rb +11 -0
  470. data/lib/generators/postnhost/install/install_generator.rb +55 -0
  471. data/lib/generators/postnhost/install/templates/carrierwave.rb +17 -0
  472. data/lib/generators/postnhost/install/templates/postnhost.rb +36 -0
  473. data/lib/generators/postnhost/locale/locale_generator.rb +36 -0
  474. data/lib/generators/postnhost/static_pages/static_pages_generator.rb +47 -0
  475. data/lib/generators/postnhost/tailwindcss/install_generator.rb +100 -0
  476. data/lib/generators/postnhost/tailwindcss/templates/host.tailwind.css +4 -0
  477. data/lib/generators/postnhost/user/user_generator.rb +36 -0
  478. data/lib/generators/postnhost/views/views_generator.rb +140 -0
  479. data/lib/postnhost/configuration.rb +64 -0
  480. data/lib/postnhost/css_build.rb +68 -0
  481. data/lib/postnhost/css_scope.rb +77 -0
  482. data/lib/postnhost/engine.rb +57 -0
  483. data/lib/postnhost/sample_data.rb +865 -0
  484. data/lib/postnhost/settings/i18n_overrides.rb +137 -0
  485. data/lib/postnhost/settings/i18n_patch.rb +18 -0
  486. data/lib/postnhost/tailwind_compiler.rb +75 -0
  487. data/lib/postnhost/tailwind_input.rb +32 -0
  488. data/lib/postnhost/version.rb +1 -3
  489. data/lib/postnhost.rb +26 -3
  490. data/lib/tasks/postnhost_snapshots.rake +77 -0
  491. data/lib/tasks/postnhost_tasks.rake +71 -0
  492. metadata +679 -21
  493. data/.github/workflows/main.yml +0 -27
  494. data/.gitignore +0 -11
  495. data/.rspec +0 -3
  496. data/.rubocop.yml +0 -8
  497. data/Gemfile +0 -13
  498. data/bin/console +0 -11
  499. data/bin/setup +0 -8
  500. data/postnhost.gemspec +0 -31
@@ -0,0 +1,175 @@
1
+ <% content_for :title, "Author Schema" %>
2
+
3
+ <div class="space-y-8">
4
+ <%= render "postnhost/shared/elements/page_header",
5
+ title: "Author Schema",
6
+ description: "Advanced Person schema settings for this author profile",
7
+ stats: [
8
+ { text: "Author: #{@user.name}" },
9
+ { text: author_pages_enabled? ? "Slug: /authors/#{@user.slug}" : "Slug: #{@user.slug}" },
10
+ *(@user.slug.present? && author_pages_enabled? ? [{ text: "Open", url: public_author_path(@user.slug), icon: "external-link", target: "_blank" }] : [])
11
+ ] do %>
12
+ <%= render "postnhost/shared/elements/button_link",
13
+ text: "Back to Author",
14
+ url: edit_user_path(@user),
15
+ variant: :secondary,
16
+ icon: "chevron-left",
17
+ extra_class: "w-full md:w-auto" %>
18
+ <% end %>
19
+
20
+ <section class="bg-white rounded-2xl border border-gray-200 p-6 space-y-6">
21
+ <div>
22
+ <h2 class="text-lg font-medium text-gray-900">Derived Defaults</h2>
23
+ <p class="mt-1 text-sm text-gray-500">These values are used automatically when no schema override exists.</p>
24
+ </div>
25
+
26
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm text-gray-700">
27
+ <div class="rounded-xl border border-gray-200 p-4">
28
+ <p><span class="font-medium">name:</span> <%= @user.name.presence || "Not set" %></p>
29
+ <p class="mt-2"><span class="font-medium">jobTitle:</span> <%= @user.position.presence || "Author" %></p>
30
+ <p class="mt-2"><span class="font-medium">description:</span> <%= @user.bio.presence || "Not set" %></p>
31
+ </div>
32
+ <div class="rounded-xl border border-gray-200 p-4">
33
+ <p><span class="font-medium">url:</span> <%= author_pages_enabled? ? public_author_url(@user.slug) : "Author pages disabled" %></p>
34
+ <p class="mt-2"><span class="font-medium">@id:</span> <%= author_pages_enabled? ? "#{public_author_url(@user.slug)}#person" : "Author pages disabled" %></p>
35
+ <p class="mt-2"><span class="font-medium">Default language:</span> <%= @schema_default_locale_key %></p>
36
+ </div>
37
+ </div>
38
+
39
+ <div class="rounded-xl border border-gray-200 p-4 space-y-4">
40
+ <h3 class="text-base font-medium text-gray-900">Schema Fields</h3>
41
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
42
+ <div class="space-y-2">
43
+ <label for="schema_derived_author_slug" class="<%= form_label_classes %>">slug</label>
44
+ <%= text_field_tag "schema_derived_author_slug",
45
+ @user.slug,
46
+ id: "schema_derived_author_slug",
47
+ class: "w-full px-3 py-2 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-gray-900 focus:border-transparent text-sm disabled:bg-gray-100",
48
+ readonly: true,
49
+ disabled: true %>
50
+ </div>
51
+
52
+ <div class="space-y-2">
53
+ <label for="schema_derived_author_url" class="<%= form_label_classes %>">url</label>
54
+ <%= text_field_tag "schema_derived_author_url",
55
+ author_pages_enabled? ? public_author_url(@user.slug) : "Author pages disabled",
56
+ id: "schema_derived_author_url",
57
+ class: "w-full px-3 py-2 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-gray-900 focus:border-transparent text-sm disabled:bg-gray-100",
58
+ readonly: true,
59
+ disabled: true %>
60
+ </div>
61
+ </div>
62
+
63
+ <div class="space-y-2">
64
+ <label for="schema_derived_author_id" class="<%= form_label_classes %>">@id</label>
65
+ <%= text_field_tag "schema_derived_author_id",
66
+ author_pages_enabled? ? "#{public_author_url(@user.slug)}#person" : "Author pages disabled",
67
+ id: "schema_derived_author_id",
68
+ class: "w-full px-3 py-2 border border-gray-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-gray-900 focus:border-transparent text-sm disabled:bg-gray-100",
69
+ readonly: true,
70
+ disabled: true %>
71
+ </div>
72
+ </div>
73
+ </section>
74
+
75
+ <section class="bg-white rounded-2xl border border-gray-200 p-6 space-y-6">
76
+ <div>
77
+ <h2 class="text-lg font-medium text-gray-900">Schema Overrides</h2>
78
+ <p class="mt-1 text-sm text-gray-500">Leave language-specific fields blank to inherit default language values.</p>
79
+ </div>
80
+
81
+ <%= form_with url: schema_edit_user_path(@user), method: :get, class: "space-y-2" do %>
82
+ <label for="schema-locale-selector" class="<%= form_label_classes %>">Language</label>
83
+ <%= select_tag :locale,
84
+ options_for_select(@schema_locale_keys, @schema_selected_locale_key),
85
+ id: "schema-locale-selector",
86
+ class: form_input_classes,
87
+ onchange: "this.form.requestSubmit()" %>
88
+ <% end %>
89
+
90
+ <%= form_with url: schema_update_user_path(@user), method: :patch, class: "space-y-6" do %>
91
+ <%= render "postnhost/shared/elements/error_messages", resource: @user %>
92
+ <%= hidden_field_tag :locale_key, @schema_selected_locale_key %>
93
+
94
+ <div class="rounded-xl border border-gray-200 p-4 space-y-4">
95
+ <h3 class="text-base font-medium text-gray-900">Localized Text</h3>
96
+
97
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
98
+ <div class="space-y-2">
99
+ <label for="schema_translation_name" class="<%= form_label_classes %>">name</label>
100
+ <%= text_field_tag "schema_translations[name]", @schema_translation_entries["name"], id: "schema_translation_name", class: form_input_classes %>
101
+ </div>
102
+
103
+ <div class="space-y-2">
104
+ <label for="schema_translation_job_title" class="<%= form_label_classes %>">jobTitle</label>
105
+ <%= text_field_tag "schema_translations[job_title]", @schema_translation_entries["job_title"], id: "schema_translation_job_title", class: form_input_classes %>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="space-y-2">
110
+ <label for="schema_translation_bio" class="<%= form_label_classes %>">description</label>
111
+ <%= text_area_tag "schema_translations[bio]", @schema_translation_entries["bio"], id: "schema_translation_bio", rows: 3, class: form_textarea_classes %>
112
+ </div>
113
+
114
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
115
+ <div class="space-y-2">
116
+ <label for="schema_translation_knows_about" class="<%= form_label_classes %>">knowsAbout (Optional, one per line)</label>
117
+ <%= text_area_tag "schema_translations[knows_about]", @schema_translation_entries["knows_about"], id: "schema_translation_knows_about", rows: 3, class: form_textarea_classes %>
118
+ </div>
119
+
120
+ <div class="space-y-2">
121
+ <label for="schema_translation_awards" class="<%= form_label_classes %>">awards (Optional, one per line)</label>
122
+ <%= text_area_tag "schema_translations[awards]", @schema_translation_entries["awards"], id: "schema_translation_awards", rows: 3, class: form_textarea_classes %>
123
+ </div>
124
+ </div>
125
+
126
+ <div class="space-y-2">
127
+ <label for="schema_translation_alumni_of" class="<%= form_label_classes %>">alumniOf.name (Optional)</label>
128
+ <%= text_field_tag "schema_translations[alumni_of]", @schema_translation_entries["alumni_of"], id: "schema_translation_alumni_of", class: form_input_classes %>
129
+ </div>
130
+ </div>
131
+
132
+ <div class="rounded-xl border border-gray-200 p-4 space-y-4">
133
+ <h3 class="text-base font-medium text-gray-900">Global Advanced Fields</h3>
134
+
135
+ <div class="space-y-2">
136
+ <label for="schema_profile_same_as" class="<%= form_label_classes %>">sameAs (Optional, one URL per line)</label>
137
+ <%= text_area_tag "schema_profile[same_as]",
138
+ schema_array_to_multiline(@schema_profile_values["same_as"]),
139
+ id: "schema_profile_same_as",
140
+ rows: 3,
141
+ class: form_textarea_classes,
142
+ placeholder: "Auto-included from Social Links profile fields. Add only extra URLs here.\nhttps://wikipedia.org/wiki/Author_Name\nhttps://www.imdb.com/name/nm0000000/" %>
143
+ </div>
144
+
145
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
146
+ <div class="space-y-2">
147
+ <label for="schema_profile_image_url" class="<%= form_label_classes %>">image.url (Optional)</label>
148
+ <%= url_field_tag "schema_profile[image_url]", @schema_profile_values["image_url"], id: "schema_profile_image_url", class: form_input_classes, placeholder: "Leave blank to use Author Image." %>
149
+ </div>
150
+
151
+ <div class="space-y-2">
152
+ <label for="schema_profile_alumni_type" class="<%= form_label_classes %>">alumniOf.@type (Optional)</label>
153
+ <%= select_tag "schema_profile[alumni_type]",
154
+ options_for_select(schema_author_alumni_type_options, @schema_profile_values["alumni_type"]),
155
+ include_blank: "Not set",
156
+ id: "schema_profile_alumni_type",
157
+ class: form_input_classes %>
158
+ </div>
159
+ </div>
160
+
161
+ <div class="space-y-2">
162
+ <label for="schema_profile_knows_language" class="<%= form_label_classes %>">knowsLanguage (Optional, one code per line)</label>
163
+ <%= text_area_tag "schema_profile[knows_language]",
164
+ schema_array_to_multiline(@schema_profile_values["knows_language"]),
165
+ id: "schema_profile_knows_language",
166
+ rows: 3,
167
+ class: form_textarea_classes,
168
+ placeholder: "en\nfr\nde" %>
169
+ </div>
170
+ </div>
171
+
172
+ <%= submit_tag "Save Author Schema", class: button_classes %>
173
+ <% end %>
174
+ </section>
175
+ </div>
@@ -0,0 +1,55 @@
1
+ de:
2
+ postnhost:
3
+ public:
4
+ site:
5
+ schema_site_name: "PostnHost"
6
+ blog_tagline: "Blog"
7
+ blog_subtitle: "Entdecken Sie die neuesten Einblicke, Tutorials und Geschichten"
8
+ blog_meta_title: "Blog – PostnHost"
9
+ blog_meta_description: "Entdecken Sie die neuesten Einblicke, Tutorials und Geschichten von PostnHost."
10
+ blog_meta_title_paginated: "Seite %{page} – %{blog_meta_title}"
11
+ name_footer_copyright: "postnhost.com"
12
+
13
+ blog:
14
+ page_title: "Seite %{page} – Blog"
15
+ author_label: "Autor"
16
+ no_articles: "Noch keine Artikel"
17
+ no_articles_description: "Schauen Sie bald wieder vorbei. Neue Inhalte folgen in Kürze."
18
+ back_to_articles: "Zurück zu allen Artikeln"
19
+ more_in_category: "Mehr in %{category}"
20
+ available_in_languages: "In weiteren Sprachen verfügbar:"
21
+ browse_all_articles: "Alle Artikel ansehen"
22
+ read_more: "Ähnliche Artikel"
23
+ read_article_aria_label: "Artikel „%{title}“ lesen"
24
+ top_picks: "Empfehlungen"
25
+
26
+ search:
27
+ title: "Suchergebnisse für „%{query}“"
28
+ heading: "Suchergebnisse für „%{query}“"
29
+ input_placeholder: "Nach Titel oder Inhalt suchen"
30
+ submit: "Suchen"
31
+
32
+ category:
33
+ title: "%{category} – PostnHost"
34
+ page_title: "Seite %{page} – %{category} – PostnHost"
35
+ page_heading: "Seite %{page} – %{category}"
36
+ no_articles: "Keine Artikel gefunden"
37
+ no_articles_description: "Es gibt noch keine veröffentlichten Artikel in dieser Kategorie."
38
+
39
+ authors:
40
+ latest_from_author: "Neueste Beiträge dieses Autors"
41
+ no_articles: "Noch keine Artikel"
42
+ no_articles_description: "Dieser Autor hat noch keine Artikel veröffentlicht."
43
+
44
+ footer:
45
+ heading: "Fußzeile"
46
+ explore_categories: "Beiträge nach Kategorien"
47
+ pages: "Seiten"
48
+
49
+ breadcrumbs:
50
+ home: "Startseite"
51
+
52
+ pagination:
53
+ navigation: "Seitennavigation"
54
+ previous: "Zurück"
55
+ next: "Weiter"
@@ -0,0 +1,88 @@
1
+ # Files in the config/locales directory are used for internationalization and
2
+ # are automatically loaded by Rails. If you want to use locales other than
3
+ # English, add the necessary files in this directory.
4
+ #
5
+ # To use the locales, use `I18n.t`:
6
+ #
7
+ # I18n.t "hello"
8
+ #
9
+ # In views, this is aliased to just `t`:
10
+ #
11
+ # <%= t("hello") %>
12
+ #
13
+ # To use a different locale, set it with `I18n.locale`:
14
+ #
15
+ # I18n.locale = :es
16
+ #
17
+ # This would use the information in config/locales/es.yml.
18
+ #
19
+ # To learn more about the API, please read the Rails Internationalization guide
20
+ # at https://guides.rubyonrails.org/i18n.html.
21
+ #
22
+ # Be aware that YAML interprets the following case-insensitive strings as
23
+ # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings
24
+ # must be quoted to be interpreted as strings. For example:
25
+ #
26
+ # en:
27
+ # "yes": yup
28
+ # enabled: "ON"
29
+
30
+ en:
31
+ postnhost:
32
+ onboarding:
33
+ title: "Welcome to PostnHost"
34
+ step_indicator: "Step %{step} of %{total}"
35
+
36
+ public:
37
+ site:
38
+ schema_site_name: "PostnHost"
39
+ blog_tagline: "Blog"
40
+ blog_subtitle: "Discover the latest insights, tutorials, and stories"
41
+ blog_meta_title: "Blog — PostnHost"
42
+ blog_meta_description: "Discover the latest insights, tutorials, and stories from PostnHost."
43
+ blog_meta_title_paginated: "Page %{page} — %{blog_meta_title}"
44
+ name_footer_copyright: "postnhost.com"
45
+
46
+ blog:
47
+ page_title: "Page %{page} — Blog"
48
+ author_label: "Author"
49
+ no_articles: "No articles yet"
50
+ no_articles_description: "Check back soon for new content."
51
+ back_to_articles: "Back to articles"
52
+ more_in_category: "More in %{category}"
53
+ available_in_languages: "Available in other languages:"
54
+ browse_all_articles: "Browse all articles"
55
+ read_more: "Related articles"
56
+ read_article_aria_label: "Read “%{title}”"
57
+ top_picks: "Top picks"
58
+
59
+ search:
60
+ title: "Search results for “%{query}”"
61
+ heading: "Search results for “%{query}”"
62
+ input_placeholder: "Search by title or content"
63
+ submit: "Search"
64
+
65
+ category:
66
+ title: "%{category} — PostnHost"
67
+ page_title: "Page %{page} — %{category} — PostnHost"
68
+ page_heading: "Page %{page} — %{category}"
69
+ no_articles: "No articles found"
70
+ no_articles_description: "There are no published articles in this category yet."
71
+
72
+ authors:
73
+ latest_from_author: "Latest from this author"
74
+ no_articles: "No articles yet"
75
+ no_articles_description: "This author has not published any articles yet."
76
+
77
+ footer:
78
+ heading: "Footer"
79
+ explore_categories: "Browse posts by category"
80
+ pages: "Pages"
81
+
82
+ breadcrumbs:
83
+ home: "Home"
84
+
85
+ pagination:
86
+ navigation: "Pagination"
87
+ previous: "Previous"
88
+ next: "Next"
@@ -0,0 +1,58 @@
1
+ es:
2
+ date:
3
+ formats:
4
+ long: "%d de %B de %Y"
5
+ postnhost:
6
+ public:
7
+ site:
8
+ schema_site_name: "PostnHost"
9
+ blog_tagline: "Blog"
10
+ blog_subtitle: "Descubre las últimas perspectivas, tutoriales e historias"
11
+ blog_meta_title: "Blog — PostnHost"
12
+ blog_meta_description: "Descubre las últimas perspectivas, tutoriales e historias de PostnHost."
13
+ blog_meta_title_paginated: "Página %{page} — %{blog_meta_title}"
14
+ name_footer_copyright: "postnhost.com"
15
+
16
+ blog:
17
+ page_title: "Página %{page} — Blog"
18
+ author_label: "Autor"
19
+ no_articles: "Aún no hay artículos"
20
+ no_articles_description: "Vuelve pronto para descubrir nuevo contenido."
21
+ back_to_articles: "Volver a los artículos"
22
+ more_in_category: "Más en %{category}"
23
+ available_in_languages: "Disponible en otros idiomas:"
24
+ browse_all_articles: "Ver todos los artículos"
25
+ read_more: "Artículos relacionados"
26
+ read_article_aria_label: "Leer «%{title}»"
27
+ top_picks: "Destacados"
28
+
29
+ search:
30
+ title: "Resultados de búsqueda para «%{query}»"
31
+ heading: "Resultados de búsqueda para «%{query}»"
32
+ input_placeholder: "Buscar por título o contenido"
33
+ submit: "Buscar"
34
+
35
+ category:
36
+ title: "%{category} — PostnHost"
37
+ page_title: "Página %{page} — %{category} — PostnHost"
38
+ page_heading: "Página %{page} — %{category}"
39
+ no_articles: "No se encontraron artículos"
40
+ no_articles_description: "Todavía no hay artículos publicados en esta categoría."
41
+
42
+ authors:
43
+ latest_from_author: "Últimos artículos de este autor"
44
+ no_articles: "Aún no hay artículos"
45
+ no_articles_description: "Este autor aún no ha publicado ningún artículo."
46
+
47
+ footer:
48
+ heading: "Pie de página"
49
+ explore_categories: "Artículos por categoría"
50
+ pages: "Páginas"
51
+
52
+ breadcrumbs:
53
+ home: "Inicio"
54
+
55
+ pagination:
56
+ navigation: "Paginación"
57
+ previous: "Anterior"
58
+ next: "Siguiente"
@@ -0,0 +1,55 @@
1
+ fr:
2
+ postnhost:
3
+ public:
4
+ site:
5
+ schema_site_name: "PostnHost"
6
+ blog_tagline: "Blog"
7
+ blog_subtitle: "Découvrez les dernières idées, tutoriels et histoires"
8
+ blog_meta_title: "Blog — PostnHost"
9
+ blog_meta_description: "Découvrez les dernières idées, tutoriels et histoires de PostnHost."
10
+ blog_meta_title_paginated: "Page %{page} — %{blog_meta_title}"
11
+ name_footer_copyright: "postnhost.com"
12
+
13
+ blog:
14
+ page_title: "Page %{page} — Blog"
15
+ author_label: "Auteur"
16
+ no_articles: "Pas encore d’articles"
17
+ no_articles_description: "Revenez bientôt pour découvrir de nouveaux contenus."
18
+ back_to_articles: "Retour aux articles"
19
+ more_in_category: "Plus d’articles dans %{category}"
20
+ available_in_languages: "Disponible dans d’autres langues :"
21
+ browse_all_articles: "Parcourir tous les articles"
22
+ read_more: "Articles similaires"
23
+ read_article_aria_label: "Lire « %{title} »"
24
+ top_picks: "À la une"
25
+
26
+ search:
27
+ title: "Résultats de recherche pour « %{query} »"
28
+ heading: "Résultats de recherche pour « %{query} »"
29
+ input_placeholder: "Rechercher par titre ou contenu"
30
+ submit: "Rechercher"
31
+
32
+ category:
33
+ title: "%{category} — PostnHost"
34
+ page_title: "Page %{page} — %{category} — PostnHost"
35
+ page_heading: "Page %{page} — %{category}"
36
+ no_articles: "Aucun article trouvé"
37
+ no_articles_description: "Il n’y a pas encore d’articles publiés dans cette catégorie."
38
+
39
+ authors:
40
+ latest_from_author: "Derniers articles de cet auteur"
41
+ no_articles: "Pas encore d’articles"
42
+ no_articles_description: "Cet auteur n’a pas encore publié d’articles."
43
+
44
+ footer:
45
+ heading: "Pied de page"
46
+ explore_categories: "Articles par catégorie"
47
+ pages: "Pages"
48
+
49
+ breadcrumbs:
50
+ home: "Accueil"
51
+
52
+ pagination:
53
+ navigation: "Pagination"
54
+ previous: "Précédent"
55
+ next: "Suivant"
@@ -0,0 +1,55 @@
1
+ ja:
2
+ postnhost:
3
+ public:
4
+ site:
5
+ schema_site_name: "PostnHost"
6
+ blog_tagline: "ブログ"
7
+ blog_subtitle: "最新の洞察、チュートリアル、ストーリーをご覧ください"
8
+ blog_meta_title: "ブログ|PostnHost"
9
+ blog_meta_description: "PostnHostの最新の洞察、チュートリアル、ストーリーをご覧ください。"
10
+ blog_meta_title_paginated: "ページ %{page}|%{blog_meta_title}"
11
+ name_footer_copyright: "postnhost.com"
12
+
13
+ blog:
14
+ page_title: "ページ %{page}|ブログ"
15
+ author_label: "著者"
16
+ no_articles: "まだ記事がありません"
17
+ no_articles_description: "新しいコンテンツをお楽しみに。"
18
+ back_to_articles: "記事一覧に戻る"
19
+ more_in_category: "%{category}の記事をもっと見る"
20
+ available_in_languages: "他の言語でも読めます:"
21
+ browse_all_articles: "すべての記事を見る"
22
+ read_more: "関連記事"
23
+ read_article_aria_label: "「%{title}」を読む"
24
+ top_picks: "おすすめ記事"
25
+
26
+ search:
27
+ title: "「%{query}」の検索結果"
28
+ heading: "「%{query}」の検索結果"
29
+ input_placeholder: "タイトルまたは内容で検索"
30
+ submit: "検索"
31
+
32
+ category:
33
+ title: "%{category}|PostnHost"
34
+ page_title: "ページ %{page}|%{category}|PostnHost"
35
+ page_heading: "ページ %{page}|%{category}"
36
+ no_articles: "記事が見つかりません"
37
+ no_articles_description: "このカテゴリーにはまだ公開された記事がありません。"
38
+
39
+ authors:
40
+ latest_from_author: "この著者の最新記事"
41
+ no_articles: "まだ記事がありません"
42
+ no_articles_description: "この著者はまだ記事を公開していません。"
43
+
44
+ footer:
45
+ heading: "フッター"
46
+ explore_categories: "カテゴリー別の記事"
47
+ pages: "ページ"
48
+
49
+ breadcrumbs:
50
+ home: "ホーム"
51
+
52
+ pagination:
53
+ navigation: "ページナビゲーション"
54
+ previous: "前へ"
55
+ next: "次へ"
@@ -0,0 +1,55 @@
1
+ ko:
2
+ postnhost:
3
+ public:
4
+ site:
5
+ schema_site_name: "PostnHost"
6
+ blog_tagline: "블로그"
7
+ blog_subtitle: "최신 인사이트, 튜토리얼, 스토리를 만나보세요"
8
+ blog_meta_title: "블로그 — PostnHost"
9
+ blog_meta_description: "PostnHost의 최신 인사이트, 튜토리얼, 스토리를 만나보세요."
10
+ blog_meta_title_paginated: "페이지 %{page} — %{blog_meta_title}"
11
+ name_footer_copyright: "postnhost.com"
12
+
13
+ blog:
14
+ page_title: "페이지 %{page} — 블로그"
15
+ author_label: "작성자"
16
+ no_articles: "아직 게시물이 없습니다"
17
+ no_articles_description: "새로운 콘텐츠가 곧 공개됩니다."
18
+ back_to_articles: "게시물 목록으로"
19
+ more_in_category: "%{category} 카테고리 글 더 보기"
20
+ available_in_languages: "다른 언어로 보기:"
21
+ browse_all_articles: "모든 게시물 보기"
22
+ read_more: "관련 글"
23
+ read_article_aria_label: "“%{title}” 읽기"
24
+ top_picks: "추천 글"
25
+
26
+ search:
27
+ title: "“%{query}” 검색 결과"
28
+ heading: "“%{query}” 검색 결과"
29
+ input_placeholder: "제목 또는 내용으로 검색"
30
+ submit: "검색"
31
+
32
+ category:
33
+ title: "%{category} — PostnHost"
34
+ page_title: "페이지 %{page} — %{category} — PostnHost"
35
+ page_heading: "페이지 %{page} — %{category}"
36
+ no_articles: "게시물을 찾을 수 없습니다"
37
+ no_articles_description: "이 카테고리에는 아직 게시된 글이 없습니다."
38
+
39
+ authors:
40
+ latest_from_author: "이 작성자의 최신 글"
41
+ no_articles: "아직 게시물이 없습니다"
42
+ no_articles_description: "이 작성자는 아직 게시물을 발행하지 않았습니다."
43
+
44
+ footer:
45
+ heading: "푸터"
46
+ explore_categories: "카테고리별 글 둘러보기"
47
+ pages: "페이지"
48
+
49
+ breadcrumbs:
50
+ home: "홈"
51
+
52
+ pagination:
53
+ navigation: "페이지 탐색"
54
+ previous: "이전"
55
+ next: "다음"
@@ -0,0 +1,55 @@
1
+ pl:
2
+ postnhost:
3
+ public:
4
+ site:
5
+ schema_site_name: "PostnHost"
6
+ blog_tagline: "Blog"
7
+ blog_subtitle: "Odkryj najnowsze spostrzeżenia, tutoriale i historie"
8
+ blog_meta_title: "Blog – PostnHost"
9
+ blog_meta_description: "Odkryj najnowsze spostrzeżenia, poradniki i historie z PostnHost."
10
+ blog_meta_title_paginated: "Strona %{page} – %{blog_meta_title}"
11
+ name_footer_copyright: "postnhost.com"
12
+
13
+ blog:
14
+ page_title: "Strona %{page} – Blog"
15
+ author_label: "Autor"
16
+ no_articles: "Nie ma jeszcze artykułów"
17
+ no_articles_description: "Wkrótce pojawią się nowe treści."
18
+ back_to_articles: "Powrót do artykułów"
19
+ more_in_category: "Więcej w kategorii %{category}"
20
+ available_in_languages: "Dostępne w innych językach:"
21
+ browse_all_articles: "Przeglądaj wszystkie artykuły"
22
+ read_more: "Powiązane artykuły"
23
+ read_article_aria_label: "Przeczytaj „%{title}”"
24
+ top_picks: "Polecane"
25
+
26
+ search:
27
+ title: "Wyniki wyszukiwania dla „%{query}”"
28
+ heading: "Wyniki wyszukiwania dla „%{query}”"
29
+ input_placeholder: "Szukaj po tytule lub treści"
30
+ submit: "Szukaj"
31
+
32
+ category:
33
+ title: "%{category} – PostnHost"
34
+ page_title: "Strona %{page} – %{category} – PostnHost"
35
+ page_heading: "Strona %{page} – %{category}"
36
+ no_articles: "Nie znaleziono artykułów"
37
+ no_articles_description: "W tej kategorii nie ma jeszcze opublikowanych artykułów."
38
+
39
+ authors:
40
+ latest_from_author: "Najnowsze artykuły tego autora"
41
+ no_articles: "Nie ma jeszcze artykułów"
42
+ no_articles_description: "Ten autor nie opublikował jeszcze żadnych artykułów."
43
+
44
+ footer:
45
+ heading: "Stopka"
46
+ explore_categories: "Wpisy według kategorii"
47
+ pages: "Strony"
48
+
49
+ breadcrumbs:
50
+ home: "Strona główna"
51
+
52
+ pagination:
53
+ navigation: "Paginacja"
54
+ previous: "Poprzednia"
55
+ next: "Następna"
@@ -0,0 +1,55 @@
1
+ pt:
2
+ postnhost:
3
+ public:
4
+ site:
5
+ schema_site_name: "PostnHost"
6
+ blog_tagline: "Blog"
7
+ blog_subtitle: "Descubra os últimos insights, tutoriais e histórias"
8
+ blog_meta_title: "Blog — PostnHost"
9
+ blog_meta_description: "Descubra os insights, tutoriais e histórias mais recentes do PostnHost."
10
+ blog_meta_title_paginated: "Página %{page} — %{blog_meta_title}"
11
+ name_footer_copyright: "postnhost.com"
12
+
13
+ blog:
14
+ page_title: "Página %{page} — Blog"
15
+ author_label: "Autor"
16
+ no_articles: "Ainda não há artigos"
17
+ no_articles_description: "Volte em breve para conferir novos conteúdos."
18
+ back_to_articles: "Voltar aos artigos"
19
+ more_in_category: "Mais em %{category}"
20
+ available_in_languages: "Disponível em outros idiomas:"
21
+ browse_all_articles: "Ver todos os artigos"
22
+ read_more: "Artigos relacionados"
23
+ read_article_aria_label: "Ler “%{title}”"
24
+ top_picks: "Destaques"
25
+
26
+ search:
27
+ title: "Resultados da busca por “%{query}”"
28
+ heading: "Resultados da busca por “%{query}”"
29
+ input_placeholder: "Buscar por título ou conteúdo"
30
+ submit: "Buscar"
31
+
32
+ category:
33
+ title: "%{category} — PostnHost"
34
+ page_title: "Página %{page} — %{category} — PostnHost"
35
+ page_heading: "Página %{page} — %{category}"
36
+ no_articles: "Nenhum artigo encontrado"
37
+ no_articles_description: "Ainda não há artigos publicados nesta categoria."
38
+
39
+ authors:
40
+ latest_from_author: "Artigos mais recentes deste autor"
41
+ no_articles: "Ainda não há artigos"
42
+ no_articles_description: "Este autor ainda não publicou nenhum artigo."
43
+
44
+ footer:
45
+ heading: "Rodapé"
46
+ explore_categories: "Artigos por categoria"
47
+ pages: "Páginas"
48
+
49
+ breadcrumbs:
50
+ home: "Início"
51
+
52
+ pagination:
53
+ navigation: "Paginação"
54
+ previous: "Anterior"
55
+ next: "Próxima"