Working on zeitwerk support

This commit is contained in:
Alexander Meindl
2021-11-23 19:16:49 +01:00
parent fbece21051
commit 1c23f13ec7
35 changed files with 977 additions and 911 deletions

View File

@@ -4,7 +4,7 @@ Changelog
3.0.4 3.0.4
+++++ +++++
- Mermaid 8.13.3 support - Mermaid 8.13.4 support
- D3 7.1.1 support - D3 7.1.1 support
- Ruby 2.6 is required - Ruby 2.6 is required

View File

@@ -2,11 +2,11 @@
lib = File.expand_path '../lib', __FILE__ lib = File.expand_path '../lib', __FILE__
$LOAD_PATH.unshift lib unless $LOAD_PATH.include? lib $LOAD_PATH.unshift lib unless $LOAD_PATH.include? lib
require 'additionals/version' require 'additionals/plugin_version'
Gem::Specification.new do |spec| Gem::Specification.new do |spec|
spec.name = 'additionals' spec.name = 'additionals'
spec.version = Additionals::VERSION spec.version = Additionals::PluginVersion::VERSION
spec.authors = ['AlphaNodes'] spec.authors = ['AlphaNodes']
spec.email = ['alex@alphanodes.com'] spec.email = ['alex@alphanodes.com']
spec.metadata = { 'rubygems_mfa_required' => 'true' } spec.metadata = { 'rubygems_mfa_required' => 'true' }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -181,7 +181,7 @@ It provides :
* `d3 7.1.1 <https://d3js.org/>`_ * `d3 7.1.1 <https://d3js.org/>`_
* `d3plus v2.0.0-alpha.30 <https://d3plus.org/>`_ * `d3plus v2.0.0-alpha.30 <https://d3plus.org/>`_
* `FontAwesome 5.15.4 <https://fontawesome.com/>`_ * `FontAwesome 5.15.4 <https://fontawesome.com/>`_
* `mermaid 8.13.3 <https://github.com/mermaid-js/mermaid>`_ * `mermaid 8.13.4 <https://github.com/mermaid-js/mermaid>`_
* `Select2 4.0.13 <https://select2.org/>`_ * `Select2 4.0.13 <https://select2.org/>`_
And a set of various Rails helper methods (see below). And a set of various Rails helper methods (see below).

View File

@@ -4,7 +4,7 @@ Redmine::Plugin.register :additionals do
name 'Additionals' name 'Additionals'
author 'AlphaNodes GmbH' author 'AlphaNodes GmbH'
description 'Customizing Redmine, providing wiki macros and act as a library/function provider for other Redmine plugins' description 'Customizing Redmine, providing wiki macros and act as a library/function provider for other Redmine plugins'
version Additionals::VERSION version Additionals::PluginVersion::VERSION
author_url 'https://alphanodes.com/' author_url 'https://alphanodes.com/'
url 'https://github.com/alphanodes/additionals' url 'https://github.com/alphanodes/additionals'
directory __dir__ directory __dir__
@@ -61,6 +61,8 @@ Dir.glob(Rails.root.join('plugins/*/app/overrides')).each do |dir|
Rails.application.paths['app/overrides'] << dir unless Rails.application.paths['app/overrides'].include? dir Rails.application.paths['app/overrides'] << dir unless Rails.application.paths['app/overrides'].include? dir
end end
Rails.configuration.to_prepare do if Rails.version > '6.0'
Additionals.setup ActiveSupport.on_load(:active_record) { Additionals.setup }
else
Rails.configuration.to_prepare { Additionals.setup }
end end

View File

@@ -1,7 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'additionals/version'
module Additionals module Additionals
MAX_CUSTOM_MENU_ITEMS = 5 MAX_CUSTOM_MENU_ITEMS = 5
SELECT2_INIT_ENTRIES = 20 SELECT2_INIT_ENTRIES = 20
@@ -17,22 +15,27 @@ module Additionals
redmine_changeauthor redmine_changeauthor
redmine_auto_watch] redmine_auto_watch]
patch %w[ApplicationController ApplicationController.include Additionals::Patches::ApplicationControllerPatch
AutoCompletesController AutoCompletesController.include Additionals::Patches::AutoCompletesControllerPatch
Issue Issue.include Additionals::Patches::IssuePatch
IssuePriority IssuePriority.include Additionals::Patches::IssuePriorityPatch
TimeEntry TimeEntry.include Additionals::Patches::TimeEntryPatch
Project Project.include Additionals::Patches::ProjectPatch
Wiki Wiki.include Additionals::Patches::WikiPatch
ProjectsController ProjectsController.include Additionals::Patches::ProjectsControllerPatch
WelcomeController WelcomeController.include Additionals::Patches::WelcomeControllerPatch
ReportsController ReportsController.include Additionals::Patches::ReportsControllerPatch
Principal Principal.include Additionals::Patches::PrincipalPatch
Query Query.include Additionals::Patches::QueryPatch
QueryFilter QueryFilter.include Additionals::Patches::QueryFilterPatch
Role Role.include Additionals::Patches::RolePatch
User User.include Additionals::Patches::UserPatch
UserPreference] UserPreference.include Additionals::Patches::UserPreferencePatch
IssuesController.send :helper, AdditionalsIssuesHelper
SettingsController.send :helper, AdditionalsSettingsHelper
WikiController.send :helper, AdditionalsWikiPdfHelper
CustomFieldsController.send :helper, AdditionalsCustomFieldsHelper
Redmine::WikiFormatting.format_names.each do |format| Redmine::WikiFormatting.format_names.each do |format|
case format case format
@@ -45,11 +48,6 @@ module Additionals
end end
end end
IssuesController.send :helper, AdditionalsIssuesHelper
SettingsController.send :helper, AdditionalsSettingsHelper
WikiController.send :helper, AdditionalsWikiPdfHelper
CustomFieldsController.send :helper, AdditionalsCustomFieldsHelper
# Static class patches # Static class patches
Redmine::AccessControl.include Additionals::Patches::AccessControlPatch Redmine::AccessControl.include Additionals::Patches::AccessControlPatch
Redmine::AccessControl.singleton_class.prepend Additionals::Patches::AccessControlClassPatch Redmine::AccessControl.singleton_class.prepend Additionals::Patches::AccessControlClassPatch
@@ -58,13 +56,13 @@ module Additionals
ActionView::Base.include Additionals::Helpers ActionView::Base.include Additionals::Helpers
ActionView::Base.include AdditionalsFontawesomeHelper ActionView::Base.include AdditionalsFontawesomeHelper
ActionView::Base.include AdditionalsMenuHelper ActionView::Base.include AdditionalsMenuHelper
ActionView::Base.include Additionals::AdditionalsSelect2Helper ActionView::Base.include AdditionalsSelect2Helper
# Hooks
require_dependency 'additionals/hooks'
# Macros # Macros
load_macros load_macros
# Hooks
Additionals::Hooks
end end
# support with default setting as fall back # support with default setting as fall back
@@ -132,6 +130,7 @@ module Additionals
end end
end end
# obsolete, do not use this method (it will be removed in next major release)
def patch(patches = [], plugin_id = 'additionals') def patch(patches = [], plugin_id = 'additionals')
patches.each do |name| patches.each do |name|
patch_dir = Rails.root.join "plugins/#{plugin_id}/lib/#{plugin_id}/patches" patch_dir = Rails.root.join "plugins/#{plugin_id}/lib/#{plugin_id}/patches"
@@ -152,6 +151,16 @@ module Additionals
'**/*_macro.rb')].sort.each { |f| require f } '**/*_macro.rb')].sort.each { |f| require f }
end end
def load_custom_field_format(plugin_id, reverse: false)
files = Dir[File.join(plugin_dir(plugin_id),
'lib',
plugin_id,
'custom_field_formats',
'**/*_format.rb')].sort
files.reverse! if reverse
files.each { |f| require f }
end
def plugin_dir(plugin_id = 'additionals') def plugin_dir(plugin_id = 'additionals')
if Gem.loaded_specs[plugin_id].nil? if Gem.loaded_specs[plugin_id].nil?
File.join Redmine::Plugin.directory, plugin_id File.join Redmine::Plugin.directory, plugin_id

View File

