Skip to content

Commit

Permalink
Add multi language image descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
tvdeyen committed Apr 11, 2024
1 parent 3ceaff0 commit e6339fd
Show file tree
Hide file tree
Showing 26 changed files with 247 additions and 26 deletions.
3 changes: 2 additions & 1 deletion app/assets/javascripts/alchemy/alchemy.image_overlay.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class window.Alchemy.ImageOverlay extends Alchemy.Dialog
@$previous = $('.previous-picture')
@$next = $('.next-picture')
@$document.keydown (e) =>
return true if e.target.nodeName == 'INPUT'
if e.target.nodeName == 'INPUT' || e.target.nodeName == 'TEXTAREA'
return true
switch e.which
when 37
@previous()
Expand Down
6 changes: 6 additions & 0 deletions app/assets/stylesheets/alchemy/forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ form {
@include form-label;
}

.inline-label {
display: inline-flex;
align-items: center;
gap: var(--spacing-1);
}

.input {
padding: $default-padding 0;
@include clearfix;
Expand Down
19 changes: 19 additions & 0 deletions app/controllers/alchemy/admin/picture_descriptions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module Alchemy
module Admin
class PictureDescriptionsController < Alchemy::Admin::ResourcesController
def index
load_resource

Check warning on line 5 in app/controllers/alchemy/admin/picture_descriptions_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/alchemy/admin/picture_descriptions_controller.rb#L5

Added line #L5 was not covered by tests
end

def edit
@picture_description = @picture.descriptions.find_or_initialize_by(language_id: params[:language_id])

Check warning on line 9 in app/controllers/alchemy/admin/picture_descriptions_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/alchemy/admin/picture_descriptions_controller.rb#L9

Added line #L9 was not covered by tests
end

private

def load_resource
@picture = Alchemy::Picture.find(params[:picture_id])

Check warning on line 15 in app/controllers/alchemy/admin/picture_descriptions_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/alchemy/admin/picture_descriptions_controller.rb#L15

Added line #L15 was not covered by tests
end
end
end
end
19 changes: 18 additions & 1 deletion app/controllers/alchemy/admin/pictures_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Admin
class PicturesController < Alchemy::Admin::ResourcesController
include UploaderResponses
include ArchiveOverlay
include CurrentLanguage

helper "alchemy/admin/tags"

Expand Down Expand Up @@ -33,6 +34,9 @@ def show
@previous = filtered_pictures.where("name < ?", @picture.name).last
@next = filtered_pictures.where("name > ?", @picture.name).first
@assignments = @picture.picture_ingredients.joins(element: :page)
@picture_description = @picture.descriptions.find_or_initialize_by(
language_id: Alchemy::Current.language.id
)

render action: "show"
end
Expand Down Expand Up @@ -193,7 +197,20 @@ def search_filter_params
end

def picture_params
params.require(:picture).permit(:image_file, :upload_hash, :name, :description, :tag_list)
params.require(:picture).permit(
:image_file,
:upload_hash,
:name,
{
descriptions_attributes: [
:id,
:text,
:language_id,
:picture_id
]
},
:tag_list
)
end

def picture_url_params
Expand Down
4 changes: 3 additions & 1 deletion app/models/alchemy/ingredients/picture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ class Picture < Alchemy::Ingredient
]

def alt_text
alt_tag.presence || picture&.description || picture&.name&.humanize
alt_tag.presence ||
picture&.description_for(Alchemy::Current.language) ||
picture&.name&.humanize
end

# The first 30 characters of the pictures name
Expand Down
8 changes: 8 additions & 0 deletions app/models/alchemy/picture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ class Picture < BaseRecord
has_many :elements, through: :picture_ingredients
has_many :pages, through: :elements
has_many :thumbs, class_name: "Alchemy::PictureThumb", dependent: :destroy
has_many :descriptions, class_name: "Alchemy::PictureDescription", dependent: :destroy

accepts_nested_attributes_for :descriptions, allow_destroy: true, reject_if: ->(attr) { attr[:text].blank? }

# Raise error, if picture is in use (aka. assigned to an Picture ingredient)
#
Expand Down Expand Up @@ -231,6 +234,11 @@ def to_jq_upload
}
end

# Returns the picture description for a given language.
def description_for(language)
descriptions.find_by(language: language)&.text
end

# Returns an uri escaped name.
#
def urlname
Expand Down
8 changes: 8 additions & 0 deletions app/models/alchemy/picture_description.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Alchemy
class PictureDescription < ActiveRecord::Base
belongs_to :picture, class_name: "Alchemy::Picture"
belongs_to :language, class_name: "Alchemy::Language"

