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
+++++
- Mermaid 8.13.3 support
- Mermaid 8.13.4 support
- D3 7.1.1 support
- Ruby 2.6 is required

View File

@ -2,11 +2,11 @@
lib = File.expand_path '../lib', __FILE__
$LOAD_PATH.unshift lib unless $LOAD_PATH.include? lib
require 'additionals/version'
require 'additionals/plugin_version'
Gem::Specification.new do |spec|
spec.name = 'additionals'
spec.version = Additionals::VERSION
spec.version = Additionals::PluginVersion::VERSION
spec.authors = ['AlphaNodes']
spec.email = ['alex@alphanodes.com']
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/>`_
* `d3plus v2.0.0-alpha.30 <https://d3plus.org/>`_
* `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/>`_
And a set of various Rails helper methods (see below).

View File

@ -4,7 +4,7 @@ Redmine::Plugin.register :additionals do
name 'Additionals'
author 'AlphaNodes GmbH'
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/'
url 'https://github.com/alphanodes/additionals'
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
end
Rails.configuration.to_prepare do
Additionals.setup
if Rails.version > '6.0'
ActiveSupport.on_load(:active_record) { Additionals.setup }
else
Rails.configuration.to_prepare { Additionals.setup }
end

View File

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

View File

@ -1,49 +1,52 @@
# frozen_string_literal: true
module Additionals
class AdditionalsHookListener < Redmine::Hook::ViewListener
include IssuesHelper
include AdditionalsIssuesHelper
module Hooks
class AdditionalsHookListener < Redmine::Hook::ViewListener
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_body_top, partial: 'additionals/body_top'
render_on :view_layouts_base_body_bottom, partial: 'additionals/body_bottom'
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_bottom, partial: 'additionals/body_bottom'
render_on :view_account_login_bottom, partial: 'login_text'
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_form_details_bottom, partial: 'change_author'
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_queries_bottom, partial: 'issues/additionals_sidebar_queries'
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_show_contextual, partial: 'users/additionals_contextual'
render_on :view_wiki_show_sidebar_bottom, partial: 'wiki/additionals_sidebar'
render_on :view_account_login_bottom, partial: 'login_text'
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_form_details_bottom, partial: 'change_author'
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_queries_bottom, partial: 'issues/additionals_sidebar_queries'
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_show_contextual, partial: 'users/additionals_contextual'
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 = {})
detail = context[:detail]
return unless detail.prop_key == 'author_id'
def helper_issues_show_detail_after_setting(context = {})
detail = context[:detail]
return unless detail.prop_key == 'author_id'
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
end
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
end
def view_layouts_base_content(context = {})
controller = context[:controller]
return if controller.nil?
def view_layouts_base_content(context = {})
controller = context[:controller]
return if controller.nil?
controller_name = context[:controller].params[:controller]
action_name = context[:controller].params[:action]
controller_name = context[:controller].params[:controller]
action_name = context[:controller].params[:action]
return if controller_name == 'account' && action_name == 'login' ||
controller_name == 'my' ||
controller_name == 'account' && action_name == 'lost_password' ||
!Additionals.setting?(:add_go_to_top)
return if controller_name == 'account' && action_name == 'login' ||
controller_name == 'my' ||
controller_name == 'account' && action_name == 'lost_password' ||
!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

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 WikiMacros
Redmine::WikiFormatting::Macros.register do
desc 'asciinema embed'
module AsciinemaMacro
Redmine::WikiFormatting::Macros.register do
desc 'asciinema embed'
macro :asciinema do |_obj, args|
raise 'The correct usage is {{asciinema(<cast_id>)}}' if args.empty?
macro :asciinema do |_obj, args|
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

View File

