spina-admin-conferences-blog 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +42 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/config/spina_admin_conferences_blog_manifest.js +0 -0
  6. data/app/controllers/spina/admin/conferences/blog/categories_controller.rb +80 -0
  7. data/app/controllers/spina/admin/conferences/blog/posts_controller.rb +103 -0
  8. data/app/decorators/spina/admin/conferences/blog/post_decorator.rb +26 -0
  9. data/app/helpers/spina/admin/conferences/blog/posts_helper.rb +18 -0
  10. data/app/models/spina/admin/conferences/blog/application_record.rb +12 -0
  11. data/app/models/spina/admin/conferences/blog/category.rb +23 -0
  12. data/app/models/spina/admin/conferences/blog/post.rb +52 -0
  13. data/app/models/spina/admin/conferences/blog.rb +10 -0
  14. data/app/views/layouts/spina/admin/conferences/blog/blog.html.haml +29 -0
  15. data/app/views/layouts/spina/admin/conferences/blog/categories.html.haml +10 -0
  16. data/app/views/spina/admin/conferences/blog/categories/_category.html.haml +8 -0
  17. data/app/views/spina/admin/conferences/blog/categories/_form.html.haml +42 -0
  18. data/app/views/spina/admin/conferences/blog/categories/edit.html.haml +3 -0
  19. data/app/views/spina/admin/conferences/blog/categories/index.html.haml +23 -0
  20. data/app/views/spina/admin/conferences/blog/categories/new.html.haml +2 -0
  21. data/app/views/spina/admin/conferences/blog/posts/_form.html.haml +43 -0
  22. data/app/views/spina/admin/conferences/blog/posts/_form_post_configuration.html.haml +50 -0
  23. data/app/views/spina/admin/conferences/blog/posts/_form_post_content.html.haml +46 -0
  24. data/app/views/spina/admin/conferences/blog/posts/_form_post_seo.html.haml +14 -0
  25. data/app/views/spina/admin/conferences/blog/posts/_post.html.haml +19 -0
  26. data/app/views/spina/admin/conferences/blog/posts/edit.html.haml +3 -0
  27. data/app/views/spina/admin/conferences/blog/posts/index.html.haml +23 -0
  28. data/app/views/spina/admin/conferences/blog/posts/new.html.haml +2 -0
  29. data/app/views/spina/admin/hooks/conferences/blog/_primary_navigation.html.haml +10 -0
  30. data/config/initializers/friendly_id.rb +94 -0
  31. data/config/locales/en.yml +41 -0
  32. data/config/locales/nl.yml +42 -0
  33. data/config/locales/pt-BR.yml +41 -0
  34. data/config/routes.rb +32 -0
  35. data/db/migrate/1_create_spina_blog_posts.rb +18 -0
  36. data/db/migrate/2_create_spina_blog_friendly_id_slugs.rb +19 -0
  37. data/db/migrate/3_create_spina_blog_categories.rb +12 -0
  38. data/db/migrate/4_add_category_id_to_spina_blog_posts.rb +7 -0
  39. data/db/migrate/5_add_featured_to_spina_blog_posts.rb +9 -0
  40. data/db/migrate/6_add_seo_fields.rb +11 -0
  41. data/lib/generators/spina_admin_conferences_blog/install_generator.rb +24 -0
  42. data/lib/spina/admin/conferences/blog/configuration.rb +17 -0
  43. data/lib/spina/admin/conferences/blog/engine.rb +24 -0
  44. data/lib/spina/admin/conferences/blog/version.rb +8 -0
  45. data/lib/spina/admin/conferences/blog.rb +18 -0
  46. data/lib/spina/admin/conferences.rb +6 -0
  47. data/lib/spina/admin.rb +5 -0
  48. data/lib/tasks/spina/admin/conferences/blog_tasks.rake +14 -0
  49. data/spec/controllers/spina/admin/conferences/blog/categories_controller_spec.rb +99 -0
  50. data/spec/controllers/spina/admin/conferences/blog/posts_controller_spec.rb +152 -0
  51. data/spec/dummy/Rakefile +8 -0
  52. data/spec/dummy/app/assets/config/manifest.js +4 -0
  53. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  54. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  55. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  56. data/spec/dummy/app/assets/stylesheets/default/application.css.sass +0 -0
  57. data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
  58. data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
  59. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  60. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  61. data/spec/dummy/app/jobs/application_job.rb +4 -0
  62. data/spec/dummy/app/mailers/application_mailer.rb +6 -0
  63. data/spec/dummy/app/models/application_record.rb +6 -0
  64. data/spec/dummy/app/views/default/pages/homepage.html.haml +2 -0
  65. data/spec/dummy/app/views/default/pages/show.html.haml +3 -0
  66. data/spec/dummy/app/views/default/shared/_navigation.html.haml +2 -0
  67. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  68. data/spec/dummy/app/views/layouts/default/application.html.haml +11 -0
  69. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  70. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  71. data/spec/dummy/bin/bundle +5 -0
  72. data/spec/dummy/bin/rails +6 -0
  73. data/spec/dummy/bin/rake +6 -0
  74. data/spec/dummy/bin/setup +36 -0
  75. data/spec/dummy/bin/update +31 -0
  76. data/spec/dummy/config/application.rb +16 -0
  77. data/spec/dummy/config/boot.rb +7 -0
  78. data/spec/dummy/config/cable.yml +9 -0
  79. data/spec/dummy/config/database.yml +17 -0
  80. data/spec/dummy/config/environment.rb +7 -0
  81. data/spec/dummy/config/environments/development.rb +56 -0
  82. data/spec/dummy/config/environments/production.rb +88 -0
  83. data/spec/dummy/config/environments/test.rb +44 -0
  84. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  85. data/spec/dummy/config/initializers/assets.rb +13 -0
  86. data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
  87. data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
  88. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  89. data/spec/dummy/config/initializers/inflections.rb +18 -0
  90. data/spec/dummy/config/initializers/mime_types.rb +6 -0
  91. data/spec/dummy/config/initializers/mobility.rb +16 -0
  92. data/spec/dummy/config/initializers/new_framework_defaults.rb +25 -0
  93. data/spec/dummy/config/initializers/session_store.rb +5 -0
  94. data/spec/dummy/config/initializers/spina.rb +22 -0
  95. data/spec/dummy/config/initializers/themes/default.rb +32 -0
  96. data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
  97. data/spec/dummy/config/locales/en.yml +23 -0
  98. data/spec/dummy/config/puma.rb +49 -0
  99. data/spec/dummy/config/routes.rb +6 -0
  100. data/spec/dummy/config/secrets.yml +22 -0
  101. data/spec/dummy/config/spring.rb +8 -0
  102. data/spec/dummy/config.ru +7 -0
  103. data/spec/dummy/db/migrate/20190513103729_create_spina_tables.spina.rb +132 -0
  104. data/spec/dummy/db/migrate/20190513103730_create_spina_translation_tables.spina.rb +46 -0
  105. data/spec/dummy/db/migrate/20190513103731_create_spina_navigations.spina.rb +24 -0
  106. data/spec/dummy/db/migrate/20190513103732_add_password_reset_token_to_spina_users.spina.rb +9 -0
  107. data/spec/dummy/db/migrate/20190513103733_remove_translated_columns.spina.rb +14 -0
  108. data/spec/dummy/db/migrate/20190513103734_create_spina_options.spina.rb +11 -0
  109. data/spec/dummy/db/migrate/20190513103735_create_spina_settings.spina.rb +14 -0
  110. data/spec/dummy/db/migrate/20190513103736_create_spina_media_folders.spina.rb +11 -0
  111. data/spec/dummy/db/migrate/20190513103737_create_spina_images.spina.rb +13 -0
  112. data/spec/dummy/db/migrate/20190513103738_create_spina_image_collections.spina.rb +17 -0
  113. data/spec/dummy/db/migrate/20190513103739_create_spina_resources.spina.rb +18 -0
  114. data/spec/dummy/db/schema.rb +288 -0
  115. data/spec/dummy/db/seeds.rb +4 -0
  116. data/spec/dummy/public/404.html +67 -0
  117. data/spec/dummy/public/422.html +67 -0
  118. data/spec/dummy/public/500.html +66 -0
  119. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  120. data/spec/dummy/public/apple-touch-icon.png +0 -0
  121. data/spec/dummy/public/favicon.ico +0 -0
  122. data/spec/factories/spina/admin/conferences/blog/categories.rb +11 -0
  123. data/spec/factories/spina/admin/conferences/blog/posts.rb +16 -0
  124. data/spec/models/spina/admin/conferences/blog/category_spec.rb +21 -0
  125. data/spec/models/spina/admin/conferences/blog/post_spec.rb +39 -0
  126. data/spec/rails_helper.rb +68 -0
  127. data/spec/spec_helper.rb +97 -0
  128. data/spec/support/capybara.rb +25 -0
  129. data/spec/support/controller_helpers.rb +25 -0
  130. data/spec/support/controller_routes.rb +13 -0
  131. data/spec/support/factory_bot.rb +5 -0
  132. data/spec/support/rails_controller_testing.rb +13 -0
  133. data/spec/support/system_tests.rb +11 -0
  134. data/spec/system/spina/admin/conferences/blog/posts_spec.rb +34 -0
  135. data/spec/system/support/image.png +0 -0
  136. metadata +508 -0