validates_uniqueness_of :picture_id, scope: :language_id
end
end
11 changes: 11 additions & 0 deletions app/views/alchemy/admin/picture_descriptions/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<% field_name_prefix = "picture[descriptions_attributes][#{picture_description_counter}]" %>
<% if picture_description.persisted? %>
<%= hidden_field field_name_prefix, :id, value: picture_description.id %>
<% else %>
<%= hidden_field field_name_prefix, :language_id, value: picture_description.language_id %>
<%= hidden_field field_name_prefix, :picture_id, value: picture_description.picture_id %>
<% end %>
<%= label field_name_prefix, :text, Alchemy::PictureDescription.human_attribute_name(:text), class: "control-label" %>
<%= text_area field_name_prefix, :text, value: picture_description.text, rows: 3 %>
6 changes: 6 additions & 0 deletions app/views/alchemy/admin/picture_descriptions/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<turbo-frame id="picture_descriptions">
<%= render "form", {
picture_description: @picture_description,
picture_description_counter: @picture.descriptions.index(@picture_description)
} %>
</turbo-frame>
Original file line number Diff line number Diff line change
@@ -1 +1,28 @@
<%= f.input :description %>
<div class="input">
<label class="inline-label" style="float: right">
<%= Alchemy::Language.model_name.human %>
<%= select_tag :language_id, options_from_collection_for_select(
Alchemy::Language.published, :id, ->(l) { l.code.upcase },
selected: @picture_description.language_id,
), data: {
url: alchemy.edit_admin_picture_description_url(id: "__ID__", picture_id: @picture)
}, disabled: Alchemy::Language.count < 2 %>
</label>

<turbo-frame id="picture_descriptions">
<%= render "alchemy/admin/picture_descriptions/form",
picture_description_counter: @picture.descriptions.index(@picture_description),
picture_description: @picture_description %>
</turbo-frame>
</div>

<script type="module">
const select = document.querySelector("#language_id")

select.addEventListener("change", () => {
const url = new URL(select.dataset.url)
url.searchParams.set("language_id", select.value)
console.log("url", url)
Turbo.visit(url, { frame: "picture_descriptions" })
})
</script>
5 changes: 5 additions & 0 deletions config/locales/alchemy.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,9 @@ en:
alchemy/picture:
one: Picture
other: Pictures
alchemy/picture_description:
one: Picture Description
other: Picture Descriptions
alchemy/user:
one: User
other: User
Expand Down Expand Up @@ -902,6 +905,8 @@ en:
image_file_size: "Filesize"
name: "Name"
tag_list: Tags
alchemy/picture_description:
text: "Description"
alchemy/site:
name: "Name"
host: "Primary Host"
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
end
end

resources :picture_descriptions, only: [:index, :edit]

resources :attachments, except: [:new] do
member do
get :download
Expand Down
5 changes: 0 additions & 5 deletions db/migrate/20240208101342_add_description_to_picture.rb

This file was deleted.

11 changes: 11 additions & 0 deletions db/migrate/20240314105244_create_alchemy_picture_descriptions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateAlchemyPictureDescriptions < ActiveRecord::Migration[7.0]
def change
create_table :alchemy_picture_descriptions do |t|
t.belongs_to :picture, null: false, foreign_key: {to_table: :alchemy_pictures}
t.belongs_to :language, null: false, foreign_key: {to_table: :alchemy_languages}
t.text :text

t.timestamps
end
end
end
1 change: 1 addition & 0 deletions lib/alchemy/permissions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ def alchemy_editor_rules
end

can :manage, Alchemy::Picture
can :manage, Alchemy::PictureDescription
can :manage, Alchemy::Attachment
can :manage, Alchemy::Tag
can :index, Alchemy::Language
Expand Down
17 changes: 15 additions & 2 deletions spec/controllers/alchemy/admin/pictures_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ module Alchemy
authorize_user(:as_admin)
end

let!(:language) { create(:alchemy_language) }

describe "#index" do
context "with search params" do
let!(:picture_1) { create(:alchemy_picture, name: "cute kitten") }
Expand Down Expand Up @@ -250,12 +252,23 @@ module Alchemy
let(:picture) { create(:alchemy_picture) }

subject do
put :update, params: {id: 1, picture: {name: "", description: "foo bar"}}, xhr: true
put :update, params: {
id: 1,
picture: {
name: "",
descriptions_attributes: {
0 => {
text: "foo bar",
language_id: language.id
}
}
}
}, xhr: true
end

