From c06723ee715512c2033c7786c48f15674585b56b Mon Sep 17 00:00:00 2001 From: erdgeist Date: Fri, 26 Jun 2026 01:59:57 +0200 Subject: Stage 4: Rails 5.2 -> 6.1 on Ruby 2.7.2 - routing-filter 0.6.3 -> 0.7.0 (Rails 6.1 compatibility) - RSS named routes rss_xml/rss_rdf added - RouteWithParams workarounds: will_paginate_patch, content_path shim, safe_path helper - Paperclip removed, replaced with FileAttachment concern (preserves URL scheme) - Assets resource moved to /admin/assets (Sprockets middleware conflict) - ApplicationRecord base class added, all models migrated - Strong parameters added to Assets, Occurrences, Events, MenuItems controllers - update_attributes -> update throughout - render :nothing -> head :ok/:not_found throughout - language_selector rewritten (removes :overwrite_params) - Environment files updated for Rails 6.1 (eager_load, public_file_server, ActionMailer) - Arel::Visitors::DepthFirst and Integer/Float duration patches removed from test_helper - AssetsController tests added (10 tests covering upload, variants, destroy, auth) - ImageMagick geometry: 460x250! for headline crop (not # which is invalid in IM6) 129 runs, 311 assertions, 5 failures (all pre-existing), 0 errors --- app/models/concerns/file_attachment.rb | 124 +++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 app/models/concerns/file_attachment.rb (limited to 'app/models/concerns') diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb new file mode 100644 index 00000000..b3ff0f14 --- /dev/null +++ b/app/models/concerns/file_attachment.rb @@ -0,0 +1,124 @@ +# FileAttachment — minimal drop-in replacement for Paperclip's has_attached_file. +# +# Provides the same interface used throughout this codebase: +# asset.upload.url -> "/system/uploads/:id/original/:filename" +# asset.upload.url(:thumb) -> "/system/uploads/:id/thumb/:filename" +# asset.upload.content_type -> string +# asset.upload.size -> integer (bytes) +# +# Files are stored at: +# Rails.root/public/system/uploads/:id/:style/:filename +# +# Image variants are generated via ImageMagick (convert) on upload. +# Non-image files get only an original, no variants. +# +# To replace an asset: assign a new file to asset.upload= and save. +# The filename is fixed on first upload and preserved on replacement, +# keeping all public URLs stable. +# +# Future: if more sophisticated asset management is needed (versioning, +# S3, on-demand resizing), replace this module and keep the interface. + +module FileAttachment + extend ActiveSupport::Concern + + STYLES = { + medium: { geometry: "300x300>", format: nil }, + thumb: { geometry: "100x100>", format: nil }, + headline: { geometry: "460x250!", format: nil } + }.freeze + + IMAGE_CONTENT_TYPES = %w[image/jpeg image/gif image/png image/webp].freeze + + included do + attr_reader :upload + + after_initialize :build_upload_proxy + after_save :process_upload + before_destroy :delete_upload_files + end + + def upload=(uploaded_file) + return if uploaded_file.blank? + @pending_upload = uploaded_file + # Populate the database columns immediately so validations can use them + self.upload_file_name = sanitize_filename(uploaded_file.original_filename) + self.upload_content_type = uploaded_file.content_type.to_s.split(';').first.strip + self.upload_file_size = uploaded_file.size + self.upload_updated_at = Time.current + build_upload_proxy + end + + private + + def build_upload_proxy + @upload = UploadProxy.new(self) + end + + def process_upload + return unless @pending_upload + uploaded_file = @pending_upload + @pending_upload = nil + + original_path = file_path(:original) + FileUtils.mkdir_p(File.dirname(original_path)) + FileUtils.cp(uploaded_file.tempfile.path, original_path) + + if IMAGE_CONTENT_TYPES.include?(upload_content_type) + generate_variants(original_path) + end + end + + def generate_variants(original_path) + STYLES.each do |style, options| + dest_path = file_path(style) + FileUtils.mkdir_p(File.dirname(dest_path)) + system("convert", original_path, "-resize", options[:geometry], dest_path) + end + end + + def delete_upload_files + dir = Rails.root.join("public", "system", "uploads", id.to_s) + FileUtils.rm_rf(dir) if Dir.exist?(dir) + end + + def file_path(style) + Rails.root.join( + "public", "system", "uploads", + id.to_s, style.to_s, upload_file_name + ).to_s + end + + def sanitize_filename(filename) + File.basename(filename).gsub(/[^\w\.\-]/, '_') + end + + # Proxy object returned by asset.upload, providing the Paperclip-compatible + # interface used in views: .url, .url(:style), .content_type, .size + class UploadProxy + def initialize(record) + @record = record + end + + def url(style = :original) + return "" if @record.upload_file_name.blank? + "/system/uploads/#{@record.id}/#{style}/#{@record.upload_file_name}" + end + + def content_type + @record.upload_content_type.to_s + end + + def size + @record.upload_file_size.to_i + end + + def present? + @record.upload_file_name.present? + end + + def blank? + !present? + end + end +end -- cgit v1.3 From 289ec85be338c6c9085497820f53f57ee714b9b7 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Fri, 26 Jun 2026 22:04:42 +0200 Subject: Fix ImageMagick 7: use 'magick' instead of deprecated 'convert' --- app/models/concerns/file_attachment.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/models/concerns') diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb index b3ff0f14..5483de5e 100644 --- a/app/models/concerns/file_attachment.rb +++ b/app/models/concerns/file_attachment.rb @@ -73,7 +73,7 @@ module FileAttachment STYLES.each do |style, options| dest_path = file_path(style) FileUtils.mkdir_p(File.dirname(dest_path)) - system("convert", original_path, "-resize", options[:geometry], dest_path) + system("magick", original_path, "-resize", options[:geometry], dest_path) end end -- cgit v1.3 From b4f850e97aeb12369399d8e1ab354f66d3b88e40 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Sat, 27 Jun 2026 02:39:55 +0200 Subject: Stage 6 click-testing fixes and production setup - file_attachment.rb: delete old upload directory before writing replacement files; fixes orphaned variants when filename or mime type changes - assets/edit.html.erb: add file upload field and current file display; the form was previously empty and non-functional - admin.css: fix button_to hover styling; buttons now show orange hover to signal interactivity - test/controllers/users_controller_test.rb: assert input[type=submit] not anchor tag for destroy action (button_to change) - test/test_helper.rb: add I18n.locale reset in setup block - doc/rc.d_cccms: fix cccms_chdir, add start_precmd for log/pid dirs, PATH export for bash wrapper, user/pid/tcp_nopush unicorn fixes - doc/INSTALL.md: new installation guide covering all non-obvious steps - Remove parked search migration from doc/ (now in db/migrate/) --- app/models/concerns/file_attachment.rb | 3 + app/views/assets/edit.html.erb | 18 +- ...d_search_vector_to_page_translations.rb.pending | 47 --- doc/INSTALL.md | 341 +++++++++++++++++++++ doc/rc.d_cccms | 7 + public/stylesheets/admin.css | 5 +- test/controllers/users_controller_test.rb | 6 +- test/test_helper.rb | 4 + 8 files changed, 376 insertions(+), 55 deletions(-) delete mode 100644 doc/20260626025705_add_search_vector_to_page_translations.rb.pending create mode 100644 doc/INSTALL.md (limited to 'app/models/concerns') diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb index 5483de5e..e9acda6a 100644 --- a/app/models/concerns/file_attachment.rb +++ b/app/models/concerns/file_attachment.rb @@ -60,6 +60,9 @@ module FileAttachment uploaded_file = @pending_upload @pending_upload = nil + old_dir = Rails.root.join("public", "system", "uploads", id.to_s) + FileUtils.rm_rf(old_dir) if Dir.exist?(old_dir) + original_path = file_path(:original) FileUtils.mkdir_p(File.dirname(original_path)) FileUtils.cp(uploaded_file.tempfile.path, original_path) diff --git a/app/views/assets/edit.html.erb b/app/views/assets/edit.html.erb index e65d6004..f1986000 100644 --- a/app/views/assets/edit.html.erb +++ b/app/views/assets/edit.html.erb @@ -1,12 +1,24 @@

Editing asset

-<%= form_for(@asset) do |f| %> +<%= form_for(@asset, html: { multipart: true }) do |f| %> <%= form_error_messages(f) %> + <% if @asset.upload.present? %> +

+ Current file: + <%= @asset.upload.url %> + (<%= number_to_human_size(@asset.upload.size) %>) +

+ <% end %> + +

+
+ <%= f.file_field :upload %> +

+

<%= f.submit 'Update' %>

<% end %> -<%= link_to 'Show', @asset %> | -<%= link_to 'Back', assets_path %> +<%= link_to 'Show', @asset %> | <%= link_to 'Back', assets_path %> diff --git a/doc/20260626025705_add_search_vector_to_page_translations.rb.pending b/doc/20260626025705_add_search_vector_to_page_translations.rb.pending deleted file mode 100644 index 0747637f..00000000 --- a/doc/20260626025705_add_search_vector_to_page_translations.rb.pending +++ /dev/null @@ -1,47 +0,0 @@ -class AddSearchVectorToPageTranslations < ActiveRecord::Migration[7.2] - def up - add_column :page_translations, :search_vector, :tsvector - - execute <<~SQL - UPDATE page_translations - SET search_vector = to_tsvector( - 'simple', - coalesce(title, '') || ' ' || - coalesce(abstract, '') || ' ' || - coalesce(body, '') - ) - SQL - - add_index :page_translations, :search_vector, - using: :gin, - name: 'index_page_translations_on_search_vector' - - execute <<~SQL - CREATE OR REPLACE FUNCTION page_translations_search_vector_update() - RETURNS trigger AS $$ - BEGIN - NEW.search_vector := to_tsvector( - 'simple', - coalesce(NEW.title, '') || ' ' || - coalesce(NEW.abstract, '') || ' ' || - coalesce(NEW.body, '') - ); - RETURN NEW; - END; - $$ LANGUAGE plpgsql; - - CREATE TRIGGER page_translations_search_vector_trigger - BEFORE INSERT OR UPDATE ON page_translations - FOR EACH ROW EXECUTE PROCEDURE page_translations_search_vector_update(); - SQL - end - - def down - execute <<~SQL - DROP TRIGGER IF EXISTS page_translations_search_vector_trigger ON page_translations; - DROP FUNCTION IF EXISTS page_translations_search_vector_update(); - SQL - remove_index :page_translations, name: 'index_page_translations_on_search_vector' - remove_column :page_translations, :search_vector - end -end diff --git a/doc/INSTALL.md b/doc/INSTALL.md new file mode 100644 index 00000000..8056f7cf --- /dev/null +++ b/doc/INSTALL.md @@ -0,0 +1,341 @@ +# CCCMS Installation Guide + +This document covers the non-obvious steps required to install the CCCMS +stack on a fresh FreeBSD jail. It assumes a FreeBSD 14.x base jail with +network access and a working pkg repository. + +## 1. Install packages + +```sh +pkg install gmake pkgconf curl gnupg git autoconf automake libtool bash \ + readline libyaml libffi gdbm libxml2 libxslt libical \ + postgresql16-server postgresql16-client \ + ImageMagick7-nox11 node vim +``` + +Note: the package is `ImageMagick7-nox11`, not `ImageMagick-nox11`. The +nox11 variant avoids pulling in the entire X11 dependency chain. + +## 2. Enable sysvipc for the jail + +PostgreSQL uses System V shared memory for inter-process communication. +On the host, the jail must have sysvipc enabled. In `/etc/jail.conf` or +the jail's ezjail configuration: + + `allow.sysvipc = 1;` + +Restart the jail after making this change. Without it, PostgreSQL will +fail to start with a shared memory error. + +## 3. Enable and initialise PostgreSQL + +```sh +# Enable PostgreSQL in rc.conf +echo 'postgresql_enable="YES"' >> /etc/rc.conf + +# Initialise the database cluster +service postgresql initdb + +# Start PostgreSQL +service postgresql start +``` + +## 4. Create database roles and set permissions + +```sh +psql -U postgres postgres +``` + +```sql +CREATE ROLE rails WITH LOGIN PASSWORD 'your-password-here'; +ALTER ROLE rails CREATEDB; +``` + +`CREATEDB` is required for the Rails test suite to create and drop the +test database between runs. + +## 5. Create databases + +```sql +CREATE DATABASE cccms_production OWNER rails ENCODING 'UTF8' + LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8' TEMPLATE template0; +CREATE DATABASE cccms_dev OWNER rails ENCODING 'UTF8' + LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8' TEMPLATE template0; +CREATE DATABASE psql_test OWNER rails ENCODING 'UTF8' + LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8' TEMPLATE template0; +``` + +`TEMPLATE template0` is required when specifying a non-default locale. + +## 6. Restore the database dump (or start empty) + +If restoring from a pg_dump: + +```sh +pg_restore -U postgres -d cccms_production \ + --no-owner --no-acl /path/to/cccms_production.dump + +pg_restore -U postgres -d cccms_dev \ + --no-owner --no-acl /path/to/cccms_production.dump +``` + +Expected harmless warnings: +- `schema "public" already exists` — benign, ignore +- `array_accum aggregate` failure — dead code, ignore + +Transfer ownership to the rails user (REASSIGN OWNED does not work on +PostgreSQL 15+ due to system object protection): + +```sh +psql -U postgres cccms_production +``` + +```sql +DO $$ +DECLARE + obj RECORD; +BEGIN + FOR obj IN + SELECT tablename FROM pg_tables WHERE schemaname = 'public' + LOOP + EXECUTE 'ALTER TABLE public.' || quote_ident(obj.tablename) || + ' OWNER TO rails'; + END LOOP; + FOR obj IN + SELECT sequence_name FROM information_schema.sequences + WHERE sequence_schema = 'public' + LOOP + EXECUTE 'ALTER SEQUENCE public.' || quote_ident(obj.sequence_name) || + ' OWNER TO rails'; + END LOOP; + FOR obj IN + SELECT viewname FROM pg_views WHERE schemaname = 'public' + LOOP + EXECUTE 'ALTER VIEW public.' || quote_ident(obj.viewname) || + ' OWNER TO rails'; + END LOOP; +END $$; + +ALTER SCHEMA public OWNER TO rails; +``` + +Repeat for `cccms_dev`. + +## 7. Clone the repository + +```sh +cd /usr/local/www +git clone https://github.com/erdgeist/cccms.git +cd cccms +git checkout rails-upgrade +``` + +## 8. Copy assets (optional but recommended) + +The `public/system/uploads/` directory contains all uploaded files +referenced by the database. Without it, images and attachments will be +missing throughout the site. + +```sh +# On the source system: +tar -czf /tmp/cccms_uploads.tar.gz -C /usr/local/www cccms/public/system + +# On the new system: +tar -xzf /path/to/cccms_uploads.tar.gz -C /usr/local/www +``` + +## 9. Copy gitignored config files + +These files are not in the repository and must be copied or created: + +```sh +# Required: +config/database.yml +config/initializers/secret_token.rb + +# If used: +config/initializers/exception_notification.rb +/usr/local/etc/unicorn.rb +``` + +`database.yml` template: + +```yaml +development: + adapter: postgresql + encoding: unicode + database: cccms_dev + pool: 5 + username: rails + password: your-password-here + +test: + adapter: postgresql + encoding: UTF8 + database: psql_test + username: rails + password: + +production: + adapter: postgresql + encoding: unicode + database: cccms_production + pool: 5 + username: rails + password: your-password-here +``` + +## 10. Install rvm + +rvm 1.29.12 is the latest formal release as of mid-2026. Download and +verify before installing: + +```sh +curl -L https://github.com/rvm/rvm/releases/download/1.29.12/1.29.12.tar.gz \ + -o /tmp/rvm-1.29.12.tar.gz +curl -L https://github.com/rvm/rvm/releases/download/1.29.12/1.29.12.tar.gz.asc \ + -o /tmp/rvm-1.29.12.tar.gz.asc + +gpg --keyserver hkps://keys.openpgp.org \ + --recv-keys 7D2BAF1CF37B13E2069D6956105BD0E739499BDB + +gpg --verify /tmp/rvm-1.29.12.tar.gz.asc /tmp/rvm-1.29.12.tar.gz +``` + +If verification passes: + +```sh +tar -xzf /tmp/rvm-1.29.12.tar.gz -C /tmp +bash /tmp/rvm-1.29.12/install --auto-dotfiles +source /usr/local/rvm/scripts/rvm +``` + +The installed rvm ships with a stale known-versions list that only goes +to Ruby 3.0.0. Update it immediately: + +```sh +curl -L https://raw.githubusercontent.com/rvm/rvm/master/config/known \ + -o /usr/local/rvm/config/known +rvm list known | grep '^\[ruby-\]3\.' +``` + +Should now show Ruby 3.2.x and later. + +## 11. Install Ruby and create gemset + +```sh +source /usr/local/rvm/scripts/rvm +rvm install 3.2.11 --autolibs=read-only --with-opt-dir=/usr/local +rvm use 3.2.11 +rvm gemset create rails7-upgrade +rvm use 3.2.11@rails7-upgrade +``` + +The `.ruby-version` and `.ruby-gemset` files in the project root will +cause rvm to switch automatically when entering the project directory. + +## 12. Install bundler and gems + +```sh +gem install bundler +cd /usr/local/www/cccms +export MAKE=gmake +bundle install 2>&1 | tee /tmp/bundle_install.log +``` + +`MAKE=gmake` is required because FreeBSD's native make (BSD make) uses +different `-j` syntax than native gems expect. Without it, several native +gem compilations will fail. + +## 13. Run migrations + +```sh +bundle exec rails db:migrate +``` + +If restoring an existing database, first insert fake migration versions +to prevent re-running migrations that were applied to the old schema: + +```sql +INSERT INTO schema_migrations (version) VALUES + ('20260624035149'), ('20260624035150'), ('20260624035151'), + ('20260624035152'), ('20260624035153'), + ('20260625031409') +ON CONFLICT DO NOTHING; +``` + +Then run `db:migrate` to apply only new migrations. + +To enable full-text search (requires PostgreSQL 10+ with plpgsql): + +```sh +mv doc/20260626025705_add_search_vector_to_page_translations.rb.pending \ + db/migrate/20260626025705_add_search_vector_to_page_translations.rb +bundle exec rails db:migrate +``` + +## 14. Compile admin assets + +```sh +bundle exec rails assets:precompile +``` + +This compiles the admin JavaScript bundle (jQuery, jQuery UI, hotkeys) +into `public/assets/`. Required for the admin interface to work. Must be +re-run after any changes to `app/assets/javascripts/admin_bundle.js`. + +## 15. Run tests (optional but recommended) + +```sh +bundle exec rake test +``` + +Expected result: 129 runs, ~339 assertions, 3 failures, 0 errors. +The 3 failures are pre-existing and documented in the handover document. + +## 16. Start the server + +Development: + +```sh +bundle exec rails server -p 3000 -b 0.0.0.0 -e development +``` + +Note: `-b 0.0.0.0` is required — `localhost` does not resolve inside +a FreeBSD jail. + +Production (unicorn): + +```sh +/usr/local/rvm/gems/ruby-3.2.11@rails7-upgrade/wrappers/unicorn \ + -c /usr/local/etc/unicorn.rb -E production -D +``` + +The rc.d script at `/etc/rc.d/cccms` needs updating from `unicorn_rails` +to `unicorn` before use — see the handover document for details. + +## Known Gotchas + +**sysvipc:** PostgreSQL will fail silently or with a cryptic error if +sysvipc is not enabled for the jail. Enable it on the host before starting +PostgreSQL. + +**MAKE=gmake:** Native gem compilation fails without this. Set it before +every `bundle install` or add to your shell profile. + +**rvm known versions:** rvm 1.29.12 ships with a stale `config/known` that +only lists Ruby up to 3.0.0. Always update from master after installing rvm. + +**ImageMagick 7:** The `convert` command is deprecated; use `magick convert`. +The `file_attachment.rb` concern needs updating before production use. + +**pg_hba.conf:** The default FreeBSD PostgreSQL configuration uses `trust` +for local Unix socket connections, which is sufficient for the application. +No changes needed unless TCP connections are required. + +**assets:precompile:** Must be run after checkout and after any changes to +admin JavaScript. The compiled files in `public/assets/` are gitignored. + +**chaos_calendar include path:** On FreeBSD 14.x with libical 3.0.20+, +the include path is `` not ``. This is already +fixed in the `erdgeist-ruby1.9` branch. diff --git a/doc/rc.d_cccms b/doc/rc.d_cccms index 62e8bde2..8404bc7a 100644 --- a/doc/rc.d_cccms +++ b/doc/rc.d_cccms @@ -25,6 +25,13 @@ required_dirs="${cccms_dir}" extra_commands="reload" sig_reload="USR2" +cccms_prestart() +{ + mkdir -p /usr/local/www/cccms/tmp/pids /var/log + touch /var/log/unicorn.stderr.log + chown www:www /var/log/unicorn.stderr.log +} + export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin export RAILS_ENV=production export HOME=/root diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css index 1a29effc..4b083568 100644 --- a/public/stylesheets/admin.css +++ b/public/stylesheets/admin.css @@ -131,11 +131,12 @@ form.button_to input[type="submit"] { font: inherit; color: inherit; cursor: pointer; - text-decoration: underline; + text-decoration: none } form.button_to input[type="submit"]:hover { - color: inherit; + color: #ffffff; + background-color: #ff9600; } #admin_wizard { diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index 3ace95c3..d37b4288 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -8,13 +8,13 @@ class UsersControllerTest < ActionController::TestCase assert_response :success assert_select "a", { :count => 0, :text => "Destroy" } end - + test "get index as admin user renders admin partial" do login_as :aaron get :index assert_response :success - assert_select "a", "destroy" - assert_select "a", "show", "Show Link is missing" + assert_select "input[type=submit][value=destroy]" + assert_select "a", "show" end test "get new when logged in as admin" do diff --git a/test/test_helper.rb b/test/test_helper.rb index e7b15da4..d438bb5e 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -47,6 +47,10 @@ class ActiveSupport::TestCase # Add more helper methods to be used by all tests here... + setup do + I18n.locale = I18n.default_locale + end + def create_node_with_published_page node = create_node_with_draft draft = node.draft -- cgit v1.3 From 8957808536e53bb9329cb6ae12835fde7835210b Mon Sep 17 00:00:00 2001 From: erdgeist Date: Sat, 27 Jun 2026 21:43:55 +0200 Subject: Stage 7 click-testing fixes (2) - nodes_controller: permit staged_slug and staged_parent_id in node params; these were silently dropped since strong parameters migration, breaking the two-phase slug/parent change workflow - file_attachment: add SVG support; vector files are copied to all style directories without rasterisation, preserving scalability in the browser - assets index/show: constrain image display with max-width/max-height via admin.css td img rule; fixes oversized SVG thumbnails while leaving raster variants unaffected --- app/controllers/nodes_controller.rb | 2 +- app/models/concerns/file_attachment.rb | 14 +++++++++++++- app/views/assets/index.html.erb | 2 +- app/views/assets/show.html.erb | 4 ++-- 4 files changed, 17 insertions(+), 5 deletions(-) (limited to 'app/models/concerns') diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb index bd60b272..494887d5 100644 --- a/app/controllers/nodes_controller.rb +++ b/app/controllers/nodes_controller.rb @@ -107,7 +107,7 @@ class NodesController < ApplicationController private def node_params - params.fetch(:node, {}).permit(:slug, :parent_id) + params.fetch(:node, {}).permit(:slug, :parent_id, :staged_slug, :staged_parent_id) end def page_params diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb index e9acda6a..0e99fa2e 100644 --- a/app/models/concerns/file_attachment.rb +++ b/app/models/concerns/file_attachment.rb @@ -28,7 +28,9 @@ module FileAttachment headline: { geometry: "460x250!", format: nil } }.freeze - IMAGE_CONTENT_TYPES = %w[image/jpeg image/gif image/png image/webp].freeze + IMAGE_CONTENT_TYPES = %w[image/jpeg image/gif image/png image/webp].freeze + VECTOR_CONTENT_TYPES = %w[image/svg+xml].freeze + DISPLAYABLE_AS_IMAGE = IMAGE_CONTENT_TYPES + VECTOR_CONTENT_TYPES included do attr_reader :upload @@ -69,6 +71,8 @@ module FileAttachment if IMAGE_CONTENT_TYPES.include?(upload_content_type) generate_variants(original_path) + elsif VECTOR_CONTENT_TYPES.include?(upload_content_type) + generate_svg_variants(original_path) end end @@ -80,6 +84,14 @@ module FileAttachment end end + def generate_svg_variants(original_path) + STYLES.each do |style, _| + dest_path = file_path(style) + FileUtils.mkdir_p(File.dirname(dest_path)) + FileUtils.cp(original_path, dest_path) + end + end + def delete_upload_files dir = Rails.root.join("public", "system", "uploads", id.to_s) FileUtils.rm_rf(dir) if Dir.exist?(dir) diff --git a/app/views/assets/index.html.erb b/app/views/assets/index.html.erb index 83d55c29..51fc4869 100644 --- a/app/views/assets/index.html.erb +++ b/app/views/assets/index.html.erb @@ -10,7 +10,7 @@ <% @assets.each do |asset| %> - <%= image_tag asset.upload.url(:thumb) %> + <%= image_tag asset.upload.url(:thumb), style: "max-width: 100px; max-height: 100px;" %> <%= link_to asset.name, asset.upload.url %> <%= asset.upload.content_type %> <%= link_to 'Show', asset %> diff --git a/app/views/assets/show.html.erb b/app/views/assets/show.html.erb index a64987cb..694be5a5 100644 --- a/app/views/assets/show.html.erb +++ b/app/views/assets/show.html.erb @@ -6,7 +6,7 @@ - + @@ -20,4 +20,4 @@ -
Thumbnail<%= image_tag @asset.upload.url(:medium) %><%= image_tag @asset.upload.url(:medium), style: "max-width: 300px; max-height: 300px;" %>
Public PathSize <%= "#{@asset.upload.size/1024} KB" %>
\ No newline at end of file + -- cgit v1.3