@@ -1,49 +1,52 @@
# frozen_string_literal: true # frozen_string_literal: true
module Additionals module Additionals
class AdditionalsHookListener < Redmine::Hook::ViewListener module Hooks
include IssuesHelper class AdditionalsHookListener < Redmine::Hook::ViewListener
include AdditionalsIssuesHelper Additionals.debug 'additonals hooks load'
include IssuesHelper
include AdditionalsIssuesHelper
render_on :view_layouts_base_html_head, partial: 'additionals/html_head' render_on :view_layouts_base_html_head, partial: 'additionals/html_head'
render_on :view_layouts_base_body_top, partial: 'additionals/body_top' render_on :view_layouts_base_body_top, partial: 'additionals/body_top'
render_on :view_layouts_base_body_bottom, partial: 'additionals/body_bottom' render_on :view_layouts_base_body_bottom, partial: 'additionals/body_bottom'
render_on :view_account_login_bottom, partial: 'login_text' render_on :view_account_login_bottom, partial: 'login_text'
render_on :view_issues_context_menu_start, partial: 'additionals_closed_issues' render_on :view_issues_context_menu_start, partial: 'additionals_closed_issues'
render_on :view_issues_bulk_edit_details_bottom, partial: 'change_author_bulk' render_on :view_issues_bulk_edit_details_bottom, partial: 'change_author_bulk'
render_on :view_issues_form_details_bottom, partial: 'change_author' render_on :view_issues_form_details_bottom, partial: 'change_author'
render_on :view_issues_new_top, partial: 'new_ticket_message' render_on :view_issues_new_top, partial: 'new_ticket_message'
render_on :view_issues_sidebar_issues_bottom, partial: 'issues/additionals_sidebar_issues' render_on :view_issues_sidebar_issues_bottom, partial: 'issues/additionals_sidebar_issues'
render_on :view_issues_sidebar_queries_bottom, partial: 'issues/additionals_sidebar_queries' render_on :view_issues_sidebar_queries_bottom, partial: 'issues/additionals_sidebar_queries'
render_on :view_my_account_preferences, partial: 'users/autowatch_involved_issue' render_on :view_my_account_preferences, partial: 'users/autowatch_involved_issue'
render_on :view_users_form_preferences, partial: 'users/autowatch_involved_issue' render_on :view_users_form_preferences, partial: 'users/autowatch_involved_issue'
render_on :view_users_show_contextual, partial: 'users/additionals_contextual' render_on :view_users_show_contextual, partial: 'users/additionals_contextual'
render_on :view_wiki_show_sidebar_bottom, partial: 'wiki/additionals_sidebar' render_on :view_wiki_show_sidebar_bottom, partial: 'wiki/additionals_sidebar'
render_on :view_projects_issue_settings, partial: 'projects/additionals_settings_issues' render_on :view_projects_issue_settings, partial: 'projects/additionals_settings_issues'
def helper_issues_show_detail_after_setting(context = {}) def helper_issues_show_detail_after_setting(context = {})
detail = context[:detail] detail = context[:detail]
return unless detail.prop_key == 'author_id' return unless detail.prop_key == 'author_id'
detail[:value] = find_name_by_reflection('author', detail.value) || detail.value detail[:value] = find_name_by_reflection('author', detail.value) || detail.value
detail[:old_value] = find_name_by_reflection('author', detail.old_value) || detail.old_value detail[:old_value] = find_name_by_reflection('author', detail.old_value) || detail.old_value
end end
def view_layouts_base_content(context = {}) def view_layouts_base_content(context = {})
controller = context[:controller] controller = context[:controller]
return if controller.nil? return if controller.nil?
controller_name = context[:controller].params[:controller] controller_name = context[:controller].params[:controller]
action_name = context[:controller].params[:action] action_name = context[:controller].params[:action]
return if controller_name == 'account' && action_name == 'login' || return if controller_name == 'account' && action_name == 'login' ||
controller_name == 'my' || controller_name == 'my' ||
controller_name == 'account' && action_name == 'lost_password' || controller_name == 'account' && action_name == 'lost_password' ||
!Additionals.setting?(:add_go_to_top) !Additionals.setting?(:add_go_to_top)
link_to l(:label_go_to_top), '#gototop', class: 'gototop' link_to l(:label_go_to_top), '#gototop', class: 'gototop'
end
end end
end end
end end

View File

@@ -0,0 +1,7 @@
# frozen_string_literal: true
module Additionals
module PluginVersion
VERSION = '3.0.4-master'
end
end

View File

@@ -1,5 +0,0 @@
# frozen_string_literal: true
module Additionals
VERSION = '3.0.4-master' unless defined? VERSION
end

View File

@@ -2,13 +2,15 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module AsciinemaMacro
desc 'asciinema embed' Redmine::WikiFormatting::Macros.register do
desc 'asciinema embed'
macro :asciinema do |_obj, args| macro :asciinema do |_obj, args|
raise 'The correct usage is {{asciinema(<cast_id>)}}' if args.empty? raise 'The correct usage is {{asciinema(<cast_id>)}}' if args.empty?
javascript_tag nil, id: "asciicast-#{args[0]}", src: "//asciinema.org/a/#{args[0]}.js", async: true javascript_tag nil, id: "asciicast-#{args[0]}", src: "//asciinema.org/a/#{args[0]}.js", async: true
end
end end
end end
end end

View File

@@ -4,86 +4,88 @@
# see https://www.cryptocompare.com/dev/widget/wizard/ # see https://www.cryptocompare.com/dev/widget/wizard/
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module CryptocompareMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Create CryptoCompare information. desc <<-DESCRIPTION
{{cryptocompare(options)}} Create CryptoCompare information.
see https://additionals.readthedocs.io/en/latest/macros/#cryptocompare {{cryptocompare(options)}}
DESCRIPTION see https://additionals.readthedocs.io/en/latest/macros/#cryptocompare
DESCRIPTION
macro :cryptocompare do |_obj, args| macro :cryptocompare do |_obj, args|
raise 'The correct usage is {{cryptocompare(options)}}' if args.empty? raise 'The correct usage is {{cryptocompare(options)}}' if args.empty?
_args, options = extract_macro_options args, :fsym, :fsyms, :tsym, :tsyms, :period, :type _args, options = extract_macro_options args, :fsym, :fsyms, :tsym, :tsyms, :period, :type
options[:fsym] = 'BTC' if options[:fsym].blank? options[:fsym] = 'BTC' if options[:fsym].blank?
options[:tsym] = 'EUR' if options[:tsym].blank? options[:tsym] = 'EUR' if options[:tsym].blank?
if options[:type].blank? if options[:type].blank?
widget_type = 'chart' widget_type = 'chart'
else else
widget_type = options[:type] widget_type = options[:type]
options.delete :type options.delete :type
end
case widget_type
when 'chart'
url = 'serve/v2/coin/chart'
when 'news'
options[:feedType] = 'CoinTelegraph' if options[:feedType].blank?
url = 'serve/v1/coin/feed'
when 'list'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/list'
when 'titles'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/tiles'
when 'tabbed'
options[:fsyms] = Additionals.crypto_default options, :fsyms, 'BTC,ETH,LTC'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :fsym
options.delete :tsym
url = 'serve/v1/coin/multi'
when 'header', 'header_v1'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/header'
when 'header_v2'
options[:fsyms] = Additionals.crypto_default options, :fsyms, 'BTC,ETH,LTC'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :fsym
options.delete :tsym
url = 'serve/v2/coin/header'
when 'header_v3'
options[:fsyms] = Additionals.crypto_default options, :fsyms, 'BTC,ETH,LTC'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR'
options.delete :fsym
options.delete :tsym
url = 'serve/v3/coin/header'
when 'summary'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/summary'
when 'historical'
url = 'serve/v1/coin/histo_week'
when 'converter'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/converter'
when 'advanced'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v3/coin/chart'
else
raise 'type is not supported'
end
params = options.map { |k, v| "#{k}=#{v}" }.join('&')
render partial: 'wiki/cryptocompare',
formats: [:html],
locals: { url: "https://widgets.cryptocompare.com/#{url}?#{params}" }
end end
case widget_type
when 'chart'
url = 'serve/v2/coin/chart'
when 'news'
options[:feedType] = 'CoinTelegraph' if options[:feedType].blank?
url = 'serve/v1/coin/feed'
when 'list'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/list'
when 'titles'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/tiles'
when 'tabbed'
options[:fsyms] = Additionals.crypto_default options, :fsyms, 'BTC,ETH,LTC'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :fsym
options.delete :tsym
url = 'serve/v1/coin/multi'
when 'header', 'header_v1'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/header'
when 'header_v2'
options[:fsyms] = Additionals.crypto_default options, :fsyms, 'BTC,ETH,LTC'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :fsym
options.delete :tsym
url = 'serve/v2/coin/header'
when 'header_v3'
options[:fsyms] = Additionals.crypto_default options, :fsyms, 'BTC,ETH,LTC'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR'
options.delete :fsym
options.delete :tsym
url = 'serve/v3/coin/header'
when 'summary'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/summary'
when 'historical'
url = 'serve/v1/coin/histo_week'
when 'converter'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v1/coin/converter'
when 'advanced'
options[:tsyms] = Additionals.crypto_default options, :tsyms, 'EUR,USD'
options.delete :tsym
url = 'serve/v3/coin/chart'
else
raise 'type is not supported'
end
params = options.map { |k, v| "#{k}=#{v}" }.join('&')
render partial: 'wiki/cryptocompare',
formats: [:html],
locals: { url: "https://widgets.cryptocompare.com/#{url}?#{params}" }
end end
end end
end end

View File

