Skip to content

Commit 09e2e6d

Browse files
committed
Extract shared static-macro label composition
Reviewer feedback on cd122f8: the `parts << status / type / label` block was duplicated between the regex-driven (`WorkPackages` link handler) and envelope-driven (`MentionFilter`) static paths, with no guard against silent desynchronisation. Centralise the composition on the link handler and document why the two callers pass different labels — the regex path preserves the alias-as-matched, the envelope path normalises to the WP's current formatted_id.
1 parent cd122f8 commit 09e2e6d

2 files changed

Lines changed: 24 additions & 18 deletions

File tree

lib/open_project/text_formatting/filters/mention_filter.rb

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,14 @@ def work_package_quickinfo(work_package, detailed:)
134134

135135
# Static fallback shared with the PatternMatcherFilter's `##`/`###`
136136
# path so envelope-driven and text-driven references render the same
137-
# shape in channels that cannot hydrate the custom element.
137+
# shape in channels that cannot hydrate the custom element. Always
138+
# uses the WP's current `formatted_id`, normalising any historical
139+
# alias the envelope may have been authored with.
138140
def work_package_static_macro(work_package, detailed:)
139-
parts = []
140-
parts << work_package.status&.name if detailed
141-
parts << work_package.type&.name
142-
parts << work_package.formatted_id
143-
link_text = "#{parts.compact.join(' ')}: #{work_package.subject}"
141+
label = OpenProject::TextFormatting::Matchers::LinkHandlers::WorkPackages
142+
.compose_static_macro_label(work_package, label: work_package.formatted_id, detailed:)
144143

145-
link_to(link_text,
144+
link_to(label,
146145
work_package_path_or_url(id: work_package.display_id, only_path: context[:only_path]),
147146
class: "issue work_package")
148147
end

lib/open_project/text_formatting/matchers/link_handlers/work_packages.rb

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ class WorkPackages < Base
3838
# Shared with the PDF-export subclass in `app/models/work_package/exports/macros/links.rb`.
3939
HASH_TRIGGERS = %w[# ## ###].freeze
4040

41+
# Builds the user-facing label for the static-anchor variant of `##`/
42+
# `###` macros. Centralised so the PatternMatcherFilter path here and
43+
# the `<mention>`-envelope path in `MentionFilter` stay in lockstep.
44+
def self.compose_static_macro_label(work_package, label:, detailed:)
45+
parts = []
46+
parts << work_package.status&.name if detailed
47+
parts << work_package.type&.name
48+
parts << label
49+
"#{parts.compact.join(' ')}: #{work_package.subject}"
50+
end
51+
4152
def applicable?
4253
hash_trigger? && matcher.prefix.nil?
4354
end
@@ -112,20 +123,16 @@ def render_work_package_macro(work_package:, fallback_id:, detailed: false)
112123
end
113124

114125
# Static fallback for channels that cannot hydrate the quickinfo
115-
# custom element (HTML mailers, exports). Mirrors the in-app widget's
116-
# text composition — type, optional status, formatted_id, subject —
117-
# so the anchor reads the same as the rich rendering once flattened.
118-
# Unresolved references collapse to the bare label.
126+
# custom element. Composes type, optional status, label, and subject
127+
# into the anchor; unresolved references collapse to the bare label.
128+
# The label is the matched identifier (potentially a historical alias)
129+
# to preserve what the author wrote — the `<mention>` envelope path
130+
# in `MentionFilter` instead normalises to the WP's current
131+
# `formatted_id`.
119132
def render_static_work_package_macro(work_package, label, detailed:)
120133
return label unless work_package
121134

122-
parts = []
123-
parts << work_package.status&.name if detailed
124-
parts << work_package.type&.name
125-
parts << label
126-
link_text = "#{parts.compact.join(' ')}: #{work_package.subject}"
127-
128-
link_to(link_text,
135+
link_to(self.class.compose_static_macro_label(work_package, label:, detailed:),
129136
work_package_path_or_url(id: work_package.display_id, only_path: context[:only_path]),
130137
class: "issue work_package")
131138
end

0 commit comments

Comments
 (0)