@@ -0,0 +1,46 @@
1
+ .tab-content.active#post_content
2
+ .page-form
3
+ .page-form-group
4
+ .page-form-label
5
+ = Spina::Admin::Conferences::Blog::Post.human_attribute_name :title
6
+ .page-form-content
7
+ = f.text_field :title, placeholder: Spina::Admin::Conferences::Blog::Post.human_attribute_name(:title_placeholder)
8
+
9
+ .page-form-group
10
+ .page-form-label
11
+ = Spina::Admin::Conferences::Blog::Post.human_attribute_name :excerpt
12
+ .page-form-content
13
+ .page-form-rich-text
14
+ = f.hidden_field :excerpt, id: 'excerpt_input'
15
+ %trix-editor.text-input.trix-content{ input: 'excerpt_input' }
16
+
17
+
18
+ .page-form-group
19
+ .page-form-label
20
+ = Spina::Admin::Conferences::Blog::Post.human_attribute_name :content
21
+ .page-form-content
22
+ .page-form-rich-text
23
+ = f.hidden_field :content, id: 'content_input'
24
+ %trix-editor.text-input.trix-content{ input: 'content_input' }
25
+
26
+ .page-form-group
27
+ .page-form-label
28
+ = Spina::Admin::Conferences::Blog::Post.human_attribute_name :image_id
29
+ .page-form-control{ data: { controller: 'image-form' } }
30
+ .page-form-media-picker
31
+ %div{ style: 'width: 100%' }
32
+ = link_to spina.admin_media_picker_path(selected_ids: [f.object.image_id],
33
+ input: "media_picker_#{f.object.object_id}_image_id", mode: 'single'), remote: true, class: 'image',
34
+ data: { target: 'image-form.image' } do
35
+ .page-form-media-picker-placeholder= t 'spina.images.choose_image'
36
+ %div{ id: "media_picker_#{f.object.object_id}_image_id" }
37
+ = hidden_field_tag :signed_blob_id, '', data: { target: 'image-form.signedBlobId' }
38
+ = hidden_field_tag :filename, '', data: { target: 'image-form.filename' }
39
+ = f.hidden_field :image_id, data: { target: 'image-form.imageId' }
40
+ %div
41
+ - if f.object.image.present?
42
+ = image_tag main_app.url_for(f.object.image.variant(resize: '400x300^', crop: '400x300+0+0')), width: 200, height: 150
43
+
44
+ = button_tag type: :default, class: 'button button-small button-white',
45
+ data: { action: 'image-form#remove' } do
46
+ %i.icon.icon-cross{ style: 'margin: 0; font-size: 10px' }
@@ -0,0 +1,14 @@
1
+ .tab-content#post_seo
2
+ .horizontal-form
3
+ %div{style: "margin: 40px 0"}
4
+ .horizontal-form-group
5
+ .horizontal-form-label
6
+ = Spina::Admin::Conferences::Blog::Post.human_attribute_name :seo_title
7
+ .horizontal-form-content
8
+ = f.text_field :seo_title, placeholder: Spina::Admin::Conferences::Blog::Post.human_attribute_name(:seo_title_placeholder)
9
+
10
+ .horizontal-form-group
11
+ .horizontal-form-label
12
+ = Spina::Admin::Conferences::Blog::Post.human_attribute_name :description
13
+ .horizontal-form-content
14
+ = f.text_field :description, placeholder: Spina::Admin::Conferences::Blog::Post.human_attribute_name(:description_placeholder)
@@ -0,0 +1,19 @@
1
+ %tr{data: { id: post.id }}
2
+ %td.nowrap
3
+ %h3= link_to post.title, spina.edit_admin_conferences_blog_post_path(post.id)
4
+ %small #{time_ago_in_words(post.created_at)} ago
5
+ .labels
6
+ - if post.draft?
7
+ %span.label.label-info= t('spina.blog.posts.concept')
8
+ - if post.published_at and post.published_at > Time.now
9
+ %span.label.label-default
10
+ Will be published on #{post.decorate.published_date}
11
+
12
+ %td.nowrap.text-right
13
+ = link_to spina.blog_post_path(post), class: 'button button-small button-link dd-nodrag', target: '_blank' do
14
+ = icon 'eye'
15
+ = t('spina.view')
16
+
17
+ = link_to spina.edit_admin_conferences_blog_post_path(post.id), class: 'button button-link' do
18
+ = icon 'pencil-outline'
19
+ = t('spina.blog.posts.edit')
@@ -0,0 +1,3 @@
1
+ = form_for [spina, :admin, :conferences, :blog, @post], url: spina.admin_conferences_blog_post_path(@post.id),
2
+ html: {id: 'post_form', autocomplete: "off"} do |f|
3
+ = render 'form', f: f
@@ -0,0 +1,23 @@
1
+ - content_for :header_actions do
2
+ %span
3
+ = link_to spina.new_admin_conferences_blog_post_path, class: 'button button-primary', style: 'margin-right: 0' do
4
+ = icon 'plus'
5
+ = t 'spina.blog.posts.new'
6
+
7
+
8
+
9
+ .table-container
10
+ %table.table
11
+ %thead
12
+ %tr
13
+ %th Post Title
14
+ %th
15
+
16
+ %tbody
17
+ - if @posts.any?
18
+ = render partial: 'post', collection: @posts, as: :post
19
+
20
+ - else
21
+ %tr
22
+ %td.align-center{colspan: 2}
23
+ %em There are no posts yet. Create your first one!
@@ -0,0 +1,2 @@
1
+ = form_for [spina, :admin, :conferences, :blog, @post], html: {id: 'post_form', autocomplete: "off"} do |f|
2
+ = render 'form', f: f
@@ -0,0 +1,10 @@
1
+ %li{class: ('active' if (current_admin_path.start_with?('/blog')))}
2
+ = link_to spina.admin_conferences_blog_posts_path do
3
+ = icon 'comment'
4
+ = t('spina.blog.title')
5
+ = icon 'caret-right'
6
+ %ul
7
+ %li{class: ('active' if current_admin_path.start_with?('/blog/posts'))}
8
+ = link_to t('spina.blog.posts.title'), spina.admin_conferences_blog_posts_path
9
+ %li{class: ('active' if current_admin_path.start_with?('/blog/categories'))}
10
+ = link_to t('spina.blog.categories.title'), spina.admin_conferences_blog_categories_path
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ # FriendlyId Global Configuration
4
+ #
5
+ # Use this to set up shared configuration options for your entire application.
6
+ # Any of the configuration options shown here can also be applied to single
7
+ # models by passing arguments to the `friendly_id` class method or defining
8
+ # methods in your model.
9
+ #
10
+ # To learn more, check out the guide:
11
+ #
12
+ # http://norman.github.io/friendly_id/file.Guide.html
13
+
14
+ FriendlyId.defaults do |config|
15
+ # ## Reserved Words
16
+ #
17
+ # Some words could conflict with Rails's routes when used as slugs, or are
18
+ # undesirable to allow as slugs. Edit this list as needed for your app.
19
+ config.use :reserved
20
+
21
+ config.reserved_words = %w[new edit index session login logout users admin
22
+ stylesheets assets javascripts images]
23
+
24
+ # ## Friendly Finders
25
+ #
26
+ # Uncomment this to use friendly finders in all models. By default, if
27
+ # you wish to find a record by its friendly id, you must do:
28
+ #
29
+ # MyModel.friendly.find('foo')
30
+ #
31
+ # If you uncomment this, you can do:
32
+ #
33
+ # MyModel.find('foo')
34
+ #
35
+ # This is significantly more convenient but may not be appropriate for
36
+ # all applications, so you must explicity opt-in to this behavior. You can
37
+ # always also configure it on a per-model basis if you prefer.
38
+ #
39
+ # Something else to consider is that using the :finders addon boosts
40
+ # performance because it will avoid Rails-internal code that makes runtime
41
+ # calls to `Module.extend`.
42
+ #
43
+ # config.use :finders
44
+ #
45
+ # ## Slugs
46
+ #
47
+ # Most applications will use the :slugged module everywhere. If you wish
48
+ # to do so, uncomment the following line.
49
+ #
50
+ # config.use :slugged
51
+ #
52
+ # By default, FriendlyId's :slugged addon expects the slug column to be named
53
+ # 'slug', but you can change it if you wish.
54
+ #
55
+ # config.slug_column = 'slug'
56
+ #
57
+ # When FriendlyId can not generate a unique ID from your base method, it appends
58
+ # a UUID, separated by a single dash. You can configure the character used as the
59
+ # separator. If you're upgrading from FriendlyId 4, you may wish to replace this
60
+ # with two dashes.
61
+ #
62
+ # config.sequence_separator = '-'
63
+ #
64
+ # Note that you must use the :slugged addon **prior** to the line which
65
+ # configures the sequence separator, or else FriendlyId will raise an undefined
66
+ # method error.
67
+ #
68
+ # ## Tips and Tricks
69
+ #
70
+ # ### Controlling when slugs are generated
71
+ #
72
+ # As of FriendlyId 5.0, new slugs are generated only when the slug field is
73
+ # nil, but if you're using a column as your base method can change this
74
+ # behavior by overriding the `should_generate_new_friendly_id?` method that
75
+ # FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave
76
+ # more like 4.0.
77
+ #
78
+ # config.use Module.new {
79
+ # def should_generate_new_friendly_id?
80
+ # slug.blank? || <your_column_name_here>_changed?
81
+ # end
82
+ # }
83
+ #
84
+ # FriendlyId uses Rails's `parameterize` method to generate slugs, but for
85
+ # languages that don't use the Roman alphabet, that's not usually sufficient.
86
+ # Here we use the Babosa library to transliterate Russian Cyrillic slugs to
87
+ # ASCII. If you use this, don't forget to add "babosa" to your Gemfile.
88
+ #
89
+ # config.use Module.new {
90
+ # def normalize_friendly_id(text)
91
+ # text.to_slug.normalize! :transliterations => [:russian, :latin]
92
+ # end
93
+ # }
94
+ end
@@ -0,0 +1,41 @@
1
+ en:
2
+ spina:
3
+ view: View
4
+
5
+ blog:
6
+ title: Blog
7
+
8
+ posts:
9
+ title: Posts
10
+ new: New Post
11
+ save: Save post
12
+ saving: Saving...
13
+ saved: Post saved
14
+ post_content: Content
15
+ post_configuration: Settings
16
+ concept: Draft
17
+
18
+ categories:
19
+ title: Categories
20
+ new: New Category
21
+ name: Categories
22
+ save: Save category
23
+ saving: Saving...
24
+ saved: Category saved
25
+
26
+ activerecord:
27
+ attributes:
28
+ spina/blog/post:
29
+ title: Post title
30
+ title_placeholder: Post title
31
+ content: Post content
32
+ draft: Draft
33
+ draft_description: Great for when your post is not quite finished
34
+ published_at: Publishing date/time
35
+ slug: Permalink
36
+ slug_description: Permalink URL for this post
37
+ excerpt: Excerpt
38
+ spina_user: Author
39
+ spina/blog/category:
40
+ name: Category name
41
+ name_placeholder: Category name
@@ -0,0 +1,42 @@
1
+ nl:
2
+ spina:
3
+ view: View
4
+
5
+ blog:
6
+ title: Blog
7
+
8
+ posts:
9
+ title: Posts
10
+ new: Nieuwe post
11
+ save: Post opslaan
12
+ saving: Opslaan...
13
+ saved: Post opgeslagen
14
+ post_content: Inhoud
15
+ post_configuration: Instellingen
16
+ concept: Concept
17
+
18
+ categories:
19
+ title: Categorieën
20
+ new: Nieuwe categorie
21
+ name: Categoriën
22
+ save: Categorie opslaan
23
+ saving: Opslaan...
24
+ saved: Categorie opgeslagen
25
+
26
+ activerecord:
27
+ attributes:
28
+ spina/blog/post:
29
+ title: Post titel
30
+ title_placeholder: Post titel
31
+ content: Post inhoud
32
+ draft: Concept
33
+ draft_description: Handig voor als je post nog niet helemaal af is
34
+ published_at: Publicatiedatum/tijd
35
+ slug: Permalink
36
+ slug_description: Permalink URL for this post
37
+ excerpt: Uittreksel
38
+ spina_user: Auteur
39
+ photo: Afbeelding
40
+ spina/blog/category:
41
+ name: Naam categorie
42
+ name_placeholder: Naam categorie
@@ -0,0 +1,41 @@
1
+ pt-BR:
2
+ spina:
3
+ view: Visão
4
+
5
+ blog:
6
+ title: Blog
7
+
8
+ posts:
9
+ title: Postagens
10
+ new: Nova Postagem
11
+ save: Salvar postagem
12
+ saving: Salvando...
13
+ saved: Postagem salva
14
+ post_content: Conteúdo
15
+ post_configuration: Configurações
16
+ concept: Rascunho
17
+
18
+ categories:
19
+ title: Categorias
20
+ new: Nova Categoria
21
+ name: Categorias
22
+ save: Salvar categoria
23
+ saving: Salvando...
24
+ saved: Categoria salva
25
+
26
+ activerecord:
27
+ attributes:
28
+ spina/blog/post:
29
+ title: Título da Postagem
30
+ title_placeholder: Título da Postagem
31
+ content: Conteúdo da postagem
32
+ draft: Rascunho
33
+ draft_description: Ótimo quando sua postagem não está finalizada
34
+ published_at: Data/hora da publicação
35
+ slug: Permalink
36
+ slug_description: URL Permalink para esta postagem
37
+ excerpt: Resumo
38
+ spina_user: Autor
39
+ spina/blog/category:
40
+ name: Nome da categoria
41
+ name_placeholder: Nome da categoria
data/config/routes.rb ADDED
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ Spina::Engine.routes.draw do
4
+ namespace :blog do
5
+ root to: 'posts#index'
6
+
7
+ get ':id', to: 'posts#show', as: :post
8
+
9
+ # Redirects for old sites that used the old blog path
10
+ get 'posts/', to: redirect('/blog'), as: :old_index
11
+ get 'posts/:id', to: redirect('/blog/%{id}'), as: :old_post
12
+
13
+ get 'feed.atom', to: 'posts#index', as: :rss_feed, defaults: { format: :atom }
14
+ get 'categories/:id', to: 'categories#show', as: :category
15
+ get 'archive/:year(/:month)', to: 'posts#archive', as: :archive_posts
16
+ end
17
+
18
+ namespace :admin, path: Spina.config.backend_path do
19
+ namespace :conferences do
20
+ namespace :blog do
21
+ resources :categories
22
+ resources :posts, except: :show do
23
+ collection do
24
+ get :live
25
+ get :draft
26
+ get :future
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateSpinaBlogPosts < ActiveRecord::Migration[5.0]
4
+ def change
5
+ create_table :spina_blog_posts do |t|
6
+ t.string :title
7
+ t.text :excerpt
8
+ t.text :content
9
+ t.references :image, foreign_key: { to_table: :spina_images }
10
+ t.boolean :draft
11
+ t.datetime :published_at
12
+ t.string :slug, unique: true, index: true
13
+ t.references :user, foreign_key: { to_table: :spina_users }
14
+
15
+ t.timestamps
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateSpinaBlogFriendlyIdSlugs < ActiveRecord::Migration[5.0]
4
+ def change
5
+ return if ActiveRecord::Base.connection.table_exists? 'friendly_id_slugs'
6
+
7
+ create_table :friendly_id_slugs do |t|
8
+ t.string :slug, null: false
9
+ t.integer :sluggable_id, null: false
10
+ t.string :sluggable_type, limit: 50
11
+ t.string :scope
12
+ t.datetime :created_at
13
+ end
14
+ add_index :friendly_id_slugs, :sluggable_id
15
+ add_index :friendly_id_slugs, %i[slug sluggable_type], length: { slug: 140, sluggable_type: 50 }
16
+ add_index :friendly_id_slugs, %i[slug sluggable_type scope], length: { slug: 70, sluggable_type: 50, scope: 70 }, unique: true
17
+ add_index :friendly_id_slugs, :sluggable_type
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateSpinaBlogCategories < ActiveRecord::Migration[5.0]
4
+ def change
5
+ create_table :spina_blog_categories do |t|
6
+ t.string :name
7
+ t.string :slug, unique: true, index: true
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddCategoryIdToSpinaBlogPosts < ActiveRecord::Migration[5.0]
4
+ def change
5
+ add_reference :spina_blog_posts, :category, to_table: :spina_blog_categories
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # AddCategoryIdToSpinaBlogPosts
4
+ class AddFeaturedToSpinaBlogPosts < ActiveRecord::Migration[5.2]
5
+ def change
6
+ add_column :spina_blog_posts, :featured, :boolean, index: true,
7
+ default: false
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Addition of SEO fields
4
+ class AddSeoFields < ActiveRecord::Migration[5.2]
5
+ def change
6
+ change_table :spina_blog_posts do |t|
7
+ t.string :seo_title
8
+ t.text :description
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SpinaBlog
4
+ class InstallGenerator < Rails::Generators::Base
5
+ def copy_migrations
6
+ return if Rails.env.production?
7
+
8
+ rake 'spina_conferences_blog:install:migrations'
9
+ end
10
+
11
+ def run_migrations
12
+ rake 'db:migrate'
13
+ end
14
+
15
+ def feedback
16
+ puts
17
+ puts ' Spina Conferences Blog has been succesfully installed! '
18
+ puts
19
+ puts ' Restart your server and visit http://localhost:3000 in your browser!'
20
+ puts " The admin backend is located at http://localhost:3000/#{Spina.config.backend_path}."
21
+ puts
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ # Spina::Blog
5
+ module Admin::Conferences::Blog
6
+ include ActiveSupport::Configurable
7
+
8
+ config_accessor :title, :controller, :description, :spina_icon, :plugin_type
9
+
10
+ self.title = 'Blog'
11
+ self.controller = 'blog'
12
+ self.description = 'Blog posts'
13
+ self.spina_icon = 'pencil-outline'
14
+
15
+ self.plugin_type = 'website_resource'
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ module Admin::Conferences::Blog
5
+ # Spina::Blog::Engine
6
+ class Engine < ::Rails::Engine
7
+ isolate_namespace Spina::Admin::Conferences::Blog
8
+
9
+ config.before_initialize do
10
+ ::Spina::Plugin.register do |plugin|
11
+ plugin.name = 'conferences-blog'
12
+ plugin.namespace = 'conferences/blog'
13
+ end
14
+ end
15
+
16
+ config.generators do |g|
17
+ g.test_framework :rspec, fixture: false
18
+ g.fixture_replacement :factory_bot, dir: 'spec/factories'
19
+ g.assets false
20
+ g.helper false
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spina
4
+ # Spina::Blog
5
+ module Admin::Conferences::Blog
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'friendly_id'
4
+ require 'draper'
5
+ require 'spina'
6
+ require 'nokogiri'
7
+
8
+ module Spina
9
+ # Spina::Blog
10
+ module Admin
11
+ module Conferences
12
+ module Blog
13
+ require 'spina/admin/conferences/blog/engine'
14
+ require 'spina/admin/conferences/blog/configuration'
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ module Spina
2
+ module Admin
3
+ module Conferences
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Spina
2
+ module Admin
3
+
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # desc "Explaining what the task does"
4
+ # task :spina_blog do
5
+ # # Task goes here
6
+ # end
7
+
8
+ namespace :spina_conferences_blog do
9
+ task photo_to_image: :environment do
10
+ Blog::Post.find_each do |post|
11
+ post.update_column :image_id, post.photo.image_id
12
+ end
13
+ end
14
+ end