@@ -2,69 +2,71 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module DateMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Show date. desc <<-DESCRIPTION
Show date.
Syntax: Syntax:
{{date([TYPE])}} {{date([TYPE])}}
TYPE TYPE
- current_date current date (default) - current_date current date (default)
- current_date_with_time current date with time - current_date_with_time current date with time
- current_year current year - current_year current year
- current_month current month - current_month current month
- current_day current day - current_day current day
- current_hour current hour - current_hour current hour
- current_minute current minute - current_minute current minute
- current_weekday current weekday - current_weekday current weekday
- current_weeknumber current week number (1 - 52) The week starts with Monday - current_weeknumber current week number (1 - 52) The week starts with Monday
- YYYY-MM-DD e.g. 2018-12-24, which will formated with Redmine date format - YYYY-MM-DD e.g. 2018-12-24, which will formated with Redmine date format
Examples: Examples:
{{date}} {{date}}
...show current date ...show current date
{{date(current_year)}} {{date(current_year)}}
...show current year ...show current year
{{date(current_month)}} {{date(current_month)}}
...show current month ...show current month
{{date(current_weeknumber)}} {{date(current_weeknumber)}}
...show current week number ...show current week number
DESCRIPTION DESCRIPTION
macro :date do |_obj, args| macro :date do |_obj, args|
type = if args.present? type = if args.present?
args[0] args[0]
else else
'current_date' 'current_date'
end end
d = Additionals.now_with_user_time_zone d = Additionals.now_with_user_time_zone
date_result = case type date_result = case type
when 'current_date' when 'current_date'
format_date User.current.today format_date User.current.today
when 'current_date_with_time' when 'current_date_with_time'
format_time d, true format_time d, true
when 'current_year' when 'current_year'
d.year d.year
when 'current_month' when 'current_month'
d.month d.month
when 'current_day' when 'current_day'
d.day d.day
when 'current_hour' when 'current_hour'
d.hour d.hour
when 'current_minute' when 'current_minute'
d.min d.min
when 'current_weekday' when 'current_weekday'
day_name d.wday day_name d.wday
when 'current_weeknumber' when 'current_weeknumber'
User.current.today.cweek User.current.today.cweek
else else
format_date type.to_date format_date type.to_date
end end
tag.span date_result, class: 'current-date' tag.span date_result, class: 'current-date'
end
end end
end end
end end

View File

