diff options
Diffstat (limited to 'app')
25 files changed, 266 insertions, 82 deletions
diff --git a/app/controllers/assets_controller.rb b/app/controllers/assets_controller.rb index d150e06..becfe13 100644 --- a/app/controllers/assets_controller.rb +++ b/app/controllers/assets_controller.rb | |||
| @@ -89,6 +89,6 @@ class AssetsController < ApplicationController | |||
| 89 | private | 89 | private |
| 90 | 90 | ||
| 91 | def asset_params | 91 | def asset_params |
| 92 | params.require(:asset).permit(:name, :upload) | 92 | params.require(:asset).permit(:name, :upload, :creator, :source_url, :license_key) |
| 93 | end | 93 | end |
| 94 | end | 94 | end |
diff --git a/app/controllers/related_assets_controller.rb b/app/controllers/related_assets_controller.rb index 5af73fc..da82cde 100644 --- a/app/controllers/related_assets_controller.rb +++ b/app/controllers/related_assets_controller.rb | |||
| @@ -39,7 +39,17 @@ class RelatedAssetsController < ApplicationController | |||
| 39 | end | 39 | end |
| 40 | 40 | ||
| 41 | def update | 41 | def update |
| 42 | @node.editable_page.related_assets.find(params[:id]).insert_at(params[:position].to_i) | 42 | related = @node.editable_page.related_assets.find(params[:id]) |
| 43 | |||
| 44 | if params.key?(:headline) | ||
| 45 | RelatedAsset.transaction do | ||
| 46 | @node.editable_page.related_assets.update_all(headline: false) | ||
| 47 | related.update!(headline: true) if params[:headline] == "true" | ||
| 48 | end | ||
| 49 | else | ||
| 50 | related.insert_at(params[:position].to_i) | ||
| 51 | end | ||
| 52 | |||
| 43 | head :ok | 53 | head :ok |
| 44 | end | 54 | end |
| 45 | 55 | ||
diff --git a/app/helpers/content_helper.rb b/app/helpers/content_helper.rb index 5810966..5b67259 100644 --- a/app/helpers/content_helper.rb +++ b/app/helpers/content_helper.rb | |||
| @@ -53,11 +53,8 @@ module ContentHelper | |||
| 53 | end | 53 | end |
| 54 | 54 | ||
| 55 | def headline_image | 55 | def headline_image |
| 56 | @images = @page.assets.images | 56 | @headline_asset = @page.related_assets.find_by(headline: true)&.asset |
| 57 | 57 | render :partial => 'content/headline_image' if @headline_asset || @page.assets.images.any? | |
| 58 | unless @images.empty? | ||
| 59 | render :partial => 'content/headline_image' | ||
| 60 | end | ||
| 61 | end | 58 | end |
| 62 | 59 | ||
| 63 | # Returns the published_at attribute of a page if it is not nil, otherwise | 60 | # Returns the published_at attribute of a page if it is not nil, otherwise |
| @@ -154,4 +151,26 @@ module ContentHelper | |||
| 154 | ) | 151 | ) |
| 155 | end | 152 | end |
| 156 | 153 | ||
| 154 | def asset_credit(asset) | ||
| 155 | return nil unless asset | ||
| 156 | return nil if asset.creator.blank? && asset.source_url.blank? && asset.license_key.blank? | ||
| 157 | |||
| 158 | license = AssetLicense.find(asset.license_key) | ||
| 159 | |||
| 160 | photo_label = t("asset_credits.photo", name: asset.name) | ||
| 161 | photo = asset.source_url.present? ? link_to(photo_label, asset.source_url) : photo_label | ||
| 162 | |||
| 163 | attribution_parts = [photo] | ||
| 164 | attribution_parts << t("asset_credits.by", creator: asset.creator) if asset.creator.present? | ||
| 165 | attribution = safe_join(attribution_parts, " ") | ||
| 166 | |||
| 167 | license_text = if license | ||
| 168 | name = t("asset_licenses.#{license.key}", default: license.key) | ||
| 169 | phrase = license.style == "license" ? t("asset_credits.licensed_under", license: name) : name | ||
| 170 | license.url.present? ? link_to(phrase, license.url) : phrase | ||
| 171 | end | ||
| 172 | |||
| 173 | full = license_text ? safe_join([attribution, license_text], ", ") : attribution | ||
| 174 | safe_join([full, "."]) | ||
| 175 | end | ||
| 157 | end | 176 | end |
diff --git a/app/models/asset.rb b/app/models/asset.rb index aca0ee8..8bea1b3 100644 --- a/app/models/asset.rb +++ b/app/models/asset.rb | |||
| @@ -1,12 +1,18 @@ | |||
| 1 | class Asset < ApplicationRecord | 1 | class Asset < ApplicationRecord |
| 2 | IMAGE_CONTENT_TYPES = ["image/gif", "image/jpeg", "image/png", "image/webp"] | ||
| 2 | 3 | ||
| 3 | include FileAttachment | 4 | include FileAttachment |
| 4 | 5 | ||
| 5 | has_many :related_assets, :dependent => :destroy | 6 | has_many :related_assets, :dependent => :destroy |
| 6 | has_many :pages, :through => :related_assets | 7 | has_many :pages, :through => :related_assets |
| 7 | 8 | ||
| 8 | scope :images, -> { where(:upload_content_type => ["image/gif", "image/jpeg", "image/png", "image/webp"]) } | 9 | scope :images, -> { where(:upload_content_type => IMAGE_CONTENT_TYPES) } |
| 9 | scope :documents, -> { where(:upload_content_type => ["application/pdf", "text/plain", "text/rtf"]) } | 10 | scope :documents, -> { where(:upload_content_type => ["application/pdf", "text/plain", "text/rtf"]) } |
| 10 | scope :audio, -> { where(:upload_content_type => ["audio/mpeg", "audio/x-m4a", "audio/wav", "audio/x-wav"]) } | 11 | scope :audio, -> { where(:upload_content_type => ["audio/mpeg", "audio/x-m4a", "audio/wav", "audio/x-wav"]) } |
| 11 | 12 | ||
| 13 | validates :license_key, inclusion: { in: -> { AssetLicense.keys } }, allow_blank: true | ||
| 14 | |||
| 15 | def image? | ||
| 16 | IMAGE_CONTENT_TYPES.include?(upload_content_type) | ||
| 17 | end | ||
| 12 | end | 18 | end |
diff --git a/app/models/asset_license.rb b/app/models/asset_license.rb new file mode 100644 index 0000000..ca66d40 --- /dev/null +++ b/app/models/asset_license.rb | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | class AssetLicense | ||
| 2 | Entry = Struct.new(:key, :url, :requires_attribution, :style, keyword_init: true) | ||
| 3 | |||
| 4 | DICTIONARY = YAML.load_file(Rails.root.join("config", "asset_licenses.yml")).freeze | ||
| 5 | |||
| 6 | def self.keys | ||
| 7 | DICTIONARY.keys | ||
| 8 | end | ||
| 9 | |||
| 10 | def self.find(key) | ||
| 11 | entry = DICTIONARY[key.to_s] if key.present? | ||
| 12 | return nil unless entry | ||
| 13 | Entry.new(key: key.to_s, url: entry["url"], requires_attribution: entry["requires_attribution"], style: entry["style"]) | ||
| 14 | end | ||
| 15 | end | ||
diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb index 613a6f0..e7a33c5 100644 --- a/app/models/concerns/file_attachment.rb +++ b/app/models/concerns/file_attachment.rb | |||
| @@ -52,6 +52,14 @@ module FileAttachment | |||
| 52 | build_upload_proxy | 52 | build_upload_proxy |
| 53 | end | 53 | end |
| 54 | 54 | ||
| 55 | def has_variant?(style) | ||
| 56 | upload_file_name.present? && File.exist?(file_path(style)) | ||
| 57 | end | ||
| 58 | |||
| 59 | def previewable? | ||
| 60 | has_variant?(:medium) | ||
| 61 | end | ||
| 62 | |||
| 55 | private | 63 | private |
| 56 | 64 | ||
| 57 | def build_upload_proxy | 65 | def build_upload_proxy |
| @@ -106,7 +114,8 @@ module FileAttachment | |||
| 106 | end | 114 | end |
| 107 | 115 | ||
| 108 | def sanitize_filename(filename) | 116 | def sanitize_filename(filename) |
| 109 | File.basename(filename).gsub(/[^\w\.\-]/, '_') | 117 | name = File.basename(filename).unicode_normalize(:nfc) |
| 118 | name.gsub(/(?u)[^\w\.\-]/, '_') | ||
| 110 | end | 119 | end |
| 111 | 120 | ||
| 112 | # Proxy object returned by asset.upload, providing the Paperclip-compatible | 121 | # Proxy object returned by asset.upload, providing the Paperclip-compatible |
diff --git a/app/models/node_action.rb b/app/models/node_action.rb index 13bd5ba..63a99ae 100644 --- a/app/models/node_action.rb +++ b/app/models/node_action.rb | |||
| @@ -166,4 +166,12 @@ class NodeAction < ApplicationRecord | |||
| 166 | def subject_name | 166 | def subject_name |
| 167 | metadata["human_readable_node_name"] || node&.unique_name || "deleted node" | 167 | metadata["human_readable_node_name"] || node&.unique_name || "deleted node" |
| 168 | end | 168 | end |
| 169 | |||
| 170 | def diff_link_params | ||
| 171 | prev = NodeAction.where(node_id: node_id, action: "publish") | ||
| 172 | .where("id < ?", id) | ||
| 173 | .order(id: :desc).first | ||
| 174 | return nil unless prev&.page && page | ||
| 175 | { start_revision: prev.page.revision, end_revision: page.revision } | ||
| 176 | end | ||
| 169 | end | 177 | end |
diff --git a/app/models/related_asset.rb b/app/models/related_asset.rb index 8f16460..62000cc 100644 --- a/app/models/related_asset.rb +++ b/app/models/related_asset.rb | |||
| @@ -5,4 +5,13 @@ class RelatedAsset < ApplicationRecord | |||
| 5 | acts_as_list :scope => :page_id | 5 | acts_as_list :scope => :page_id |
| 6 | 6 | ||
| 7 | default_scope -> { order("position ASC") } | 7 | default_scope -> { order("position ASC") } |
| 8 | |||
| 9 | validate :headline_only_for_images | ||
| 10 | |||
| 11 | private | ||
| 12 | |||
| 13 | def headline_only_for_images | ||
| 14 | return unless asset | ||
| 15 | errors.add(:headline, "can only be set on image assets") if headline? && !asset.image? | ||
| 16 | end | ||
| 8 | end | 17 | end |
diff --git a/app/views/assets/edit.html.erb b/app/views/assets/edit.html.erb index f198600..3ef8fea 100644 --- a/app/views/assets/edit.html.erb +++ b/app/views/assets/edit.html.erb | |||
| @@ -1,24 +1,44 @@ | |||
| 1 | <h1>Editing asset</h1> | 1 | <div id="page_editor"> |
| 2 | <h1>Editing asset</h1> | ||
| 2 | 3 | ||
| 3 | <%= form_for(@asset, html: { multipart: true }) do |f| %> | 4 | <%= form_for(@asset, html: { multipart: true }) do |f| %> |
| 4 | <%= form_error_messages(f) %> | 5 | <%= form_error_messages(f) %> |
| 5 | 6 | ||
| 6 | <% if @asset.upload.present? %> | 7 | <div id="content"> |
| 7 | <p> | 8 | <div class="node_description"><%= f.label :name %></div> |
| 8 | <strong>Current file:</strong> | 9 | <div class="node_content"><%= f.text_field :name %></div> |
| 9 | <%= @asset.upload.url %> | 10 | |
| 10 | (<%= number_to_human_size(@asset.upload.size) %>) | 11 | <% if @asset.upload.present? %> |
| 11 | </p> | 12 | <div class="node_description">Current File</div> |
| 12 | <% end %> | 13 | <div class="node_content"><%= @asset.upload.url %> (<%= number_to_human_size(@asset.upload.size) %>)</div> |
| 14 | <% end %> | ||
| 15 | |||
| 16 | <div class="node_description"><%= f.label :upload, "Replace file" %></div> | ||
| 17 | <div class="node_content"><%= f.file_field :upload %></div> | ||
| 13 | 18 | ||
| 14 | <p> | 19 | <div class="node_description"><%= f.label :creator %></div> |
| 15 | <label>Replace file:</label><br> | 20 | <div class="node_content"><%= f.text_field :creator %></div> |
| 16 | <%= f.file_field :upload %> | ||
| 17 | </p> | ||
| 18 | 21 | ||
| 19 | <p> | 22 | <div class="node_description"><%= f.label :source_url, "Source URL" %></div> |
| 20 | <%= f.submit 'Update' %> | 23 | <div class="node_content"><%= f.text_field :source_url %></div> |
| 21 | </p> | ||
| 22 | <% end %> | ||
| 23 | 24 | ||
| 24 | <%= link_to 'Show', @asset %> | <%= link_to 'Back', assets_path %> | 25 | <div class="node_description"><%= f.label :license_key, "License" %></div> |
| 26 | <div class="node_content"> | ||
| 27 | <%= f.select :license_key, | ||
| 28 | options_for_select( | ||
| 29 | [["— none —", ""]] + AssetLicense.keys.map { |key| [t("asset_licenses.#{key}"), key] }, | ||
| 30 | @asset.license_key | ||
| 31 | ) %> | ||
| 32 | </div> | ||
| 33 | |||
| 34 | <div class="node_description">Actions</div> | ||
| 35 | <div class="node_content node_info_group"> | ||
| 36 | <div class="node_info_group_items"> | ||
| 37 | <div class="node_info_item"><%= f.submit 'Update' %></div> | ||
| 38 | <div class="node_info_item"><%= link_to 'Show', @asset %></div> | ||
| 39 | <div class="node_info_item"><%= link_to 'Back', assets_path %></div> | ||
| 40 | </div> | ||
| 41 | </div> | ||
| 42 | </div> | ||
| 43 | <% end %> | ||
| 44 | </div> | ||
diff --git a/app/views/assets/index.html.erb b/app/views/assets/index.html.erb index 8c35561..ff1300a 100644 --- a/app/views/assets/index.html.erb +++ b/app/views/assets/index.html.erb | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | </tr> | 17 | </tr> |
| 18 | <% @assets.each do |asset| %> | 18 | <% @assets.each do |asset| %> |
| 19 | <tr> | 19 | <tr> |
| 20 | <td><%= image_tag asset.upload.url(:thumb), style: "max-width: 100px; max-height: 100px;" %></td> | 20 | <td><% if asset.has_variant?(:thumb) %><%= image_tag asset.upload.url(:thumb), style: "max-width: 100px; max-height: 100px;" %><% end %></td> |
| 21 | <td><%= link_to asset.name, asset.upload.url %></td> | 21 | <td><%= link_to asset.name, asset.upload.url %></td> |
| 22 | <td><%= asset.upload.content_type %></td> | 22 | <td><%= asset.upload.content_type %></td> |
| 23 | <td><%= link_to 'Show', asset %></td> | 23 | <td><%= link_to 'Show', asset %></td> |
diff --git a/app/views/assets/new.html.erb b/app/views/assets/new.html.erb index 6c1310a..2cf8865 100644 --- a/app/views/assets/new.html.erb +++ b/app/views/assets/new.html.erb | |||
| @@ -1,17 +1,38 @@ | |||
| 1 | <h1>New asset</h1> | 1 | <div id="page_editor"> |
| 2 | <h1>New asset</h1> | ||
| 2 | 3 | ||
| 3 | <%= form_for(@asset, :html => { :multipart => true }) do |f| %> | 4 | <%= form_for(@asset, :html => { :multipart => true }) do |f| %> |
| 4 | <%= form_error_messages(f) %> | 5 | <%= form_error_messages(f) %> |
| 5 | |||
| 6 | <p> | ||
| 7 | <%= f.label :name %><br /> | ||
| 8 | <%= f.text_field :name %> | ||
| 9 | </p> | ||
| 10 | 6 | ||
| 11 | <p> | 7 | <div id="content"> |
| 12 | <%= f.file_field :upload %> | 8 | <div class="node_description"><%= f.label :name %></div> |
| 13 | <%= f.submit 'Create' %> | 9 | <div class="node_content"><%= f.text_field :name %></div> |
| 14 | </p> | ||
| 15 | <% end %> | ||
| 16 | 10 | ||
| 17 | <%= link_to 'Back', assets_path %> | 11 | <div class="node_description"><%= f.label :upload, "File" %></div> |
| 12 | <div class="node_content"><%= f.file_field :upload %></div> | ||
| 13 | |||
| 14 | <div class="node_description"><%= f.label :creator %></div> | ||
| 15 | <div class="node_content"><%= f.text_field :creator %></div> | ||
| 16 | |||
| 17 | <div class="node_description"><%= f.label :source_url, "Source URL" %></div> | ||
| 18 | <div class="node_content"><%= f.text_field :source_url %></div> | ||
| 19 | |||
| 20 | <div class="node_description"><%= f.label :license_key, "License" %></div> | ||
| 21 | <div class="node_content"> | ||
| 22 | <%= f.select :license_key, | ||
| 23 | options_for_select( | ||
| 24 | [["— none —", ""]] + AssetLicense.keys.map { |key| [t("asset_licenses.#{key}"), key] }, | ||
| 25 | @asset.license_key | ||
| 26 | ) %> | ||
| 27 | </div> | ||
| 28 | |||
| 29 | <div class="node_description">Actions</div> | ||
| 30 | <div class="node_content node_info_group"> | ||
| 31 | <div class="node_info_group_items"> | ||
| 32 | <div class="node_info_item"><%= f.submit 'Create' %></div> | ||
| 33 | <div class="node_info_item"><%= link_to 'Back', assets_path %></div> | ||
| 34 | </div> | ||
| 35 | </div> | ||
| 36 | </div> | ||
| 37 | <% end %> | ||
| 38 | </div> | ||
diff --git a/app/views/assets/show.html.erb b/app/views/assets/show.html.erb index 5717dd9..e551e35 100644 --- a/app/views/assets/show.html.erb +++ b/app/views/assets/show.html.erb | |||
| @@ -16,11 +16,42 @@ | |||
| 16 | </div> | 16 | </div> |
| 17 | </div> | 17 | </div> |
| 18 | 18 | ||
| 19 | <div class="node_description">Thumbnail</div> | 19 | <% if @asset.has_variant?(:medium) %> |
| 20 | <div class="node_content"><%= image_tag @asset.upload.url(:medium), style: "max-width: 300px; max-height: 300px;" %></div> | 20 | <div class="node_description">Thumbnail</div> |
| 21 | <div class="node_content"><%= image_tag @asset.upload.url(:medium), style: "max-width: 300px; max-height: 300px;" %></div> | ||
| 22 | <% end %> | ||
| 21 | 23 | ||
| 22 | <div class="node_description">Public Path</div> | 24 | <div class="node_description">Public Path</div> |
| 23 | <div class="node_content"><%= @asset.upload.url.sub(/\?\d+$/, "") %></div> | 25 | <div class="node_content"> |
| 26 | <% public_path = @asset.upload.url.sub(/\?\d+$/, "") %> | ||
| 27 | <%= link_to public_path, public_path, target: "_blank", rel: "noopener" %> | ||
| 28 | <button type="button" class="action_button copy_button" | ||
| 29 | data-copy-url="<%= request.base_url + public_path %>"> | ||
| 30 | <%= icon("copy", library: "tabler", "aria-hidden": true) %> | ||
| 31 | <span class="copy_button_label">Copy URL</span> | ||
| 32 | </button> | ||
| 33 | </div> | ||
| 34 | |||
| 35 | <div class="node_description">Creator</div> | ||
| 36 | <div class="node_content"><%= @asset.creator.presence || "—" %></div> | ||
| 37 | |||
| 38 | <div class="node_description">Source</div> | ||
| 39 | <div class="node_content"> | ||
| 40 | <% if @asset.source_url.present? %> | ||
| 41 | <%= link_to @asset.source_url, @asset.source_url %> | ||
| 42 | <% else %> | ||
| 43 | — | ||
| 44 | <% end %> | ||
| 45 | </div> | ||
| 46 | |||
| 47 | <div class="node_description">License</div> | ||
| 48 | <div class="node_content"> | ||
| 49 | <% if (license = AssetLicense.find(@asset.license_key)) %> | ||
| 50 | <%= t("asset_licenses.#{license.key}") %> | ||
| 51 | <% else %> | ||
| 52 | — | ||
| 53 | <% end %> | ||
| 54 | </div> | ||
| 24 | 55 | ||
| 25 | <div class="node_description">Content Type</div> | 56 | <div class="node_description">Content Type</div> |
| 26 | <div class="node_content"><%= @asset.upload.content_type %></div> | 57 | <div class="node_content"><%= @asset.upload.content_type %></div> |
diff --git a/app/views/content/_asset_credits.html.erb b/app/views/content/_asset_credits.html.erb new file mode 100644 index 0000000..85739d0 --- /dev/null +++ b/app/views/content/_asset_credits.html.erb | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | <% if @page.assets.images.any? %> | ||
| 2 | <div id="asset_credits"> | ||
| 3 | <% @page.assets.images.each do |image| %> | ||
| 4 | <% credit = asset_credit(image) %> | ||
| 5 | <% next unless credit %> | ||
| 6 | <div id="credit_for_asset_<%= image.id %>" | ||
| 7 | class="glightbox-desc<%= " headline_credit" if image == @headline_asset %>"> | ||
| 8 | <%= credit %> | ||
| 9 | </div> | ||
| 10 | <% end %> | ||
| 11 | </div> | ||
| 12 | <% end %> | ||
diff --git a/app/views/content/_headline_image.html.erb b/app/views/content/_headline_image.html.erb index 243be40..c764d22 100644 --- a/app/views/content/_headline_image.html.erb +++ b/app/views/content/_headline_image.html.erb | |||
| @@ -1,16 +1,28 @@ | |||
| 1 | <%= link_to( | 1 | <% gallery_images = @page.assets.images %> |
| 2 | image_tag(@images[0].upload.url(:headline)), | ||
| 3 | @images[0].upload.url, | ||
| 4 | :class => "glightbox", | ||
| 5 | :data => { :gallery => "page-#{@page.node.id}" } | ||
| 6 | ) %> | ||
| 7 | 2 | ||
| 8 | <% if 1 < @images.length %> | 3 | <% if @headline_asset %> |
| 9 | <div class="right"> | 4 | <%= link_to( |
| 10 | <%= "#{@images.length} #{t(:images)}" %> | 5 | image_tag(@headline_asset.upload.url(:headline)), |
| 11 | </div> | 6 | @headline_asset.upload.url, |
| 7 | :class => "glightbox", | ||
| 8 | :data => { :gallery => "page-#{@page.node.id}", :title => @headline_asset.name, | ||
| 9 | :description => "#credit_for_asset_#{@headline_asset.id}" } | ||
| 10 | ) %> | ||
| 11 | <% if gallery_images.size > 1 %> | ||
| 12 | <div class="right"><%= "#{gallery_images.size} #{t(:images)}" %></div> | ||
| 13 | <% end %> | ||
| 14 | <% elsif gallery_images.any? %> | ||
| 15 | <%= link_to "#{gallery_images.size} #{t(:images)}, #{t(:open_gallery)}", | ||
| 16 | gallery_images.first.upload.url, | ||
| 17 | :class => "glightbox right", | ||
| 18 | :data => { :gallery => "page-#{@page.node.id}", :title => gallery_images.first.name, | ||
| 19 | :description => "#credit_for_asset_#{gallery_images.first.id}" } %> | ||
| 12 | <% end %> | 20 | <% end %> |
| 13 | 21 | ||
| 14 | <% @images[1..-1].each do |image| %> | 22 | <% gallery_images.each do |image| %> |
| 15 | <%= link_to "", image.upload.url, :class => "glightbox", :style => "display: none", :data => { :gallery => "page-#{@page.node.id}" } %> | 23 | <% next if image == @headline_asset %> |
| 24 | <% next if !@headline_asset && image == gallery_images.first %> | ||
| 25 | <%= link_to "", image.upload.url, :class => "glightbox", :style => "display: none", | ||
| 26 | :data => { :gallery => "page-#{@page.node.id}", :title => image.name, | ||
| 27 | :description => "#credit_for_asset_#{image.id}" } %> | ||
| 16 | <% end %> | 28 | <% end %> |
diff --git a/app/views/custom/page_templates/public/chapter_detail.html.erb b/app/views/custom/page_templates/public/chapter_detail.html.erb index c4c2598..18449b8 100644 --- a/app/views/custom/page_templates/public/chapter_detail.html.erb +++ b/app/views/custom/page_templates/public/chapter_detail.html.erb | |||
| @@ -31,4 +31,5 @@ | |||
| 31 | </ul> | 31 | </ul> |
| 32 | </div> | 32 | </div> |
| 33 | <% end %> | 33 | <% end %> |
| 34 | <%= render partial: 'content/asset_credits' %> | ||
| 34 | </div> | 35 | </div> |
diff --git a/app/views/custom/page_templates/public/no_date_and_author.html.erb b/app/views/custom/page_templates/public/no_date_and_author.html.erb index fa39e54..ec7e850 100644 --- a/app/views/custom/page_templates/public/no_date_and_author.html.erb +++ b/app/views/custom/page_templates/public/no_date_and_author.html.erb | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | <p><%= sanitize( @page.abstract ) %></p> | 3 | <p><%= sanitize( @page.abstract ) %></p> |
| 4 | <div id="headline_image"><%= headline_image %></div> | 4 | <div id="headline_image"><%= headline_image %></div> |
| 5 | <%= aggregate?(@page.body) %> | 5 | <%= aggregate?(@page.body) %> |
| 6 | <%= render partial: 'content/asset_credits' %> | ||
| 6 | </div> | 7 | </div> |
| 7 | 8 | ||
| 8 | <%= will_paginate(@content_collection) if @content_collection %> | 9 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/page_templates/public/no_title_abstract_date_and_author.html.erb b/app/views/custom/page_templates/public/no_title_abstract_date_and_author.html.erb index 64e2a7c..c486684 100644 --- a/app/views/custom/page_templates/public/no_title_abstract_date_and_author.html.erb +++ b/app/views/custom/page_templates/public/no_title_abstract_date_and_author.html.erb | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | <div class="article" lang="<%= @page.effective_lang %>"> | 1 | <div class="article" lang="<%= @page.effective_lang %>"> |
| 2 | <div id="headline_image"><%= headline_image %></div> | 2 | <div id="headline_image"><%= headline_image %></div> |
| 3 | <%= aggregate?(@page.body) %> | 3 | <%= aggregate?(@page.body) %> |
| 4 | <%= render partial: 'content/asset_credits' %> | ||
| 4 | </div> | 5 | </div> |
| 5 | 6 | ||
| 6 | <%= will_paginate(@content_collection) if @content_collection %> | 7 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/page_templates/public/standard_template.html.erb b/app/views/custom/page_templates/public/standard_template.html.erb index bbc8cd0..e1e2eb0 100644 --- a/app/views/custom/page_templates/public/standard_template.html.erb +++ b/app/views/custom/page_templates/public/standard_template.html.erb | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | <div class="abstract"><p><%= sanitize( @page.abstract )%></p></div> | 3 | <div class="abstract"><p><%= sanitize( @page.abstract )%></p></div> |
| 4 | <div id="headline_image"><%= headline_image %></div> | 4 | <div id="headline_image"><%= headline_image %></div> |
| 5 | <div class="body"><%= aggregate?(@page.body) %></div> | 5 | <div class="body"><%= aggregate?(@page.body) %></div> |
| 6 | <%= render partial: 'content/asset_credits' %> | ||
| 6 | </div> | 7 | </div> |
| 7 | 8 | ||
| 8 | <%= will_paginate(@content_collection) if @content_collection %> | 9 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/page_templates/public/title_only.html.erb b/app/views/custom/page_templates/public/title_only.html.erb index 42fe9a6..d706e9d 100644 --- a/app/views/custom/page_templates/public/title_only.html.erb +++ b/app/views/custom/page_templates/public/title_only.html.erb | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | <h2 class="headline"><%= @page.title %></h2> | 2 | <h2 class="headline"><%= @page.title %></h2> |
| 3 | <div id="headline_image"><%= headline_image %></div> | 3 | <div id="headline_image"><%= headline_image %></div> |
| 4 | <%= aggregate?(@page.body) %> | 4 | <%= aggregate?(@page.body) %> |
| 5 | <%= render partial: 'content/asset_credits' %> | ||
| 5 | </div> | 6 | </div> |
| 6 | 7 | ||
| 7 | <%= will_paginate(@content_collection) if @content_collection %> | 8 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/custom/page_templates/public/update.html.erb b/app/views/custom/page_templates/public/update.html.erb index d5995ac..0ff1bb2 100644 --- a/app/views/custom/page_templates/public/update.html.erb +++ b/app/views/custom/page_templates/public/update.html.erb | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | <div class="abstract"><p><%= sanitize( @page.abstract )%></p></div> | 4 | <div class="abstract"><p><%= sanitize( @page.abstract )%></p></div> |
| 5 | <div id="headline_image"><%= headline_image %></div> | 5 | <div id="headline_image"><%= headline_image %></div> |
| 6 | <div class="body"><%= aggregate?(@page.body) %></div> | 6 | <div class="body"><%= aggregate?(@page.body) %></div> |
| 7 | <%= render partial: 'content/asset_credits' %> | ||
| 7 | </div> | 8 | </div> |
| 8 | 9 | ||
| 9 | <%= will_paginate(@content_collection) if @content_collection %> | 10 | <%= will_paginate(@content_collection) if @content_collection %> |
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 352fb66..f981fc1 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | <meta property="og:description" content="Der Chaos Computer Club ist eine galaktische Gemeinschaft von Lebewesen für Informationsfreiheit und Technikfolgenabschätzung." /> | 10 | <meta property="og:description" content="Der Chaos Computer Club ist eine galaktische Gemeinschaft von Lebewesen für Informationsfreiheit und Technikfolgenabschätzung." /> |
| 11 | 11 | ||
| 12 | <title><%= page_title %></title> | 12 | <title><%= page_title %></title> |
| 13 | <link rel="stylesheet" href="<%= mtime_busted_path('/stylesheets/ccc_new.css') %>"> | 13 | <link rel="stylesheet" href="<%= mtime_busted_path('/stylesheets/ccc.css') %>"> |
| 14 | <link rel="stylesheet" href="<%= mtime_busted_path('/stylesheets/glightbox.min.css') %>"> | 14 | <link rel="stylesheet" href="<%= mtime_busted_path('/stylesheets/glightbox.min.css') %>"> |
| 15 | <script src="<%= mtime_busted_path('/javascripts/glightbox.min.js') %>"></script> | 15 | <script src="<%= mtime_busted_path('/javascripts/glightbox.min.js') %>"></script> |
| 16 | <script src="<%= mtime_busted_path('/javascripts/public.js') %>"></script> | 16 | <script src="<%= mtime_busted_path('/javascripts/public.js') %>"></script> |
diff --git a/app/views/layouts/events.html.erb b/app/views/layouts/events.html.erb deleted file mode 100644 index 93a6c0c..0000000 --- a/app/views/layouts/events.html.erb +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | ||
| 2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
| 3 | |||
| 4 | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | ||
| 5 | <head> | ||
| 6 | <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> | ||
| 7 | <title>Events: <%= controller.action_name %></title> | ||
| 8 | <%= stylesheet_link_tag 'scaffold' %> | ||
| 9 | </head> | ||
| 10 | <body> | ||
| 11 | |||
| 12 | <p style="color: green"><%= flash[:notice] %></p> | ||
| 13 | |||
| 14 | <%= yield %> | ||
| 15 | |||
| 16 | </body> | ||
| 17 | </html> | ||
diff --git a/app/views/node_actions/_change_details.html.erb b/app/views/node_actions/_change_details.html.erb index 2583e8b..066d0f3 100644 --- a/app/views/node_actions/_change_details.html.erb +++ b/app/views/node_actions/_change_details.html.erb | |||
| @@ -5,9 +5,13 @@ | |||
| 5 | <tr> | 5 | <tr> |
| 6 | <th><%= I18n.default_locale.to_s.upcase %></th> | 6 | <th><%= I18n.default_locale.to_s.upcase %></th> |
| 7 | <td> | 7 | <td> |
| 8 | <%= safe_join(default_items, ", ") %> | 8 | <%= safe_join(default_items, tag.br) %> |
| 9 | <% if action_entry.page && action_entry.node %> | 9 | <% if action_entry.page && action_entry.node %> |
| 10 | <%= link_to t("node_actions.view_revision"), node_revision_path(action_entry.node, action_entry.page) %> | 10 | <% if (diff_params = action_entry.diff_link_params) %> |
| 11 | <%= link_to t("node_actions.view_diff"), diff_node_revisions_path(action_entry.node, diff_params) %> | ||
| 12 | <% else %> | ||
| 13 | <%= link_to t("node_actions.view_revision"), node_revision_path(action_entry.node, action_entry.page) %> | ||
| 14 | <% end %> | ||
| 11 | <% end %> | 15 | <% end %> |
| 12 | </td> | 16 | </td> |
| 13 | </tr> | 17 | </tr> |
| @@ -16,9 +20,13 @@ | |||
| 16 | <tr> | 20 | <tr> |
| 17 | <th><%= locale.upcase %></th> | 21 | <th><%= locale.upcase %></th> |
| 18 | <td> | 22 | <td> |
| 19 | <%= safe_join(translation_changes(diff), ", ") %> | 23 | <%= safe_join(translation_changes(diff), tag.br) %> |
| 20 | <% if action_entry.page && action_entry.node %> | 24 | <% if action_entry.page && action_entry.node %> |
| 21 | <%= link_to t("node_actions.view_revision"), node_revision_path(action_entry.node, action_entry.page, :locale => locale) %> | 25 | <% if (diff_params = action_entry.diff_link_params) %> |
| 26 | <%= link_to t("node_actions.view_diff"), diff_node_revisions_path(action_entry.node, diff_params.merge(:locale => locale)) %> | ||
| 27 | <% else %> | ||
| 28 | <%= link_to t("node_actions.view_revision"), node_revision_path(action_entry.node, action_entry.page, :locale => locale) %> | ||
| 29 | <% end %> | ||
| 22 | <% end %> | 30 | <% end %> |
| 23 | </td> | 31 | </td> |
| 24 | </tr> | 32 | </tr> |
diff --git a/app/views/nodes/edit.html.erb b/app/views/nodes/edit.html.erb index 25f15c2..da682f0 100644 --- a/app/views/nodes/edit.html.erb +++ b/app/views/nodes/edit.html.erb | |||
| @@ -82,17 +82,26 @@ | |||
| 82 | <ul id="related_asset_list" class="thumbnail_list"> | 82 | <ul id="related_asset_list" class="thumbnail_list"> |
| 83 | <% @page.related_assets.includes(:asset).each do |related| %> | 83 | <% @page.related_assets.includes(:asset).each do |related| %> |
| 84 | <li data-url="<%= node_related_asset_path(@node, related) %>" | 84 | <li data-url="<%= node_related_asset_path(@node, related) %>" |
| 85 | data-asset-id="<%= related.asset.id %>" | ||
| 85 | data-large-url="<%= related.asset.upload.url(:large) %>" | 86 | data-large-url="<%= related.asset.upload.url(:large) %>" |
| 86 | data-original-url="<%= related.asset.upload.url %>" | 87 | data-original-url="<%= related.asset.upload.url %>" |
| 87 | data-name="<%= related.asset.name %>"> | 88 | data-name="<%= related.asset.name %>" |
| 89 | data-headline="<%= related.headline? %>" | ||
| 90 | class="<%= "is_headline" if related.headline? %>"> | ||
| 88 | <span class="related_asset_handle"><%= icon("grip-vertical", library: "tabler", "aria-hidden": true) %></span> | 91 | <span class="related_asset_handle"><%= icon("grip-vertical", library: "tabler", "aria-hidden": true) %></span> |
| 89 | <%= image_tag related.asset.upload.url(:thumb) %> | 92 | <%= image_tag related.asset.upload.url(:thumb) %> |
| 93 | <button type="button" class="related_asset_set_headline" | ||
| 94 | aria-pressed="<%= related.headline? %>" aria-label="Set as headline image" | ||
| 95 | title="Use this photo as the page's headline image"> | ||
| 96 | <%= icon("star", library: "tabler", "aria-hidden": true) %> | ||
| 97 | </button> | ||
| 90 | <button type="button" class="related_asset_remove" aria-label="Remove image"> | 98 | <button type="button" class="related_asset_remove" aria-label="Remove image"> |
| 91 | <%= icon("x", library: "tabler", "aria-hidden": true) %> | 99 | <%= icon("x", library: "tabler", "aria-hidden": true) %> |
| 92 | </button> | 100 | </button> |
| 93 | </li> | 101 | </li> |
| 94 | <% end %> | 102 | <% end %> |
| 95 | </ul> | 103 | </ul> |
| 104 | <p class="field_hint">The starred photo becomes this page's headline image on the public site. If none is starred, visitors get a link to browse all attached images instead.</p> | ||
| 96 | <%= text_field_tag nil, nil, id: "related_asset_search_term", placeholder: "Search images to attach…", autocomplete: "off" %> | 105 | <%= text_field_tag nil, nil, id: "related_asset_search_term", placeholder: "Search images to attach…", autocomplete: "off" %> |
| 97 | <div id="related_asset_search_results" class="search_results"></div> | 106 | <div id="related_asset_search_results" class="search_results"></div> |
| 98 | </div> | 107 | </div> |
| @@ -102,6 +111,9 @@ | |||
| 102 | <li> | 111 | <li> |
| 103 | <span class="related_asset_handle"><%= icon("grip-vertical", library: "tabler", "aria-hidden": true) %></span> | 112 | <span class="related_asset_handle"><%= icon("grip-vertical", library: "tabler", "aria-hidden": true) %></span> |
| 104 | <img src=""> | 113 | <img src=""> |
| 114 | <button type="button" class="related_asset_set_headline" aria-pressed="false" aria-label="Set as headline image"> | ||
| 115 | <%= icon("star", library: "tabler", "aria-hidden": true) %> | ||
| 116 | </button> | ||
| 105 | <button type="button" class="related_asset_remove" aria-label="Remove image"> | 117 | <button type="button" class="related_asset_remove" aria-label="Remove image"> |
| 106 | <%= icon("x", library: "tabler", "aria-hidden": true) %> | 118 | <%= icon("x", library: "tabler", "aria-hidden": true) %> |
| 107 | </button> | 119 | </button> |
diff --git a/app/views/nodes/new.html.erb b/app/views/nodes/new.html.erb index 890d46e..805fbc9 100644 --- a/app/views/nodes/new.html.erb +++ b/app/views/nodes/new.html.erb | |||
| @@ -41,7 +41,10 @@ | |||
| 41 | <div class="node_description">Resulting path</div> | 41 | <div class="node_description">Resulting path</div> |
| 42 | <div class="node_content"> | 42 | <div class="node_content"> |
| 43 | <span id="resulting_path">—</span> | 43 | <span id="resulting_path">—</span> |
| 44 | <button type="button" id="copy_resulting_path" class="unselected">copy</button> | 44 | <button type="button" id="copy_resulting_path" class="unselected copy_button" data-copy-target="#resulting_path"> |
| 45 | <span class="copy_button_label">copy</span> | ||
| 46 | </button> | ||
| 47 | |||
| 45 | <span class="field_hint">This preview updates as you type. The final path can still be changed afterward by editing the title (for the last segment) or moving the node to a different parent (for everything before it).</span> | 48 | <span class="field_hint">This preview updates as you type. The final path can still be changed afterward by editing the title (for the last segment) or moving the node to a different parent (for everything before it).</span> |
| 46 | </div> | 49 | </div> |
| 47 | 50 | ||
