Working on zeitwerk support
This commit is contained in:
parent
fbece21051
commit
1c23f13ec7
@ -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
|
||||
|
||||
|
@ -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' }
|
||||
|
2
assets/javascripts/mermaid.min.js
vendored
2
assets/javascripts/mermaid.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -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).
|
||||
|
8
init.rb
8
init.rb
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
7
lib/additionals/plugin_version.rb
Normal file
7
lib/additionals/plugin_version.rb
Normal file
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Additionals
|
||||
module PluginVersion
|
||||
VERSION = '3.0.4-master'
|
||||
end
|
||||
end
|
@ -1,5 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Additionals
|
||||
VERSION = '3.0.4-master' unless defined? VERSION
|
||||
end
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user