@ -4,86 +4,88 @@
# see https://www.cryptocompare.com/dev/widget/wizard/
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Create CryptoCompare information.
{{cryptocompare(options)}}
see https://additionals.readthedocs.io/en/latest/macros/#cryptocompare
DESCRIPTION
module CryptocompareMacro
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Create CryptoCompare information.
{{cryptocompare(options)}}
see https://additionals.readthedocs.io/en/latest/macros/#cryptocompare
DESCRIPTION
macro :cryptocompare do |_obj, args|
raise 'The correct usage is {{cryptocompare(options)}}' if args.empty?
macro :cryptocompare do |_obj, args|
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[:tsym] = 'EUR' if options[:tsym].blank?
options[:fsym] = 'BTC' if options[:fsym].blank?
options[:tsym] = 'EUR' if options[:tsym].blank?
if options[:type].blank?
widget_type = 'chart'
else
widget_type = options[:type]
options.delete :type
if options[:type].blank?
widget_type = 'chart'
else
widget_type = options[: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
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

View File

@ -2,69 +2,71 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Show date.
module DateMacro
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Show date.
Syntax:
Syntax:
{{date([TYPE])}}
TYPE
- current_date current date (default)
- current_date_with_time current date with time
- current_year current year
- current_month current month
- current_day current day
- current_hour current hour
- current_minute current minute
- current_weekday current weekday
- 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
{{date([TYPE])}}
TYPE
- current_date current date (default)
- current_date_with_time current date with time
- current_year current year
- current_month current month
- current_day current day
- current_hour current hour
- current_minute current minute
- current_weekday current weekday
- 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
Examples:
Examples:
{{date}}
...show current date
{{date(current_year)}}
...show current year
{{date(current_month)}}
...show current month
{{date(current_weeknumber)}}
...show current week number
DESCRIPTION
{{date}}
...show current date
{{date(current_year)}}
...show current year
{{date(current_month)}}
...show current month
{{date(current_weeknumber)}}
...show current week number
DESCRIPTION
macro :date do |_obj, args|
type = if args.present?
args[0]
else
'current_date'
end
macro :date do |_obj, args|
type = if args.present?
args[0]
else
'current_date'
end
d = Additionals.now_with_user_time_zone
date_result = case type
when 'current_date'
format_date User.current.today
when 'current_date_with_time'
format_time d, true
when 'current_year'
d.year
when 'current_month'
d.month
when 'current_day'
d.day
when 'current_hour'
d.hour
when 'current_minute'
d.min
when 'current_weekday'
day_name d.wday
when 'current_weeknumber'
User.current.today.cweek
else
format_date type.to_date
end
d = Additionals.now_with_user_time_zone
date_result = case type
when 'current_date'
format_date User.current.today
when 'current_date_with_time'
format_time d, true
when 'current_year'
d.year
when 'current_month'
d.month
when 'current_day'
d.day
when 'current_hour'
d.hour
when 'current_minute'
d.min
when 'current_weekday'
day_name d.wday
when 'current_weeknumber'
User.current.today.cweek
else
format_date type.to_date
end
tag.span date_result, class: 'current-date'
tag.span date_result, class: 'current-date'
end
end
end
end

View File

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

View File

@ -2,13 +2,15 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc 'gist embed'
module GistMacro
Redmine::WikiFormatting::Macros.register do
desc 'gist embed'
macro :gist do |_obj, args|
raise 'The correct usage is {{gist(<gist_id>)}}' if args.empty?
macro :gist do |_obj, args|
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

View File

@ -2,88 +2,90 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Display a google map. Examples:
module GmapMacro
Redmine::WikiFormatting::Macros.register do
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
DESCRIPTION
{{gmap(mode=directions, origin=Munich+Rosenheimerstr, destination=Arco)}} Direction from Munich to Arco
DESCRIPTION
macro :gmap do |_obj, args|
src_options = %i[attribution_ios_deep_link_id
attribution_source
attribution_web_url
avoid
center
destination
fov
heading
language
location
maptype
origin
pano
pitch
region
units
waypoints
zoom]
macro :gmap do |_obj, args|
src_options = %i[attribution_ios_deep_link_id
attribution_source
attribution_web_url
avoid
center
destination
fov
heading
language
location
maptype
origin
pano
pitch
region
units
waypoints
zoom]
args, options = extract_macro_options(args,
:mode,
:width,
:height,
:attribution_ios_deep_link_id,
:attribution_source,
:attribution_web_url,
:avoid,
:center,
:destination,
:fov,
:heading,
:language,
:location,
:maptype,
:origin,
:pano,
:pitch,
:region,
:units,
:way_mode,
:waypoints,
:zoom)
args, options = extract_macro_options(args,
:mode,
:width,
:height,
:attribution_ios_deep_link_id,
:attribution_source,
:attribution_web_url,
:avoid,
:center,
:destination,
:fov,
:heading,
:language,
:location,
:maptype,
:origin,
:pano,
:pitch,
:region,
:units,
:way_mode,
:waypoints,
: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
height = options[:height].presence || 350
mode = options[:mode].presence || 'search'
width = options[:width].presence || 620
height = options[:height].presence || 350
mode = options[:mode].presence || 'search'
if mode == 'search' && options[:q].blank? && args.empty?
raise 'The correct usage is {{gmap([q=QUERY, mode=MODE, widths=x, height=y])}}'
if mode == 'search' && options[:q].blank? && args.empty?
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
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

View File

@ -2,53 +2,55 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Google docs macro to include Google documents.
module GoogleDocsMacro
Redmine::WikiFormatting::Macros.register do
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, width=514, height=422)}
DESCRIPTION
{{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)}
DESCRIPTION
macro :google_docs do |_obj, args|
args, options = extract_macro_options args, :width, :height, :edit_link
macro :google_docs do |_obj, args|
args, options = extract_macro_options args, :width, :height, :edit_link
width = options[:width].presence || '100%'
height = options[:height].presence || 485
width = options[:width].presence || '100%'
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
unless src.include? '?'
src << if src.include? 'edit'
'?rm=minimal'
else
'?widget=true&headers=false'
end
src = v.dup
unless src.include? '?'
src << if src.include? 'edit'
'?rm=minimal'
else
'?widget=true&headers=false'
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
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