it "sets the description" do
subject
expect(picture.description).to eq("foo bar")
expect(picture.description_for(language)).to eq("foo bar")
end
end
end
Expand Down
5 changes: 5 additions & 0 deletions spec/dummy/config/locales/alchemy.de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@ de:
richtext: Dieser Inhaltstyp stellt formatierbaren Text dar
select: Dieser Inhaltstyp stellt Werte dar aus denen der Redakteur wählen kann
text: Dieser Inhaltstyp stellt eine einfache Zeile Text dar

activerecord:
attributes:
alchemy/picture_description:
text: "Bildbeschreibung"

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This migration comes from alchemy (originally 20240314105244)
class CreateAlchemyPictureDescriptions < ActiveRecord::Migration[7.0]
def change
create_table :alchemy_picture_descriptions do |t|
t.belongs_to :picture, null: false, foreign_key: {to_table: :alchemy_pictures}
t.belongs_to :language, null: false, foreign_key: {to_table: :alchemy_languages}
t.text :text

t.timestamps
end
end
end
17 changes: 14 additions & 3 deletions spec/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_02_08_101342) do
ActiveRecord::Schema[7.1].define(version: 2024_04_11_155901) do
create_table "alchemy_attachments", force: :cascade do |t|
t.string "name"
t.string "file_name"
Expand Down Expand Up @@ -136,7 +136,7 @@

create_table "alchemy_page_mutexes", force: :cascade do |t|
t.integer "page_id", null: false
t.datetime "created_at"
t.datetime "created_at", precision: nil
t.index ["page_id"], name: "index_alchemy_page_mutexes_on_page_id", unique: true
end

Expand Down Expand Up @@ -186,6 +186,16 @@
t.index ["urlname"], name: "index_pages_on_urlname"
end

create_table "alchemy_picture_descriptions", force: :cascade do |t|
t.integer "picture_id", null: false
t.integer "language_id", null: false
t.text "text"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["language_id"], name: "index_alchemy_picture_descriptions_on_language_id"
t.index ["picture_id"], name: "index_alchemy_picture_descriptions_on_picture_id"
end

create_table "alchemy_picture_thumbs", force: :cascade do |t|
t.integer "picture_id", null: false
t.string "signature", null: false
Expand All @@ -207,7 +217,6 @@
t.string "image_file_uid"
t.integer "image_file_size"
t.string "image_file_format"
t.text "description"
t.index ["creator_id"], name: "index_alchemy_pictures_on_creator_id"
t.index ["image_file_name"], name: "index_alchemy_pictures_on_image_file_name"
t.index ["name"], name: "index_alchemy_pictures_on_name"
Expand Down Expand Up @@ -293,5 +302,7 @@
add_foreign_key "alchemy_page_mutexes", "alchemy_pages", column: "page_id"
add_foreign_key "alchemy_page_versions", "alchemy_pages", column: "page_id", on_delete: :cascade
add_foreign_key "alchemy_pages", "alchemy_languages", column: "language_id"
add_foreign_key "alchemy_picture_descriptions", "alchemy_languages", column: "language_id"
add_foreign_key "alchemy_picture_descriptions", "alchemy_pictures", column: "picture_id"
add_foreign_key "alchemy_picture_thumbs", "alchemy_pictures", column: "picture_id"
end
1 change: 1 addition & 0 deletions spec/features/admin/picture_library_integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
RSpec.describe "Picture Library", type: :system do
before do
authorize_user(:as_admin)
create(:alchemy_language)
end

describe "Tagging" do
Expand Down
25 changes: 18 additions & 7 deletions spec/models/alchemy/ingredients/picture_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,19 @@
end

context "with a picture description" do
before { picture.description = "Another cute kitten" }

it { is_expected.to eq("Another cute kitten") }
it "returns picture description" do
expect(picture).to receive(:description_for) {
"Another cute kitten"
}
is_expected.to eq("Another cute kitten")
end

context "with a alt_tag" do
before { picture_ingredient.alt_tag = "A cute kitten" }

it { is_expected.to eq("A cute kitten") }
it "returns alt text" do
is_expected.to eq("A cute kitten")
end
end
end

Expand All @@ -50,10 +55,16 @@

it { is_expected.to eq("Cute kitten") }

context "with a picture description" do
before { picture.description = "Another cute kitten" }
context "with a picture description for current language" do
before do
expect(picture).to receive(:description_for) {
"Another cute kitten"
}
end

it { is_expected.to eq("Another cute kitten") }
it "returns the picture description" do
is_expected.to eq("Another cute kitten")
end
end
end
end
Expand Down
Loading

0 comments on commit e6339fd

Please sign in to comment.