diff --git a/app/models/communication/website/author.rb b/app/models/communication/website/author.rb index 5eb1c1682293bc3599b0cad0fac40d2bc4da747e..40ae840261d872f5edb1348de55b93c6b8bf43ef 100644 --- a/app/models/communication/website/author.rb +++ b/app/models/communication/website/author.rb @@ -26,8 +26,7 @@ # fk_rails_... (user_id => users.id) # class Communication::Website::Author < ApplicationRecord - include WithGithub - include WithJekyll + include WithGithubFiles include WithSlug has_rich_text :biography @@ -51,6 +50,7 @@ class Communication::Website::Author < ApplicationRecord "#{last_name} #{first_name}" end + # Override from WithGithubFiles def github_path_generated "_authors/#{slug}.html" end diff --git a/app/models/communication/website/category.rb b/app/models/communication/website/category.rb index 83f398657394a0e73e372b20e9ffb50d35d31071..97d2e66ecab43b70050247354b30a615a1772a4e 100644 --- a/app/models/communication/website/category.rb +++ b/app/models/communication/website/category.rb @@ -31,8 +31,7 @@ # fk_rails_... (university_id => universities.id) # class Communication::Website::Category < ApplicationRecord - include WithGithub - include WithJekyll + include WithGithubFiles include WithSlug include WithTree @@ -77,6 +76,7 @@ class Communication::Website::Category < ApplicationRecord "#{name}" end + # Override from WithGithubFiles def github_path_generated "_categories/#{slug}.html" end diff --git a/app/models/communication/website/github_file.rb b/app/models/communication/website/github_file.rb new file mode 100644 index 0000000000000000000000000000000000000000..9f456c6e97d5a5d72e22dc24cd1bfe577f7edf8f --- /dev/null +++ b/app/models/communication/website/github_file.rb @@ -0,0 +1,70 @@ +# == Schema Information +# +# Table name: communication_website_github_files +# +# id :uuid not null, primary key +# about_type :string not null +# github_path :string +# created_at :datetime not null +# updated_at :datetime not null +# about_id :uuid not null +# website_id :uuid not null +# +# Indexes +# +# index_communication_website_github_files_on_about (about_type,about_id) +# index_communication_website_github_files_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (website_id => communication_websites.id) +# +class Communication::Website::GithubFile < ApplicationRecord + belongs_to :website, class_name: 'Communication::Website' + belongs_to :about, polymorphic: true + + after_destroy :remove_from_github + + def publish + return unless github.valid? + if github.publish(path: about.github_path_generated, + previous_path: github_path, + commit: github_commit_message, + data: about.to_jekyll(self)) + update_column :github_path, about.github_path_generated + end + end + handle_asynchronously :publish, queue: 'default' + + def add_to_batch(github) + + end + + def github_frontmatter + @github_frontmatter ||= begin + github_content = github.read_file_at(github_path) + FrontMatterParser::Parser.new(:md).call(github_content) + rescue + FrontMatterParser::Parser.new(:md).call('') + end + end + + protected + + def remove_from_github + return unless github.valid? + github.remove(github_path, github_remove_commit_message) + end + + def github + @github ||= Github.with_website(website) + end + + def github_commit_message + "[#{about.class.name.demodulize}] Save #{about.to_s}" + end + + def github_remove_commit_message + "[#{about.class.name.demodulize}] Remove #{about.to_s}" + end +end diff --git a/app/models/communication/website/home.rb b/app/models/communication/website/home.rb index f42c936499bee8f8116b07768fbf8d7f10298109..835e6f3ccebd62506ccf907853dd415322d153c9 100644 --- a/app/models/communication/website/home.rb +++ b/app/models/communication/website/home.rb @@ -21,8 +21,7 @@ # class Communication::Website::Home < ApplicationRecord include Communication::Website::WithMedia - include WithGithub - include WithJekyll + include WithGithubFiles belongs_to :university belongs_to :website, foreign_key: :communication_website_id @@ -34,14 +33,15 @@ class Communication::Website::Home < ApplicationRecord '' end - def to_jekyll + def to_jekyll(github_file) ApplicationController.render( template: "admin/communication/website/home/jekyll", layout: false, - assigns: { home: self } + assigns: { home: self, github_file: github_file } ) end + # Override from WithGithubFiles def github_path_generated '_pages/index.html' end diff --git a/app/models/communication/website/menu.rb b/app/models/communication/website/menu.rb index 9eadd17157558bb6529af0e1409f9097fed35869..5b39c46cad824c2a1a0cb51e809306042d50c973 100644 --- a/app/models/communication/website/menu.rb +++ b/app/models/communication/website/menu.rb @@ -22,8 +22,7 @@ # fk_rails_... (university_id => universities.id) # class Communication::Website::Menu < ApplicationRecord - include WithGithub - # no WithJekyll include as this model has a custom jekyll + include WithGithubFiles belongs_to :university belongs_to :website, foreign_key: :communication_website_id @@ -38,11 +37,12 @@ class Communication::Website::Menu < ApplicationRecord "#{title}" end + # Override from WithGithubFiles def github_path_generated "_data/menus/#{identifier}.yml" end - def to_jekyll + def to_jekyll(github_file) items.root.ordered.map(&:to_jekyll_hash).to_yaml end end diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb index 0b78330c9d8dfb9ffc601d06c70a2652ea068685..726b1ad1cdc683dad34bab112fe7b730ea53c4f4 100644 --- a/app/models/communication/website/page.rb +++ b/app/models/communication/website/page.rb @@ -38,8 +38,7 @@ class Communication::Website::Page < ApplicationRecord include Communication::Website::WithMedia - include WithGithub - include WithJekyll + include WithGithubFiles include WithSlug include WithTree @@ -75,6 +74,7 @@ class Communication::Website::Page < ApplicationRecord scope :ordered, -> { order(:position) } scope :recent, -> { order(updated_at: :desc).limit(5) } + # Override from WithGithubFiles def github_path_generated "_pages/#{path}/index.html".gsub('///', '/').gsub('//', '/') end diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb index 72053a06e6b633f704d6cedad808b38d33fe8c7c..e47443cfeb2f6fd029f4ada61c380a44a6e5c4d8 100644 --- a/app/models/communication/website/post.rb +++ b/app/models/communication/website/post.rb @@ -31,8 +31,7 @@ # class Communication::Website::Post < ApplicationRecord include Communication::Website::WithMedia - include WithGithub - include WithJekyll + include WithGithubFiles include WithSlug has_rich_text :text @@ -59,6 +58,7 @@ class Communication::Website::Post < ApplicationRecord scope :ordered, -> { order(published_at: :desc, created_at: :desc) } scope :recent, -> { order(published_at: :desc).limit(5) } + # Override from WithGithubFiles def github_path_generated "_posts/#{published_at.year}/#{published_at.strftime "%Y-%m-%d"}-#{slug}.html" end diff --git a/app/models/concerns/with_github.rb b/app/models/concerns/with_github.rb deleted file mode 100644 index ac068db7eed9fa3db0a19f70fffdff0da156baae..0000000000000000000000000000000000000000 --- a/app/models/concerns/with_github.rb +++ /dev/null @@ -1,56 +0,0 @@ -module WithGithub - extend ActiveSupport::Concern - - included do - after_save_commit :publish_to_github - after_touch :publish_to_github - after_destroy :remove_from_github - end - - def force_publish! - publish_to_github - end - - def github_frontmatter - @github_frontmatter ||= begin - github_content = github.read_file_at(github_path) - FrontMatterParser::Parser.new(:md).call(github_content) - rescue - FrontMatterParser::Parser.new(:md).call('') - end - end - - def github_path_generated - raise NotImplementedError - end - - protected - - def github - @github ||= Github.with_website(website) - end - - def github_commit_message - "[#{self.class.name.demodulize}] Save #{to_s}" - end - - def github_remove_commit_message - "[#{self.class.name.demodulize}] Remove #{to_s}" - end - - def publish_to_github - return unless github.valid? - if github.publish(path: github_path_generated, - previous_path: github_path, - commit: github_commit_message, - data: to_jekyll) - update_column :github_path, github_path_generated - end - end - handle_asynchronously :publish_to_github, queue: 'default' - - def remove_from_github - return unless github.valid? - github.remove(github_path, github_remove_commit_message) - end -end diff --git a/app/models/concerns/with_github_files.rb b/app/models/concerns/with_github_files.rb new file mode 100644 index 0000000000000000000000000000000000000000..ff8335f7ed8131b88196e090bf43c9e46a9d52d0 --- /dev/null +++ b/app/models/concerns/with_github_files.rb @@ -0,0 +1,36 @@ +module WithGithubFiles + extend ActiveSupport::Concern + + included do + has_many :github_files, class_name: "Communication::Website::GithubFile", as: :about, dependent: :destroy + + after_save_commit :publish_github_files + after_touch :publish_github_files + end + + def force_publish! + publish_github_files + end + + def github_path_generated + "_#{self.class.name.demodulize.pluralize.underscore}/#{self.id}.md" + end + + def to_jekyll(github_file) + ApplicationController.render( + template: "admin/#{self.class.name.underscore.pluralize}/jekyll", + layout: false, + assigns: { self.class.name.demodulize.underscore => self, github_file: github_file } + ) + end + + protected + + def publish_github_files + list_of_websites = respond_to?(:websites) ? websites : [website] + list_of_websites.each do |website| + github_file = github_files.where(website: website).first_or_create + github_file.publish + end + end +end diff --git a/app/models/concerns/with_jekyll.rb b/app/models/concerns/with_jekyll.rb deleted file mode 100644 index 722f28cfc3a173fef51e1a78756814d292c6dd10..0000000000000000000000000000000000000000 --- a/app/models/concerns/with_jekyll.rb +++ /dev/null @@ -1,14 +0,0 @@ -module WithJekyll - extend ActiveSupport::Concern - - included do - def to_jekyll - ApplicationController.render( - template: "admin/#{self.class.name.underscore.pluralize}/jekyll", - layout: false, - assigns: { self.class.name.demodulize.underscore => self } - ) - end - end - -end diff --git a/app/models/concerns/with_publication_to_websites.rb b/app/models/concerns/with_publication_to_websites.rb deleted file mode 100644 index 337e6bb0d638e3f926a19c0c3265779d9e901193..0000000000000000000000000000000000000000 --- a/app/models/concerns/with_publication_to_websites.rb +++ /dev/null @@ -1,22 +0,0 @@ -module WithPublicationToWebsites - extend ActiveSupport::Concern - - included do - after_save_commit :publish_to_every_website - after_destroy :remove_from_every_website - end - - protected - - def publish_to_every_website - websites.each { |website| website.publish_object(self) } - end - - def remove_from_every_website - websites.each { |website| website.remove_object(self) } - end - - # You can define a `github_path` method to re-define where to save the object markdown. - # Check Communication::Website#publish_object for the default value. - -end diff --git a/app/models/education/program.rb b/app/models/education/program.rb index 9aeed4c772d73f434c804c971e00a6e78d9a312b..bd0029f95fb7abb2a83b4f9d18cb203971abd6c7 100644 --- a/app/models/education/program.rb +++ b/app/models/education/program.rb @@ -25,8 +25,7 @@ # fk_rails_... (university_id => universities.id) # class Education::Program < ApplicationRecord - include WithJekyll - include WithPublicationToWebsites + include WithGithubFiles include WithTree attr_accessor :skip_websites_categories_callback diff --git a/app/models/education/school.rb b/app/models/education/school.rb index b0851b3a039a0299b5ca9ae70872d5876a412aae..383079a78c299760bfd9b5da66a110066d8cf4e8 100644 --- a/app/models/education/school.rb +++ b/app/models/education/school.rb @@ -24,7 +24,7 @@ # fk_rails_... (university_id => universities.id) # class Education::School < ApplicationRecord - include WithPublicationToWebsites + include WithGithubFiles belongs_to :university has_many :websites, class_name: 'Communication::Website', as: :about @@ -43,11 +43,12 @@ class Education::School < ApplicationRecord "#{name}" end - def github_path + def github_path_generated + # Override from WithGithubFiles "_data/school.yml" end - def to_jekyll + def to_jekyll(github_file) { name: name, address: address, diff --git a/app/models/education/teacher.rb b/app/models/education/teacher.rb index 58510a60d65f128cc2d5e7e9116036357e4e1736..90519d164795a786188aee24aa3a296890939719 100644 --- a/app/models/education/teacher.rb +++ b/app/models/education/teacher.rb @@ -22,8 +22,7 @@ # fk_rails_... (user_id => users.id) # class Education::Teacher < ApplicationRecord - include WithJekyll - include WithPublicationToWebsites + include WithGithubFiles include WithSlug has_rich_text :biography diff --git a/app/models/research/journal.rb b/app/models/research/journal.rb index 8266d38f06535f1047f77061174d8c5996ed7071..a8a986936ea21426518ee3051c49b19b38a5a776 100644 --- a/app/models/research/journal.rb +++ b/app/models/research/journal.rb @@ -36,7 +36,7 @@ class Research::Journal < ApplicationRecord "_data/journal.yml" end - def to_jekyll + def to_jekyll(github_file) { title: title, description: description, diff --git a/app/models/research/journal/article.rb b/app/models/research/journal/article.rb index 94eb530bc5a3312f1319183b8794a418102442a5..1dd1124fb98ef0265679ccbfe71ad72bd00ca095 100644 --- a/app/models/research/journal/article.rb +++ b/app/models/research/journal/article.rb @@ -31,8 +31,7 @@ # fk_rails_... (updated_by_id => users.id) # class Research::Journal::Article < ApplicationRecord - include WithJekyll - include WithPublicationToWebsites + include WithGithubFiles has_rich_text :text has_one_attached :pdf diff --git a/app/models/research/journal/volume.rb b/app/models/research/journal/volume.rb index 03f059d2be83f20c7ad6612a8bf37a1ef2418dbf..276b08dfb6a0e1ae312532c89439a43b8699708e 100644 --- a/app/models/research/journal/volume.rb +++ b/app/models/research/journal/volume.rb @@ -24,8 +24,7 @@ # fk_rails_... (university_id => universities.id) # class Research::Journal::Volume < ApplicationRecord - include WithJekyll - include WithPublicationToWebsites + include WithGithubFiles has_one_attached_deletable :cover diff --git a/app/models/research/researcher.rb b/app/models/research/researcher.rb index fb22dd765dce3d2873bd54b17e7ad8f14eb0612e..49b6ca04b3abca0ee4118e868bf90871ee34c40f 100644 --- a/app/models/research/researcher.rb +++ b/app/models/research/researcher.rb @@ -21,8 +21,7 @@ # fk_rails_... (user_id => users.id) # class Research::Researcher < ApplicationRecord - include WithJekyll - include WithPublicationToWebsites + include WithGithubFiles has_rich_text :biography diff --git a/app/views/admin/communication/website/authors/jekyll.html.erb b/app/views/admin/communication/website/authors/jekyll.html.erb index 8aa58250eeda0702d4f386b63321b42378225bd3..7c6661057d42d54adc46a4ce36733aa680eeffaa 100644 --- a/app/views/admin/communication/website/authors/jekyll.html.erb +++ b/app/views/admin/communication/website/authors/jekyll.html.erb @@ -7,4 +7,4 @@ slug: "<%= @author.slug %>" biography: > <%= prepare_for_github @author.biography, @author.university %> --- -<%= @author.github_frontmatter.content.html_safe %> +<%= @github_file.github_frontmatter.content.html_safe %> diff --git a/app/views/admin/communication/website/categories/jekyll.html.erb b/app/views/admin/communication/website/categories/jekyll.html.erb index e1b62c6598fde2751e2b8f4a64f2cb33402c50dd..06f244bdba47a2ba4b4190ca651476f5b1bc5eb2 100644 --- a/app/views/admin/communication/website/categories/jekyll.html.erb +++ b/app/views/admin/communication/website/categories/jekyll.html.erb @@ -6,4 +6,4 @@ parent: "<%= @category.parent_id %>" description: > <%= prepare_for_github @category.description, @category.university %> --- -<%= @category.github_frontmatter.content.html_safe %> +<%= @github_file.github_frontmatter.content.html_safe %> diff --git a/app/views/admin/communication/website/home/jekyll.html.erb b/app/views/admin/communication/website/home/jekyll.html.erb index 9807ba4cc715728b30b8af074f4dec890ba7dd03..363a532fae49bae3a4489fb514a413813ece06d6 100644 --- a/app/views/admin/communication/website/home/jekyll.html.erb +++ b/app/views/admin/communication/website/home/jekyll.html.erb @@ -8,4 +8,4 @@ image: "<%= @home.featured_image.blob.id %>" description: > <%= prepare_for_github @home.text, @home.university %> --- -<%= @home.github_frontmatter.content.html_safe %> +<%= @github_file.github_frontmatter.content.html_safe %> diff --git a/app/views/admin/communication/website/pages/jekyll.html.erb b/app/views/admin/communication/website/pages/jekyll.html.erb index e835e147df36c2c1bd47a4e219624d26f108c40f..6f481d209129655c1ceb6de3801340f29a023dac 100644 --- a/app/views/admin/communication/website/pages/jekyll.html.erb +++ b/app/views/admin/communication/website/pages/jekyll.html.erb @@ -12,4 +12,4 @@ description: > text: > <%= prepare_for_github @page.text, @page.university %> --- -<%= @page.github_frontmatter.content.html_safe %> +<%= @github_file.github_frontmatter.content.html_safe %> diff --git a/app/views/admin/communication/website/posts/jekyll.html.erb b/app/views/admin/communication/website/posts/jekyll.html.erb index ba48558d16c202922b2b004f5a83b549d5a07b3e..743a558732f6a3c4d9cf19013c1cddeb1024de48 100644 --- a/app/views/admin/communication/website/posts/jekyll.html.erb +++ b/app/views/admin/communication/website/posts/jekyll.html.erb @@ -17,4 +17,4 @@ description: > text: > <%= prepare_for_github @post.text, @post.university %> --- -<%= @post.github_frontmatter.content.html_safe %> +<%= @github_file.github_frontmatter.content.html_safe %> diff --git a/db/migrate/20211206102444_create_communication_website_github_files.rb b/db/migrate/20211206102444_create_communication_website_github_files.rb new file mode 100644 index 0000000000000000000000000000000000000000..1afe7513221cc8a753c33395d8d235978e0b8df3 --- /dev/null +++ b/db/migrate/20211206102444_create_communication_website_github_files.rb @@ -0,0 +1,11 @@ +class CreateCommunicationWebsiteGithubFiles < ActiveRecord::Migration[6.1] + def change + create_table :communication_website_github_files, id: :uuid do |t| + t.string :github_path + t.references :about, null: false, polymorphic: true, type: :uuid + t.references :website, null: false, foreign_key: { to_table: :communication_websites }, type: :uuid + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index d5dd3848f98a04d1bc07a5c37d9b38e1c469da15..0b5bed61e68f479324d773a9a40d0ed87b33ad86 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_11_23_132213) do +ActiveRecord::Schema.define(version: 2021_12_06_102444) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -119,6 +119,17 @@ ActiveRecord::Schema.define(version: 2021_11_23_132213) do t.index ["communication_website_post_id", "communication_website_category_id"], name: "post_category" end + create_table "communication_website_github_files", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| + t.string "github_path" + t.string "about_type", null: false + t.uuid "about_id", null: false + t.uuid "website_id", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["about_type", "about_id"], name: "index_communication_website_github_files_on_about" + t.index ["website_id"], name: "index_communication_website_github_files_on_website_id" + end + create_table "communication_website_homes", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "university_id", null: false t.uuid "communication_website_id", null: false @@ -412,7 +423,7 @@ ActiveRecord::Schema.define(version: 2021_11_23_132213) do t.uuid "research_journal_id", null: false t.uuid "research_journal_volume_id" t.datetime "created_at", precision: 6, null: false - t.date "updated_at", null: false + t.datetime "updated_at", precision: 6, null: false t.uuid "updated_by_id" t.text "abstract" t.text "references" @@ -535,6 +546,7 @@ ActiveRecord::Schema.define(version: 2021_11_23_132213) do add_foreign_key "communication_website_categories", "communication_websites" add_foreign_key "communication_website_categories", "education_programs", column: "program_id" add_foreign_key "communication_website_categories", "universities" + add_foreign_key "communication_website_github_files", "communication_websites", column: "website_id" add_foreign_key "communication_website_homes", "communication_websites" add_foreign_key "communication_website_homes", "universities" add_foreign_key "communication_website_imported_authors", "communication_website_authors", column: "author_id" diff --git a/test/fixtures/communication/website/github_files.yml b/test/fixtures/communication/website/github_files.yml new file mode 100644 index 0000000000000000000000000000000000000000..1ee87a4e4b5e7b1a0b7aa77a5ef2072a724383a3 --- /dev/null +++ b/test/fixtures/communication/website/github_files.yml @@ -0,0 +1,30 @@ +# == Schema Information +# +# Table name: communication_website_github_files +# +# id :uuid not null, primary key +# about_type :string not null +# github_path :string +# created_at :datetime not null +# updated_at :datetime not null +# about_id :uuid not null +# website_id :uuid not null +# +# Indexes +# +# index_communication_website_github_files_on_about (about_type,about_id) +# index_communication_website_github_files_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (website_id => communication_websites.id) +# +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + github_path: MyString + about: one + +two: + github_path: MyString + about: two diff --git a/test/models/communication/website/github_file_test.rb b/test/models/communication/website/github_file_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..7e80aa4a4f43adcc1c10d4b6289481b352a00f0f --- /dev/null +++ b/test/models/communication/website/github_file_test.rb @@ -0,0 +1,28 @@ +# == Schema Information +# +# Table name: communication_website_github_files +# +# id :uuid not null, primary key +# about_type :string not null +# github_path :string +# created_at :datetime not null +# updated_at :datetime not null +# about_id :uuid not null +# website_id :uuid not null +# +# Indexes +# +# index_communication_website_github_files_on_about (about_type,about_id) +# index_communication_website_github_files_on_website_id (website_id) +# +# Foreign Keys +# +# fk_rails_... (website_id => communication_websites.id) +# +require "test_helper" + +class Communication::Website::GithubFileTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end