View File

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

View File

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

View File

@ -2,39 +2,41 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Displays a date that updated the page.
{{last_updated_at}}
{{last_updated_at(project_name, wiki_page)}}
{{last_updated_at(project_identifier, wiki_page)}}
DESCRIPTION
module LastUpdatedAtMacro
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Displays a date that updated the page.
{{last_updated_at}}
{{last_updated_at(project_name, wiki_page)}}
{{last_updated_at(project_identifier, wiki_page)}}
DESCRIPTION
macro :last_updated_at do |obj, args|
return '' unless @project
macro :last_updated_at do |obj, args|
return '' unless @project
if args.empty?
page = obj
else
raise '{{last_updated_at(project_identifier, wiki_page)}}' if args.length < 2
if args.empty?
page = obj
else
raise '{{last_updated_at(project_identifier, wiki_page)}}' if args.length < 2
project_name = args[0].strip
page_name = args[1].strip
project = Project.find_by name: project_name
project ||= Project.find_by identifier: project_name
return unless project
project_name = args[0].strip
page_name = args[1].strip
project = Project.find_by name: project_name
project ||= Project.find_by identifier: project_name
return unless project
wiki = Wiki.find_by project_id: project.id
return unless wiki
wiki = Wiki.find_by project_id: project.id
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
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

View File

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

View File

@ -2,77 +2,79 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Display members.
module MemberMacro
Redmine::WikiFormatting::Macros.register do
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}}
...List all members for all projects (with the current user permission)
{{members}}
...List all members for all projects (with the current user permission)
{{members(with_sum=true)}}
...List all members for all projects and show title with amount of members
{{members(with_sum=true)}}
...List all members for all projects and show title with amount of members
{{members(the-identifier)}}
...A box showing all members for the project with the identifier of 'the-identifier'
{{members(the-identifier)}}
...A box showing all members for the project with the identifier of 'the-identifier'
{{members(the-identifier, role=Manager)}}
...A box showing all members for the project with the identifier of 'the-identifier', which
have the role "Manager"
{{members(the-identifier, role=Manager)}}
...A box showing all members for the project with the identifier of 'the-identifier', which
have the role "Manager"
{{members(the-identifier, title=My user list)}}
...A box showing all members for the project with the identifier of 'the-identifier' and with
box title "My user list"
DESCRIPTION
{{members(the-identifier, title=My user list)}}
...A box showing all members for the project with the identifier of 'the-identifier' and with
box title "My user list"
DESCRIPTION
macro :members do |_obj, args|
args, options = extract_macro_options args, :role, :title, :with_sum
macro :members do |_obj, args|
args, options = extract_macro_options args, :role, :title, :with_sum
project_id = args[0]
user_roles = []
project_id = args[0]
user_roles = []
if project_id.present?
project_id.strip!
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?
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?
principals = project.visible_users
return if principals.nil?
principals = project.visible_users
return if principals.nil?
users = []
principals.each do |principal|
next unless principal.type == 'User'
users = []
principals.each do |principal|
next unless principal.type == 'User'
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])
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])
end
else
users = User.visible
.where(type: 'User')
.active
.sorted
end
else
users = User.visible
.where(type: 'User')
.active
.sorted
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
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