@@ -2,68 +2,70 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module FaMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Show Font Awesome icon. desc <<-DESCRIPTION
Show Font Awesome icon.
Syntax: Syntax:
{{fa(ICON [, class=CLASS, title=TITLE, text=TEXT size=SIZE, color=COLOR)}} {{fa(ICON [, class=CLASS, title=TITLE, text=TEXT size=SIZE, color=COLOR)}}
ICON of fontawesome icon, eg. fa-adjust ICON of fontawesome icon, eg. fa-adjust
CLASS = additional css classes CLASS = additional css classes
TITLE = mouseover title TITLE = mouseover title
TEXT = Text to show TEXT = Text to show
LINK = Link icon and text (if specified) to this URL LINK = Link icon and text (if specified) to this URL
COLOR = css color code COLOR = css color code
Examples: Examples:
{{fa(adjust)}} {{fa(adjust)}}
...show fontawesome icon "fas fa-adjust" ...show fontawesome icon "fas fa-adjust"
{{fa(adjust, class=fa-inverse)}} {{fa(adjust, class=fa-inverse)}}
...show fontawesome icon "fas fa-stack" and inverse ...show fontawesome icon "fas fa-stack" and inverse
{{fa(adjust, size=4x)}} {{fa(adjust, size=4x)}}
...show fontawesome icon "fas fa-adjust" with size 4x ...show fontawesome icon "fas fa-adjust" with size 4x
{{fa(fas_adjust, title=Show icon)}} {{fa(fas_adjust, title=Show icon)}}
...show fontawesome icon "fas fa-adjust" with title "Show icon" ...show fontawesome icon "fas fa-adjust" with title "Show icon"
{{fa(fab_angellist)}} {{fa(fab_angellist)}}
...Show fontawesome icon "fab fa-angellist" ...Show fontawesome icon "fab fa-angellist"
{{fa(adjust, link=https=//www.redmine.org))}} {{fa(adjust, link=https=//www.redmine.org))}}
...Show fontawesome icon "fas fa-adjust" and link it to https://www.redmine.org ...Show fontawesome icon "fas fa-adjust" and link it to https://www.redmine.org
{{fa(adjust, link=https=//www.redmine.de, name=Go to Redmine.org))}} {{fa(adjust, link=https=//www.redmine.de, name=Go to Redmine.org))}}
...Show fontawesome icon "fas fa-adjust" with name "Go to Redmine.org" and link it to https://www.redmine.org ...Show fontawesome icon "fas fa-adjust" with name "Go to Redmine.org" and link it to https://www.redmine.org
DESCRIPTION DESCRIPTION
macro :fa do |_obj, args| macro :fa do |_obj, args|
args, options = extract_macro_options args, :class, :title, :text, :size, :color, :link args, options = extract_macro_options args, :class, :title, :text, :size, :color, :link
raise 'The correct usage is {{fa(<ICON>, class=CLASS, title=TITLE, text=TEXT, size=SIZE, color=COLOR)}}' if args.empty? raise 'The correct usage is {{fa(<ICON>, class=CLASS, title=TITLE, text=TEXT, size=SIZE, color=COLOR)}}' if args.empty?
values = args[0].split '_' values = args[0].split '_'
classes = [] classes = []
if values.count == 2 if values.count == 2
classes << values[0] classes << values[0]
classes << "fa-#{values[1]}" classes << "fa-#{values[1]}"
else else
classes << 'fas' classes << 'fas'
classes << "fa-#{values[0]}" classes << "fa-#{values[0]}"
end end
classes += options[:class].split if options[:class].present? classes += options[:class].split if options[:class].present?
classes << "fa-#{options[:size]}" if options[:size].present? classes << "fa-#{options[:size]}" if options[:size].present?
content_options = { class: classes.uniq.join(' ') } content_options = { class: classes.uniq.join(' ') }
content_options[:title] = options[:title] if options[:title].present? content_options[:title] = options[:title] if options[:title].present?
content_options[:style] = "color: #{options[:color]}" if options[:color].present? content_options[:style] = "color: #{options[:color]}" if options[:color].present?
text = options[:text].present? ? " #{options[:text]}" : '' text = options[:text].present? ? " #{options[:text]}" : ''
if options[:link].present? if options[:link].present?
tag.a href: options[:link] do tag.a href: options[:link] do
tag.i text, content_options tag.i text, content_options
end
else
tag.i text, **content_options
end end
else
tag.i text, **content_options
end end
end end
end end

View File

@@ -2,13 +2,15 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module GistMacro
desc 'gist embed' Redmine::WikiFormatting::Macros.register do
desc 'gist embed'
macro :gist do |_obj, args| macro :gist do |_obj, args|
raise 'The correct usage is {{gist(<gist_id>)}}' if args.empty? raise 'The correct usage is {{gist(<gist_id>)}}' if args.empty?
javascript_tag nil, src: "https://gist.github.com/#{args[0]}.js" javascript_tag nil, src: "https://gist.github.com/#{args[0]}.js"
end
end end
end end
end end

View File

@@ -2,88 +2,90 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module GmapMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Display a google map. Examples: desc <<-DESCRIPTION
Display a google map. Examples:
Syntax: Syntax:
{{gmap([q=QUERY, mode=MODE, width=216, height=368])}} {{gmap([q=QUERY, mode=MODE, width=216, height=368])}}
Examples: Examples:
{{gmap(Munich)}} Google maps with Munich {{gmap(Munich)}} Google maps with Munich
{{gmap(mode=directions, origin=Munich+Rosenheimerstr, destination=Arco)}} Direction from Munich to Arco {{gmap(mode=directions, origin=Munich+Rosenheimerstr, destination=Arco)}} Direction from Munich to Arco
DESCRIPTION DESCRIPTION
macro :gmap do |_obj, args| macro :gmap do |_obj, args|
src_options = %i[attribution_ios_deep_link_id src_options = %i[attribution_ios_deep_link_id
attribution_source attribution_source
attribution_web_url attribution_web_url
avoid avoid
center center
destination destination
fov fov
heading heading
language language
location location
maptype maptype
origin origin
pano pano
pitch pitch
region region
units units
waypoints waypoints
zoom] zoom]
args, options = extract_macro_options(args, args, options = extract_macro_options(args,
:mode, :mode,
:width, :width,
:height, :height,
:attribution_ios_deep_link_id, :attribution_ios_deep_link_id,
:attribution_source, :attribution_source,
:attribution_web_url, :attribution_web_url,
:avoid, :avoid,
:center, :center,
:destination, :destination,
:fov, :fov,
:heading, :heading,
:language, :language,
:location, :location,
:maptype, :maptype,
:origin, :origin,
:pano, :pano,
:pitch, :pitch,
:region, :region,
:units, :units,
:way_mode, :way_mode,
:waypoints, :waypoints,
:zoom) :zoom)
raise 'Missing Google Maps Embed API Key. See documentation for more info.' if Additionals.setting(:google_maps_api_key).blank? raise 'Missing Google Maps Embed API Key. See documentation for more info.' if Additionals.setting(:google_maps_api_key).blank?
width = options[:width].presence || 620 width = options[:width].presence || 620
height = options[:height].presence || 350 height = options[:height].presence || 350
mode = options[:mode].presence || 'search' mode = options[:mode].presence || 'search'
if mode == 'search' && options[:q].blank? && args.empty? if mode == 'search' && options[:q].blank? && args.empty?
raise 'The correct usage is {{gmap([q=QUERY, mode=MODE, widths=x, height=y])}}' raise 'The correct usage is {{gmap([q=QUERY, mode=MODE, widths=x, height=y])}}'
end
src = +"https://www.google.com/maps/embed/v1/#{mode}?key=" + Additionals.setting(:google_maps_api_key)
if options[:q].present?
src << "&q=#{ERB::Util.url_encode options[:q]}"
elsif mode == 'search'
src << "&q=#{ERB::Util.url_encode args[0]}"
end
src_options.each do |key|
src << Additionals.gmap_flags(options, key)
end
src << "&#{mode}=" + ERB::Util.url_encode(options[:way_mode]) if options[:way_mode].present?
tag.iframe width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true'
end end
src = +"https://www.google.com/maps/embed/v1/#{mode}?key=" + Additionals.setting(:google_maps_api_key)
if options[:q].present?
src << "&q=#{ERB::Util.url_encode options[:q]}"
elsif mode == 'search'
src << "&q=#{ERB::Util.url_encode args[0]}"
end
src_options.each do |key|
src << Additionals.gmap_flags(options, key)
end
src << "&#{mode}=" + ERB::Util.url_encode(options[:way_mode]) if options[:way_mode].present?
tag.iframe width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true'
end end
end end
end end

View File

@@ -2,53 +2,55 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module GoogleDocsMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Google docs macro to include Google documents. desc <<-DESCRIPTION
Google docs macro to include Google documents.
Syntax: Syntax:
{{google_docs(<link> [, width=100%, height=485, edit_link=LINK)}} {{google_docs(<link> [, width=100%, height=485, edit_link=LINK)}}
Examples: Examples:
{{google_docs(https://docs.google.com/spreadsheets/d/e/2PACX-1vQL__Vgu0Y0f-P__GJ9kpUmQ0S-HG56ni_b-x4WpWxzGIGXh3X6A587SeqvJDpH42rDmWVZoUN07VGE/pubhtml)} {{google_docs(https://docs.google.com/spreadsheets/d/e/2PACX-1vQL__Vgu0Y0f-P__GJ9kpUmQ0S-HG56ni_b-x4WpWxzGIGXh3X6A587SeqvJDpH42rDmWVZoUN07VGE/pubhtml)}
{{google_docs(https://docs.google.com/spreadsheets/d/e/2PACX-1vQL__Vgu0Y0f-P__GJ9kpUmQ0S-HG56ni_b-x4WpWxzGIGXh3X6A587SeqvJDpH42rDmWVZoUN07VGE/pubhtml, width=514, height=422)} {{google_docs(https://docs.google.com/spreadsheets/d/e/2PACX-1vQL__Vgu0Y0f-P__GJ9kpUmQ0S-HG56ni_b-x4WpWxzGIGXh3X6A587SeqvJDpH42rDmWVZoUN07VGE/pubhtml, width=514, height=422)}
DESCRIPTION DESCRIPTION
macro :google_docs do |_obj, args| macro :google_docs do |_obj, args|
args, options = extract_macro_options args, :width, :height, :edit_link args, options = extract_macro_options args, :width, :height, :edit_link
width = options[:width].presence || '100%' width = options[:width].presence || '100%'
height = options[:height].presence || 485 height = options[:height].presence || 485
raise 'The correct usage is {{google_docs(<link>[, width=x, height=y, edit_link=LINK])}}' if args.empty? raise 'The correct usage is {{google_docs(<link>[, width=x, height=y, edit_link=LINK])}}' if args.empty?
v = args[0] v = args[0]
raise '<link> is not a Google document.' unless v.start_with? 'https://docs.google.com/' raise '<link> is not a Google document.' unless v.start_with? 'https://docs.google.com/'
src = v.dup src = v.dup
unless src.include? '?' unless src.include? '?'
src << if src.include? 'edit' src << if src.include? 'edit'
'?rm=minimal' '?rm=minimal'
else else
'?widget=true&headers=false' '?widget=true&headers=false'
end end
end
s = []
s << tag.iframe(width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true')
if options[:edit_link].present?
raise '<edit_link> is not a Google document.' unless options[:edit_link].start_with? 'https://docs.google.com/'
s << tag.br
s << link_to(font_awesome_icon('fab_google-drive', post_text: :label_open_in_google_docs),
options[:edit_link],
class: 'external')
end
safe_join s
end end
s = []
s << tag.iframe(width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true')
if options[:edit_link].present?
raise '<edit_link> is not a Google document.' unless options[:edit_link].start_with? 'https://docs.google.com/'
s << tag.br
s << link_to(font_awesome_icon('fab_google-drive', post_text: :label_open_in_google_docs),
options[:edit_link],
class: 'external')
end
safe_join s
end end
end end
end end

View File

@@ -2,33 +2,35 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module GroupUsersMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Display users of group. desc <<-DESCRIPTION
Display users of group.
Syntax: Syntax:
{{group_users(GROUP_NAME}} {{group_users(GROUP_NAME}}
Examples: Examples:
{{group_users(Team)}} {{group_users(Team)}}
...List all users in user group "Team" (with the current user permission) ...List all users in user group "Team" (with the current user permission)
DESCRIPTION DESCRIPTION
macro :group_users do |_obj, args| macro :group_users do |_obj, args|
raise 'The correct usage is {{group_users(<group_name>)}}' if args.empty? raise 'The correct usage is {{group_users(<group_name>)}}' if args.empty?
group_name = args[0].strip group_name = args[0].strip
group = Group.named(group_name).first group = Group.named(group_name).first
raise unless group raise unless group
users = Principal.visible.where(id: group.users).order(User.name_formatter[:order]) users = Principal.visible.where(id: group.users).order(User.name_formatter[:order])
render partial: 'wiki/user_macros', render partial: 'wiki/user_macros',
formats: [:html], formats: [:html],
locals: { users: users, locals: { users: users,
user_roles: nil, user_roles: nil,
list_title: group_name } list_title: group_name }
end
end end
end end
end end

View File

@@ -2,45 +2,47 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module IframeMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Include iframe desc <<-DESCRIPTION
Include iframe
Syntax: Syntax:
{{iframe(<url> [, width=100%, height=485)}} {{iframe(<url> [, width=100%, height=485)}}
Examples: Examples:
show iframe of URL https://www.google.com/ show iframe of URL https://www.google.com/
{{iframe(https://www.google.com/)}} {{iframe(https://www.google.com/)}}
show iframe of URL https://www.google.com/ and show link to it show iframe of URL https://www.google.com/ and show link to it
{{iframe(https://www.google.com/, with_link: true)}} {{iframe(https://www.google.com/, with_link: true)}}
DESCRIPTION DESCRIPTION
macro :iframe do |_obj, args| macro :iframe do |_obj, args|
args, options = extract_macro_options args, :width, :height, :slide, :with_link args, options = extract_macro_options args, :width, :height, :slide, :with_link
width = options[:width].presence || '100%' width = options[:width].presence || '100%'
height = options[:height].presence || 485 height = options[:height].presence || 485
raise 'The correct usage is {{iframe(<url>[, width=x, height=y, with_link=bool])}}' if args.empty? raise 'The correct usage is {{iframe(<url>[, width=x, height=y, with_link=bool])}}' if args.empty?
src = args[0] src = args[0]
if Additionals.valid_iframe_url? src if Additionals.valid_iframe_url? src
s = [tag.iframe(width: width, s = [tag.iframe(width: width,
height: height, height: height,
src: src, src: src,
frameborder: 0, frameborder: 0,
allowfullscreen: 'true')] allowfullscreen: 'true')]
s << link_to(l(:label_open_in_new_windows), src, class: 'external') if Additionals.true? options[:with_link] s << link_to(l(:label_open_in_new_windows), src, class: 'external') if Additionals.true? options[:with_link]
safe_join s safe_join s
elsif Setting.protocol == 'https' elsif Setting.protocol == 'https'
raise 'Invalid url provided to iframe (only full URLs with protocol HTTPS are accepted)' raise 'Invalid url provided to iframe (only full URLs with protocol HTTPS are accepted)'
else else
raise 'Invalid url provided to iframe (only full URLs are accepted)' raise 'Invalid url provided to iframe (only full URLs are accepted)'
end
end end
end end
end end

View File

@@ -2,39 +2,41 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module LastUpdatedAtMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Displays a date that updated the page. desc <<-DESCRIPTION
{{last_updated_at}} Displays a date that updated the page.
{{last_updated_at(project_name, wiki_page)}} {{last_updated_at}}
{{last_updated_at(project_identifier, wiki_page)}} {{last_updated_at(project_name, wiki_page)}}
DESCRIPTION {{last_updated_at(project_identifier, wiki_page)}}
DESCRIPTION
macro :last_updated_at do |obj, args| macro :last_updated_at do |obj, args|
return '' unless @project return '' unless @project
if args.empty? if args.empty?
page = obj page = obj
else else
raise '{{last_updated_at(project_identifier, wiki_page)}}' if args.length < 2 raise '{{last_updated_at(project_identifier, wiki_page)}}' if args.length < 2
project_name = args[0].strip project_name = args[0].strip
page_name = args[1].strip page_name = args[1].strip
project = Project.find_by name: project_name project = Project.find_by name: project_name
project ||= Project.find_by identifier: project_name project ||= Project.find_by identifier: project_name
return unless project return unless project
wiki = Wiki.find_by project_id: project.id wiki = Wiki.find_by project_id: project.id
return unless wiki return unless wiki
page = wiki.find_page page_name page = wiki.find_page page_name
end
return unless page
# TODO: find solution for time_tag without to use html_safe
tag.span(l(:label_updated_time, time_tag(page.updated_on)).html_safe, # rubocop:disable Rails/OutputSafety
class: 'last-updated-at')
end end
return unless page
# TODO: find solution for time_tag without to use html_safe
tag.span(l(:label_updated_time, time_tag(page.updated_on)).html_safe, # rubocop:disable Rails/OutputSafety
class: 'last-updated-at')
end end
end end
end end

View File

@@ -2,17 +2,19 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module LastUpdatedByMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Displays a user who updated the page. desc <<-DESCRIPTION
{{last_updated_by}} Displays a user who updated the page.
DESCRIPTION {{last_updated_by}}
DESCRIPTION
macro :last_updated_by do |obj, args| macro :last_updated_by do |obj, args|
raise 'The correct usage is {{last_updated_by}}' unless args.empty? raise 'The correct usage is {{last_updated_by}}' unless args.empty?
tag.span safe_join([avatar(obj.author, size: 14), ' ', link_to_user(obj.author)]), tag.span safe_join([avatar(obj.author, size: 14), ' ', link_to_user(obj.author)]),
class: 'last-updated-by' class: 'last-updated-by'
end
end end
end end
end end

View File

@@ -2,77 +2,79 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module MemberMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Display members. desc <<-DESCRIPTION
Display members.
Syntax: Syntax:
{{members([PROJECT_NAME, title=My members list, role=ROLE, with_sum=BOOL)]}} {{members([PROJECT_NAME, title=My members list, role=ROLE, with_sum=BOOL)]}}
PROJECT_NAME can be project identifier, project name or project id PROJECT_NAME can be project identifier, project name or project id
Examples: Examples:
{{members}} {{members}}
...List all members for all projects (with the current user permission) ...List all members for all projects (with the current user permission)
{{members(with_sum=true)}} {{members(with_sum=true)}}
...List all members for all projects and show title with amount of members ...List all members for all projects and show title with amount of members
{{members(the-identifier)}} {{members(the-identifier)}}
...A box showing all members for the project with the identifier of 'the-identifier' ...A box showing all members for the project with the identifier of 'the-identifier'
{{members(the-identifier, role=Manager)}} {{members(the-identifier, role=Manager)}}
...A box showing all members for the project with the identifier of 'the-identifier', which ...A box showing all members for the project with the identifier of 'the-identifier', which
have the role "Manager" have the role "Manager"
{{members(the-identifier, title=My user list)}} {{members(the-identifier, title=My user list)}}
...A box showing all members for the project with the identifier of 'the-identifier' and with ...A box showing all members for the project with the identifier of 'the-identifier' and with
box title "My user list" box title "My user list"
DESCRIPTION DESCRIPTION
macro :members do |_obj, args| macro :members do |_obj, args|
args, options = extract_macro_options args, :role, :title, :with_sum args, options = extract_macro_options args, :role, :title, :with_sum
project_id = args[0] project_id = args[0]
user_roles = [] user_roles = []
if project_id.present? if project_id.present?
project_id.strip! project_id.strip!
project = Project.visible.find_by id: project_id project = Project.visible.find_by id: project_id
project ||= Project.visible.find_by identifier: project_id project ||= Project.visible.find_by identifier: project_id
project ||= Project.visible.find_by name: project_id project ||= Project.visible.find_by name: project_id
return if project.nil? return if project.nil?
principals = project.visible_users principals = project.visible_users
return if principals.nil? return if principals.nil?
users = [] users = []
principals.each do |principal| principals.each do |principal|
next unless principal.type == 'User' next unless principal.type == 'User'
user_roles[principal.id] = principal.roles_for_project project user_roles[principal.id] = principal.roles_for_project project
users << principal if options[:role].blank? || Additionals.check_role_matches(user_roles[principal.id], options[:role]) users << principal if options[:role].blank? || Additionals.check_role_matches(user_roles[principal.id], options[:role])
end
else
users = User.visible
.where(type: 'User')
.active
.sorted
end end
else
users = User.visible list_title = if options[:with_sum]
.where(type: 'User') list_title = options[:title].presence || l(:label_member_plural)
.active list_title + " (#{users.count})"
.sorted else
options[:title]
end
render partial: 'wiki/user_macros', locals: { users: users,
user_roles: user_roles,
list_title: list_title }
end end
list_title = if options[:with_sum]
list_title = options[:title].presence || l(:label_member_plural)
list_title + " (#{users.count})"
else
options[:title]
end
render partial: 'wiki/user_macros', locals: { users: users,
user_roles: user_roles,
list_title: list_title }
end end
end end
end end

View File

@@ -2,75 +2,77 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module MeteoblueMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Display current weather from meteoblue service. Examples: desc <<-DESCRIPTION
Display current weather from meteoblue service. Examples:
Syntax: Syntax:
{{meteoblue(<location> [, days=INT, width=216, height=368, color=BOOL])}} {{meteoblue(<location> [, days=INT, width=216, height=368, color=BOOL])}}
Examples: Examples:
{{meteoblue(münchen_deutschland_2867714)}} weather for Munich {{meteoblue(münchen_deutschland_2867714)}} weather for Munich
{{meteoblue(münchen_deutschland_2867714, days=6, color=false)}} weather for Munich of the next 6 days without color {{meteoblue(münchen_deutschland_2867714, days=6, color=false)}} weather for Munich of the next 6 days without color
DESCRIPTION DESCRIPTION
macro :meteoblue do |_obj, args| macro :meteoblue do |_obj, args|
args, options = extract_macro_options(args, args, options = extract_macro_options(args,
:days, :days,
:width, :width,
:height, :height,
:color, :color,
:pictoicon, :pictoicon,
:maxtemperature, :maxtemperature,
:mintemperature, :mintemperature,
:windspeed, :windspeed,
:windgust, :windgust,
:winddirection, :winddirection,
:uv, :uv,
:humidity, :humidity,
:precipitation, :precipitation,
:precipitationprobability, :precipitationprobability,
:spot) :spot)
raise 'The correct usage is {{meteoblue(<location>[, days=x, color=BOOL])}}' if args.empty? raise 'The correct usage is {{meteoblue(<location>[, days=x, color=BOOL])}}' if args.empty?
options[:days] = 4 if options[:days].blank? options[:days] = 4 if options[:days].blank?
options[:coloured] = if Additionals.false? options[:color] options[:coloured] = if Additionals.false? options[:color]
'monochrome' 'monochrome'
else else
'coloured' 'coloured'
end end
width = options[:width].presence || 216 width = options[:width].presence || 216
height = options[:height].presence || 368 height = options[:height].presence || 368
src = if User.current.language.blank? ? ::I18n.locale : User.current.language == 'de' src = if User.current.language.blank? ? ::I18n.locale : User.current.language == 'de'
+'https://www.meteoblue.com/de/wetter/widget/daily/' +'https://www.meteoblue.com/de/wetter/widget/daily/'
else else
+'https://www.meteoblue.com/en/weather/widget/daily/' +'https://www.meteoblue.com/en/weather/widget/daily/'
end end
src << ERB::Util.url_encode(args[0]) src << ERB::Util.url_encode(args[0])
src << "?geoloc=fixed&days=#{options[:days]}&tempunit=CELSIUS&windunit=KILOMETER_PER_HOUR" src << "?geoloc=fixed&days=#{options[:days]}&tempunit=CELSIUS&windunit=KILOMETER_PER_HOUR"
src << "&precipunit=MILLIMETER&coloured=#{options[:coloured]}" src << "&precipunit=MILLIMETER&coloured=#{options[:coloured]}"
src << Additionals.meteoblue_flag(options, :pictoicon, true) src << Additionals.meteoblue_flag(options, :pictoicon, true)
src << Additionals.meteoblue_flag(options, :maxtemperature, true) src << Additionals.meteoblue_flag(options, :maxtemperature, true)
src << Additionals.meteoblue_flag(options, :mintemperature, true) src << Additionals.meteoblue_flag(options, :mintemperature, true)
src << Additionals.meteoblue_flag(options, :windspeed, false) src << Additionals.meteoblue_flag(options, :windspeed, false)
src << Additionals.meteoblue_flag(options, :windgust, false) src << Additionals.meteoblue_flag(options, :windgust, false)
src << Additionals.meteoblue_flag(options, :winddirection, false) src << Additionals.meteoblue_flag(options, :winddirection, false)
src << Additionals.meteoblue_flag(options, :uv, false) src << Additionals.meteoblue_flag(options, :uv, false)
src << Additionals.meteoblue_flag(options, :humidity, false) src << Additionals.meteoblue_flag(options, :humidity, false)
src << Additionals.meteoblue_flag(options, :precipitation, true) src << Additionals.meteoblue_flag(options, :precipitation, true)
src << Additionals.meteoblue_flag(options, :precipitationprobability, true) src << Additionals.meteoblue_flag(options, :precipitationprobability, true)
src << Additionals.meteoblue_flag(options, :spot, true) src << Additionals.meteoblue_flag(options, :spot, true)
src << Additionals.meteoblue_flag(options, :pressure, false) src << Additionals.meteoblue_flag(options, :pressure, false)
tag.iframe width: width, height: height, src: src, frameborder: 0 tag.iframe width: width, height: height, src: src, frameborder: 0
end
end end
end end
end end

View File

@@ -2,60 +2,62 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module NewIssueMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Create a link for "New issue" for the current user. desc <<-DESCRIPTION
Create a link for "New issue" for the current user.
Syntax: Syntax:
{{new_issue([PROJECT_NAME, name=Custom name]}} {{new_issue([PROJECT_NAME, name=Custom name]}}
PROJECT_NAME can be project identifier, project name or project id. PROJECT_NAME can be project identifier, project name or project id.
If no PROJECT_NAME is specified, first project is used, which the current user If no PROJECT_NAME is specified, first project is used, which the current user
has permission to create an issue. has permission to create an issue.
Examples: Examples:
{{new_issue}} {{new_issue}}
...Link to create new issue in first available project ...Link to create new issue in first available project
{{new_issue(the-identifier)}} {{new_issue(the-identifier)}}
...Link to create new issue in project with the identifier of 'the-identifier' ...Link to create new issue in project with the identifier of 'the-identifier'
{{new_issue(the-identifier, title=New issue for broken displays)}} {{new_issue(the-identifier, title=New issue for broken displays)}}
...Link to create new issue in project with the identifier of 'the-identifier' ...Link to create new issue in project with the identifier of 'the-identifier'
and the name 'New issue for broken displays' and the name 'New issue for broken displays'
DESCRIPTION DESCRIPTION
macro :new_issue do |_obj, args| macro :new_issue do |_obj, args|
if args.any? if args.any?
args, options = extract_macro_options(args, *additionals_titles_for_locale(:name)) args, options = extract_macro_options(args, *additionals_titles_for_locale(:name))
i18n_name = additionals_i18n_title options, :name i18n_name = additionals_i18n_title options, :name
project_id = args[0] project_id = args[0]
end
i18n_name = l :label_issue_new if i18n_name.blank?
if project_id.present?
project_id.strip!
project = Project.visible.find_by id: project_id
project ||= Project.visible.find_by identifier: project_id
project ||= Project.visible.find_by name: project_id
return '' if project.nil? || !User.current.allowed_to?(:add_issues, project)
return link_to i18n_name, new_project_issue_path(project), class: 'macro-new-issue icon icon-add'
else
@memberships = User.current
.memberships
.preload(:roles, :project)
.where(Project.visible_condition(User.current))
.to_a
if @memberships.present?
project_url = memberships_new_issue_project_url User.current, @memberships, :add_issues
return link_to i18n_name, project_url, class: 'macro-new-issue icon icon-add' if project_url.present?
end end
end i18n_name = l :label_issue_new if i18n_name.blank?
'' if project_id.present?
project_id.strip!
project = Project.visible.find_by id: project_id
project ||= Project.visible.find_by identifier: project_id
project ||= Project.visible.find_by name: project_id
return '' if project.nil? || !User.current.allowed_to?(:add_issues, project)
return link_to i18n_name, new_project_issue_path(project), class: 'macro-new-issue icon icon-add'
else
@memberships = User.current
.memberships
.preload(:roles, :project)
.where(Project.visible_condition(User.current))
.to_a
if @memberships.present?
project_url = memberships_new_issue_project_url User.current, @memberships, :add_issues
return link_to i18n_name, project_url, class: 'macro-new-issue icon icon-add' if project_url.present?
end
end
''
end
end end
end end
end end

View File

@@ -2,37 +2,39 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module ProjectMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Display projects. desc <<-DESCRIPTION
Display projects.
Syntax: Syntax:
{{projects([title=My project list, with_create_issue=BOOL])}} {{projects([title=My project list, with_create_issue=BOOL])}}
Examples: Examples:
{{projects}} {{projects}}
...List all project, which I am member of ...List all project, which I am member of
{{projects(title=My project list)}} {{projects(title=My project list)}}
...List all project with title "My project list", which I am member of ...List all project with title "My project list", which I am member of
{{projects(with_create_issue=true)}} {{projects(with_create_issue=true)}}
...List all project with link to create new issue, which I am member of ...List all project with link to create new issue, which I am member of
DESCRIPTION DESCRIPTION
macro :projects do |_obj, args| macro :projects do |_obj, args|
_args, options = extract_macro_options args, :title, :with_create_issue _args, options = extract_macro_options args, :title, :with_create_issue
@projects = User.current.projects.active.includes(:enabled_modules).sorted @projects = User.current.projects.active.includes(:enabled_modules).sorted
return if @projects.nil? return if @projects.nil?
@html_options = { class: 'external' } @html_options = { class: 'external' }
render partial: 'wiki/project_macros', render partial: 'wiki/project_macros',
formats: [:html], formats: [:html],
locals: { projects: @projects, locals: { projects: @projects,
list_title: options[:title], list_title: options[:title],
with_create_issue: options[:with_create_issue] } with_create_issue: options[:with_create_issue] }
end
end end
end end
end end

View File

@@ -2,55 +2,57 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module RecentlyUpdatedMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Displays a list of pages that were updated recently. desc <<-DESCRIPTION
{{recently_updated}} Displays a list of pages that were updated recently.
{{recently_updated([days])}} {{recently_updated}}
{{recently_updated([days])}}
Examples: Examples:
{{recently_updated}} {{recently_updated}}
...List last updated pages (of the last 5 days) ...List last updated pages (of the last 5 days)
{{recently_updated(15)}} {{recently_updated(15)}}
...List last updated pages of the last 15 days ...List last updated pages of the last 15 days
DESCRIPTION DESCRIPTION
macro :recently_updated do |obj, args| macro :recently_updated do |obj, args|
page = obj.page page = obj.page
return unless page return unless page
project = page.project project = page.project
return unless project return unless project
days = 5 days = 5
days = args[0].strip.to_i unless args.empty? days = args[0].strip.to_i unless args.empty?
return if days < 1 return if days < 1
pages = WikiPage.joins(:content) pages = WikiPage.joins(:content)
.where(wiki_id: page.wiki_id) .where(wiki_id: page.wiki_id)
.where("#{WikiContent.table_name}.updated_on > ?", User.current.today - days) .where("#{WikiContent.table_name}.updated_on > ?", User.current.today - days)
.order("#{WikiContent.table_name}.updated_on desc") .order("#{WikiContent.table_name}.updated_on desc")
pages = pages.visible User.current, project: project if pages.respond_to? :visible pages = pages.visible User.current, project: project if pages.respond_to? :visible
s = [] s = []
date = nil date = nil
pages.each do |page_raw| pages.each do |page_raw|
content = page_raw.content content = page_raw.content
updated_on = Date.new content.updated_on.year, content.updated_on.month, content.updated_on.day updated_on = Date.new content.updated_on.year, content.updated_on.month, content.updated_on.day
if date != updated_on if date != updated_on
date = updated_on date = updated_on
s << tag.strong(format_date(date)) s << tag.strong(format_date(date))
s << tag.br
end
s << link_to(content.page.pretty_title,
controller: 'wiki', action: 'show', project_id: content.page.project, id: content.page.title)
s << tag.br s << tag.br
end end
s << link_to(content.page.pretty_title, tag.div safe_join(s), class: 'recently-updated'
controller: 'wiki', action: 'show', project_id: content.page.project, id: content.page.title)
s << tag.br
end end
tag.div safe_join(s), class: 'recently-updated'
end end
end end
end end

View File

@@ -2,34 +2,36 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module RedditMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Creates link to reddit. desc <<-DESCRIPTION
{{reddit(name)}} Creates link to reddit.
DESCRIPTION {{reddit(name)}}
DESCRIPTION
macro :reddit do |_obj, args| macro :reddit do |_obj, args|
raise 'The correct usage is {{reddit(<name>)}}' if args.empty? raise 'The correct usage is {{reddit(<name>)}}' if args.empty?
name = args[0].strip name = args[0].strip
case name[0..1] case name[0..1]
when 'r/' when 'r/'
link_to font_awesome_icon('fab_reddit', post_text: name), link_to font_awesome_icon('fab_reddit', post_text: name),
"https://www.reddit.com/#{name}", "https://www.reddit.com/#{name}",
class: 'external reddit', class: 'external reddit',
title: l(:label_reddit_subject) title: l(:label_reddit_subject)
when 'u/' when 'u/'
link_to font_awesome_icon('fab_reddit-square', post_text: name), link_to font_awesome_icon('fab_reddit-square', post_text: name),
"https://www.reddit.com/username/#{name[2..]}", "https://www.reddit.com/username/#{name[2..]}",
class: 'external reddit', class: 'external reddit',
title: l(:label_reddit_user_account) title: l(:label_reddit_user_account)
else else
name = "r/#{name}" name = "r/#{name}"
link_to font_awesome_icon('fab_reddit', post_text: name), link_to font_awesome_icon('fab_reddit', post_text: name),
"https://www.reddit.com/#{name}", "https://www.reddit.com/#{name}",
class: 'external reddit', class: 'external reddit',
title: l(:label_reddit_subject) title: l(:label_reddit_subject)
end
end end
end end
end end

View File

@@ -2,41 +2,43 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module RedmineIssueMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Creates link to redmine.org issue. desc <<-DESCRIPTION
{{redmine_issue(1448)}} Creates link to redmine.org issue.
DESCRIPTION {{redmine_issue(1448)}}
DESCRIPTION
macro :redmine_issue do |_obj, args| macro :redmine_issue do |_obj, args|
raise 'The correct usage is {{redmine_issue(<id>)}}' if args.empty? raise 'The correct usage is {{redmine_issue(<id>)}}' if args.empty?
args, options = extract_macro_options args, :title args, options = extract_macro_options args, :title
raw_link = args[0].to_s.strip raw_link = args[0].to_s.strip
if !/\A\d+\z/.match(raw_link[0]) if !/\A\d+\z/.match(raw_link[0])
# https://www.redmine.org/issues/12066#note-7 # https://www.redmine.org/issues/12066#note-7
if raw_link =~ %r{redmine.org/issues/([0-9].+?)#(.*)} || if raw_link =~ %r{redmine.org/issues/([0-9].+?)#(.*)} ||
raw_link =~ %r{redmine.org/issues/([0-9].+)} raw_link =~ %r{redmine.org/issues/([0-9].+)}
link_name = Regexp.last_match 1
link = raw_link.gsub 'http://', 'https://'
else
raise 'The correct usage is {{redmine_issue(<id>)}}'
end
elsif raw_link =~ /([0-9].+?)\D/
# ID with parameters
link_name = Regexp.last_match 1 link_name = Regexp.last_match 1
link = raw_link.gsub 'http://', 'https://' link = "https://www.redmine.org/issues/#{raw_link}"
else else
raise 'The correct usage is {{redmine_issue(<id>)}}' # just ID
link_name = raw_link
link = "https://www.redmine.org/issues/#{raw_link}"
end end
elsif raw_link =~ /([0-9].+?)\D/
# ID with parameters link_options = { class: 'external redmine-link' }
link_name = Regexp.last_match 1 link_options[:title] = options[:title].presence || l(:label_redmine_org_issue)
link = "https://www.redmine.org/issues/#{raw_link}"
else link_to "##{link_name}", link, link_options
# just ID
link_name = raw_link
link = "https://www.redmine.org/issues/#{raw_link}"
end end
link_options = { class: 'external redmine-link' }
link_options[:title] = options[:title].presence || l(:label_redmine_org_issue)
link_to "##{link_name}", link, link_options
end end
end end
end end

View File

@@ -2,36 +2,38 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module RedmineWikiMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Creates link to redmine.org wiki page. desc <<-DESCRIPTION
{{redmine_wiki(Installing Redmine)}} Creates link to redmine.org wiki page.
DESCRIPTION {{redmine_wiki(Installing Redmine)}}
DESCRIPTION
macro :redmine_wiki do |_obj, args| macro :redmine_wiki do |_obj, args|
raise 'The correct usage is {{redmine_wiki(<page>)}}' if args.empty? raise 'The correct usage is {{redmine_wiki(<page>)}}' if args.empty?
args, options = extract_macro_options args, :title, :name args, options = extract_macro_options args, :title, :name
raw_link = args[0].to_s.strip raw_link = args[0].to_s.strip
if raw_link[0..3] == 'http' if raw_link[0..3] == 'http'
start_pos = raw_link.index 'redmine.org/projects/redmine/wiki/' start_pos = raw_link.index 'redmine.org/projects/redmine/wiki/'
raise 'The correct usage is {{redmine_wiki(<page>)}}' if start_pos.nil? || start_pos.zero? raise 'The correct usage is {{redmine_wiki(<page>)}}' if start_pos.nil? || start_pos.zero?
options[:name] = raw_link[(start_pos + 34)..] if options[:name].blank? options[:name] = raw_link[(start_pos + 34)..] if options[:name].blank?
link = raw_link.gsub 'http://', 'https://' link = raw_link.gsub 'http://', 'https://'
elsif /\w/.match?(raw_link[0]) elsif /\w/.match?(raw_link[0])
options[:name] = raw_link if options[:name].blank? options[:name] = raw_link if options[:name].blank?
link = "https://www.redmine.org/projects/redmine/wiki/#{Wiki.titleize raw_link}" link = "https://www.redmine.org/projects/redmine/wiki/#{Wiki.titleize raw_link}"
else else
raise 'The correct usage is {{redmine_wiki(<page>)}}' raise 'The correct usage is {{redmine_wiki(<page>)}}'
end
link_options = { class: 'external redmine-link' }
link_options[:title] = options[:title].presence || l(:label_redmine_org_wiki)
link_to options[:name], link, link_options
end end
link_options = { class: 'external redmine-link' }
link_options[:title] = options[:title].presence || l(:label_redmine_org_wiki)
link_to options[:name], link, link_options
end end
end end
end end

View File

@@ -2,35 +2,37 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module SlideshareMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Slideshare macro to include Slideshare slide. desc <<-DESCRIPTION
Slideshare macro to include Slideshare slide.
Syntax: Syntax:
{{slideshare(<key> [, width=595, height=485, slide=SLIDE])}} {{slideshare(<key> [, width=595, height=485, slide=SLIDE])}}
Examples: Examples:
{{slideshare(57941706)}} show slideshare slide with default size 595x485 {{slideshare(57941706)}} show slideshare slide with default size 595x485
{{slideshare(57941706, width=514, height=422)}} show slide with user defined size {{slideshare(57941706, width=514, height=422)}} show slide with user defined size
{{slideshare(57941706, slide=5)}} start with slide (page) 5 {{slideshare(57941706, slide=5)}} start with slide (page) 5
DESCRIPTION DESCRIPTION
macro :slideshare do |_obj, args| macro :slideshare do |_obj, args|
args, options = extract_macro_options args, :width, :height, :slide args, options = extract_macro_options args, :width, :height, :slide
width = options[:width].presence || 595 width = options[:width].presence || 595
height = options[:height].presence || 485 height = options[:height].presence || 485
slide = options[:slide].present? ? options[:slide].to_i : 0 slide = options[:slide].present? ? options[:slide].to_i : 0
raise 'The correct usage is {{slideshare(<key>[, width=x, height=y, slide=number])}}' if args.empty? raise 'The correct usage is {{slideshare(<key>[, width=x, height=y, slide=number])}}' if args.empty?
v = args[0] v = args[0]
src = +"//www.slideshare.net/slideshow/embed_code/#{v}" src = +"//www.slideshare.net/slideshow/embed_code/#{v}"
src += "?startSlide=#{slide}" if slide.positive? src += "?startSlide=#{slide}" if slide.positive?
tag.iframe width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true' tag.iframe width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true'
end
end end
end end
end end

View File

@@ -3,36 +3,38 @@
# see https://www.tradingview.com/widget/ # see https://www.tradingview.com/widget/
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module TradingviewMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Creates Tradingview chart desc <<-DESCRIPTION
{{tradingview(options)}} Creates Tradingview chart
see https://additionals.readthedocs.io/en/latest/macros/#tradingview {{tradingview(options)}}
DESCRIPTION see https://additionals.readthedocs.io/en/latest/macros/#tradingview
DESCRIPTION
macro :tradingview do |_obj, args| macro :tradingview do |_obj, args|
raise 'The correct usage is {{tradingview(options)}}' if args.empty? raise 'The correct usage is {{tradingview(options)}}' if args.empty?
_args, options = extract_macro_options(args, :width, :height, :symbol, :interval, :timezone, _args, options = extract_macro_options(args, :width, :height, :symbol, :interval, :timezone,
:theme, :style, :locale, :toolbar_bg, :enable_publishing, :theme, :style, :locale, :toolbar_bg, :enable_publishing,
:allow_symbol_change, :hideideasbutton) :allow_symbol_change, :hideideasbutton)
options[:width] = 640 if options[:width].blank? options[:width] = 640 if options[:width].blank?
options[:height] = 480 if options[:height].blank? options[:height] = 480 if options[:height].blank?
options[:symbol] = 'NASDAQ:AAPL' if options[:symbol].blank? options[:symbol] = 'NASDAQ:AAPL' if options[:symbol].blank?
options[:interval] = 'W' if options[:interval].blank? options[:interval] = 'W' if options[:interval].blank?
options[:timezone] = 'Europe/Berlin' if options[:timezone].blank? options[:timezone] = 'Europe/Berlin' if options[:timezone].blank?
options[:theme] = 'White' if options[:theme].blank? options[:theme] = 'White' if options[:theme].blank?
options[:style] = 2 if options[:style].blank? options[:style] = 2 if options[:style].blank?
options[:locale] = 'de' if options[:locale].blank? options[:locale] = 'de' if options[:locale].blank?
options[:toolbar_bg] = '#f1f3f6' if options[:toolbar_bg].blank? options[:toolbar_bg] = '#f1f3f6' if options[:toolbar_bg].blank?
options[:enable_publishing] = false if options[:enable_publishing].blank? options[:enable_publishing] = false if options[:enable_publishing].blank?
options[:allow_symbol_change] = true if options[:allow_symbol_change].blank? options[:allow_symbol_change] = true if options[:allow_symbol_change].blank?
options[:hideideasbutton] = true if options[:hideideasbutton].blank? options[:hideideasbutton] = true if options[:hideideasbutton].blank?
render partial: 'wiki/tradingview', render partial: 'wiki/tradingview',
formats: [:html], formats: [:html],
locals: { options: options } locals: { options: options }
end
end end
end end
end end

View File

@@ -2,32 +2,34 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module TwitterMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Creates link to twitter account page or topic. desc <<-DESCRIPTION
{{twitter(name)}} Creates link to twitter account page or topic.
DESCRIPTION {{twitter(name)}}
DESCRIPTION
macro :twitter do |_obj, args| macro :twitter do |_obj, args|
raise 'The correct usage is {{twitter(<name>)}}' if args.empty? raise 'The correct usage is {{twitter(<name>)}}' if args.empty?
name = args[0].strip name = args[0].strip
case name[0] case name[0]
when '@' when '@'
link_to(font_awesome_icon('fab_twitter', post_text: name), link_to(font_awesome_icon('fab_twitter', post_text: name),
"https://twitter.com/#{name[1..]}", "https://twitter.com/#{name[1..]}",
class: 'external twitter', class: 'external twitter',
title: l(:label_twitter_account)) title: l(:label_twitter_account))
when '#' when '#'
link_to(font_awesome_icon('fab_twitter-square', post_text: name), link_to(font_awesome_icon('fab_twitter-square', post_text: name),
"https://twitter.com/hashtag/#{name[1..]}", "https://twitter.com/hashtag/#{name[1..]}",
class: 'external twitter', class: 'external twitter',
title: l(:label_twitter_hashtag)) title: l(:label_twitter_hashtag))
else else
link_to(font_awesome_icon('fab_twitter', post_text: " @#{name}"), link_to(font_awesome_icon('fab_twitter', post_text: " @#{name}"),
"https://twitter.com/#{name}", "https://twitter.com/#{name}",
class: 'external twitter', class: 'external twitter',
title: l(:label_twitter_account)) title: l(:label_twitter_account))
end
end end
end end
end end

View File

@@ -2,61 +2,63 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module UserMacro
desc "Display link to user profile\n\n" \ Redmine::WikiFormatting::Macros.register do
"Syntax:\n\n" \ desc "Display link to user profile\n\n" \
"{{user(USER_NAME [, format=USER_FORMAT, text=BOOL], avatar=BOOL])}}\n\n" \ "Syntax:\n\n" \
"USER_NAME can be user id or user name (login name)\n" \ "{{user(USER_NAME [, format=USER_FORMAT, text=BOOL], avatar=BOOL])}}\n\n" \
"USER_FORMATS\n" \ "USER_NAME can be user id or user name (login name)\n" \
"- system (use system settings) (default)\n- " \ "USER_FORMATS\n" \
"#{User::USER_FORMATS.keys.join "\n- "}\n\n" \ "- system (use system settings) (default)\n- " \
"Examples:\n\n" \ "#{User::USER_FORMATS.keys.join "\n- "}\n\n" \
"{{user(1)}}\n" \ "Examples:\n\n" \
"...Link to user with user id 1\n\n" \ "{{user(1)}}\n" \
"{{user(1, avatar=true)}}\n" \ "...Link to user with user id 1\n\n" \
"...Link to user with user id 1 with avatar\n\n" \ "{{user(1, avatar=true)}}\n" \
"{{user(current_user, text=true)}}\n" \ "...Link to user with user id 1 with avatar\n\n" \
"...Show only user (without link) of the current user\n\n" \ "{{user(current_user, text=true)}}\n" \
"{{user(admin)}}\n" \ "...Show only user (without link) of the current user\n\n" \
"...Link to user with username 'admin'\n\n" \ "{{user(admin)}}\n" \
"{{user(admin, format=firstname)}}\n" \ "...Link to user with username 'admin'\n\n" \
"...Link to user with username 'admin' and show firstname as link text" "{{user(admin, format=firstname)}}\n" \
"...Link to user with username 'admin' and show firstname as link text"
macro :user do |_obj, args| macro :user do |_obj, args|
args, options = extract_macro_options args, :format, :avatar, :text args, options = extract_macro_options args, :format, :avatar, :text
raise 'The correct usage is {{user(<user_id or username>, format=USER_FORMAT)}}' if args.empty? raise 'The correct usage is {{user(<user_id or username>, format=USER_FORMAT)}}' if args.empty?
user_id = args[0] user_id = args[0]
user = User.find_by id: user_id user = User.find_by id: user_id
user ||= if user_id == 'current_user' user ||= if user_id == 'current_user'
User.current User.current
else
User.find_by login: user_id
end
return if user.nil?
name = if options[:format].blank?
user.name
else else
User.find_by login: user_id user.name options[:format].to_sym
end end
return if user.nil? s = []
if options[:avatar].present? && options[:avatar]
s << avatar(user, size: 14)
s << ' '
end
name = if options[:format].blank? link_css = "macro #{user.css_classes}"
user.name
s << if user.active? && (options[:text].blank? || !options[:text])
link_to h(name), user_url(user, only_path: controller_path != 'mailer'), class: link_css
else else
user.name options[:format].to_sym tag.span h(name), class: link_css
end end
safe_join s
s = []
if options[:avatar].present? && options[:avatar]
s << avatar(user, size: 14)
s << ' '
end end
link_css = "macro #{user.css_classes}"
s << if user.active? && (options[:text].blank? || !options[:text])
link_to h(name), user_url(user, only_path: controller_path != 'mailer'), class: link_css
else
tag.span h(name), class: link_css
end
safe_join s
end end
end end
end end

View File

@@ -2,36 +2,38 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module VimeoMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Vimeo macro to include vimeo video. desc <<-DESCRIPTION
Vimeo macro to include vimeo video.
Syntax: Syntax:
{{vimeo(<video key> [, width=640, height=360, autoplay=BOOL])}} {{vimeo(<video key> [, width=640, height=360, autoplay=BOOL])}}
Examples: Examples:
{{vimeo(142849533)}} show video with default size 640x360 {{vimeo(142849533)}} show video with default size 640x360
{{vimeo(142849533, width=853, height=480)}} show video with user defined size {{vimeo(142849533, width=853, height=480)}} show video with user defined size
{{vimeo(142849533, autoplay=true)}} autoplay video {{vimeo(142849533, autoplay=true)}} autoplay video
DESCRIPTION DESCRIPTION
macro :vimeo do |_obj, args| macro :vimeo do |_obj, args|
args, options = extract_macro_options args, :width, :height, :autoplay args, options = extract_macro_options args, :width, :height, :autoplay
width = options[:width].presence || 640 width = options[:width].presence || 640
height = options[:height].presence || 360 height = options[:height].presence || 360
raise 'The correct usage is {{vimeo(<video key>[, width=x, height=y])}}' if args.empty? raise 'The correct usage is {{vimeo(<video key>[, width=x, height=y])}}' if args.empty?
v = args[0] v = args[0]
src = if Additionals.true? options[:autoplay] src = if Additionals.true? options[:autoplay]
"//player.vimeo.com/video/#{v}?autoplay=1" "//player.vimeo.com/video/#{v}?autoplay=1"
else else
"//player.vimeo.com/video/#{v}" "//player.vimeo.com/video/#{v}"
end end
tag.iframe width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true' tag.iframe width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true'
end
end end
end end
end end

View File

@@ -2,36 +2,38 @@
module Additionals module Additionals
module WikiMacros module WikiMacros
Redmine::WikiFormatting::Macros.register do module YoutubeMacro
desc <<-DESCRIPTION Redmine::WikiFormatting::Macros.register do
Youtube macro to include youtube video. desc <<-DESCRIPTION
Youtube macro to include youtube video.
Syntax: Syntax:
{{youtube(<video key> [, width=640, height=360, autoplay=BOOL])}} {{youtube(<video key> [, width=640, height=360, autoplay=BOOL])}}
Examples: Examples:
{{youtube(KMU0tzLwhbE)}} show video with default size 640x360 {{youtube(KMU0tzLwhbE)}} show video with default size 640x360
{{youtube(KMU0tzLwhbE, width=853, height=480)}} show video with user defined size {{youtube(KMU0tzLwhbE, width=853, height=480)}} show video with user defined size
{{youtube(KMU0tzLwhbE, autoplay=true)}} autoplay video {{youtube(KMU0tzLwhbE, autoplay=true)}} autoplay video
DESCRIPTION DESCRIPTION
macro :youtube do |_obj, args| macro :youtube do |_obj, args|
args, options = extract_macro_options args, :width, :height, :autoplay args, options = extract_macro_options args, :width, :height, :autoplay
width = options[:width].presence || 640 width = options[:width].presence || 640
height = options[:height].presence || 360 height = options[:height].presence || 360
raise 'The correct usage is {{youtube(<video key>[, width=x, height=y])}}' if args.empty? raise 'The correct usage is {{youtube(<video key>[, width=x, height=y])}}' if args.empty?
v = args[0] v = args[0]
src = if Additionals.true? options[:autoplay] src = if Additionals.true? options[:autoplay]
"//www.youtube.com/embed/#{v}?autoplay=1" "//www.youtube.com/embed/#{v}?autoplay=1"
else else
"//www.youtube-nocookie.com/embed/#{v}" "//www.youtube-nocookie.com/embed/#{v}"
end end
tag.iframe width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true' tag.iframe width: width, height: height, src: src, frameborder: 0, allowfullscreen: 'true'
end
end end
end end
end end