View File

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

View File

@ -2,60 +2,62 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Create a link for "New issue" for the current user.
module NewIssueMacro
Redmine::WikiFormatting::Macros.register do
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
has permission to create an issue.
If no PROJECT_NAME is specified, first project is used, which the current user
has permission to create an issue.
Examples:
Examples:
{{new_issue}}
...Link to create new issue in first available project
{{new_issue(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)}}
...Link to create new issue in project with the identifier of 'the-identifier'
and the name 'New issue for broken displays'
DESCRIPTION
{{new_issue}}
...Link to create new issue in first available project
{{new_issue(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)}}
...Link to create new issue in project with the identifier of 'the-identifier'
and the name 'New issue for broken displays'
DESCRIPTION
macro :new_issue do |_obj, args|
if args.any?
args, options = extract_macro_options(args, *additionals_titles_for_locale(:name))
i18n_name = additionals_i18n_title options, :name
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?
macro :new_issue do |_obj, args|
if args.any?
args, options = extract_macro_options(args, *additionals_titles_for_locale(:name))
i18n_name = additionals_i18n_title options, :name
project_id = args[0]
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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,36 +2,38 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Creates link to redmine.org wiki page.
{{redmine_wiki(Installing Redmine)}}
DESCRIPTION
module RedmineWikiMacro
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Creates link to redmine.org wiki page.
{{redmine_wiki(Installing Redmine)}}
DESCRIPTION
macro :redmine_wiki do |_obj, args|
raise 'The correct usage is {{redmine_wiki(<page>)}}' if args.empty?
macro :redmine_wiki do |_obj, args|
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'
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?
if raw_link[0..3] == 'http'
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?
options[:name] = raw_link[(start_pos + 34)..] if options[:name].blank?
link = raw_link.gsub 'http://', 'https://'
elsif /\w/.match?(raw_link[0])
options[:name] = raw_link if options[:name].blank?
link = "https://www.redmine.org/projects/redmine/wiki/#{Wiki.titleize raw_link}"
else
raise 'The correct usage is {{redmine_wiki(<page>)}}'
options[:name] = raw_link[(start_pos + 34)..] if options[:name].blank?
link = raw_link.gsub 'http://', 'https://'
elsif /\w/.match?(raw_link[0])
options[:name] = raw_link if options[:name].blank?
link = "https://www.redmine.org/projects/redmine/wiki/#{Wiki.titleize raw_link}"
else
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
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

View File

@ -2,35 +2,37 @@
module Additionals
module WikiMacros
Redmine::WikiFormatting::Macros.register do
desc <<-DESCRIPTION
Slideshare macro to include Slideshare slide.
module SlideshareMacro
Redmine::WikiFormatting::Macros.register do
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, width=514, height=422)}} show slide with user defined size
{{slideshare(57941706, slide=5)}} start with slide (page) 5
DESCRIPTION
{{slideshare(57941706)}} show slideshare slide with default size 595x485
{{slideshare(57941706, width=514, height=422)}} show slide with user defined size
{{slideshare(57941706, slide=5)}} start with slide (page) 5
DESCRIPTION
macro :slideshare do |_obj, args|
args, options = extract_macro_options args, :width, :height, :slide
macro :slideshare do |_obj, args|
args, options = extract_macro_options args, :width, :height, :slide
width = options[:width].presence || 595
height = options[:height].presence || 485
slide = options[:slide].present? ? options[:slide].to_i : 0
width = options[:width].presence || 595
height = options[:height].presence || 485
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]
src = +"//www.slideshare.net/slideshow/embed_code/#{v}"
src += "?startSlide=#{slide}" if slide.positive?
v = args[0]
src = +"//www.slideshare.net/slideshow/embed_code/#{v}"
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

View File

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

View File

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

View File

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

View File

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

View File

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