Skip to content

Commit afe1d87

Browse files
authored
[TASK] Introduce report issue button (#674)
Introduces a "Report issue" button: ![image](https://github.com/user-attachments/assets/8bf618de-d895-45f5-a0e2-2ae15f014088) Button is displayed if project-issues or report-issue are set in the guides.xml extension tag. report-issue="none" disables the button while still displaying the issues link in the footer. Links to Github and forge.typo3.org set some fields in the form like the title fields or the version field on forge. Resolves: #673
1 parent 426e640 commit afe1d87

File tree

24 files changed

+1221
-5
lines changed

24 files changed

+1221
-5
lines changed

packages/typo3-docs-theme/resources/template/structure/layoutParts/editOnGithubButtons.html.twig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
<div class="breadcrumb-additions">
2+
{%- set reportIssueLink = getReportIssueLink() -%}
3+
{%- if (reportIssueLink) %}
4+
<a class="btn btn-sm btn-light" href="{{ reportIssueLink }}" id="btnReportIssue" rel="nofollow noopener" target="_blank">
5+
<span class="btn-icon"><i class="fas fa-bug"></i></span>
6+
<span class="btn-text">Report issue</span>
7+
</a>
8+
{% endif -%}
29
{%- set copySources = getSettings('copy_sources') -%}
310
{%- if (copySources) %}
411
<a class="btn btn-sm btn-light" href="{{ copyDownload(env.currentFileName ~ '.rst', '_sources/' ~ env.currentFileName ~ '.rst.txt') }}" rel="nofollow noopener" target="_blank">

packages/typo3-docs-theme/src/DependencyInjection/Typo3DocsThemeExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public function load(array $configs, ContainerBuilder $container): void
6363
'project_contact' => $this->getConfigValue($configs, 'project_contact', ''),
6464
'project_repository' => $this->getConfigValue($configs, 'project_repository', ''),
6565
'project_issues' => $this->getConfigValue($configs, 'project_issues', ''),
66+
'report_issue' => $this->getConfigValue($configs, 'report_issue', ''),
6667
'typo3_core_preferred' => $this->getConfigValue($configs, 'typo3_core_preferred', ''),
6768
],
6869
],

packages/typo3-docs-theme/src/Twig/TwigExtension.php

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public function getFunctions(): array
6363
new TwigFunction('getAnchorIdOfSection', $this->getAnchorIdOfSection(...), ['needs_context' => true]),
6464
new TwigFunction('getEditOnGitHubLink', $this->getEditOnGitHubLink(...), ['needs_context' => true]),
6565
new TwigFunction('getEditOnGitHubLinkFromPath', $this->getEditOnGitHubLinkFromPath(...), ['needs_context' => true]),
66+
new TwigFunction('getReportIssueLink', $this->getReportIssueLink(...), ['needs_context' => true]),
6667
new TwigFunction('getCurrentFilename', $this->getCurrentFilename(...), ['needs_context' => true]),
6768
new TwigFunction('getRelativePath', $this->getRelativePath(...), ['needs_context' => true]),
6869
new TwigFunction('getPagerLinks', $this->getPagerLinks(...), ['is_safe' => ['html'], 'needs_context' => true]),
@@ -262,6 +263,107 @@ private function getEditOnGitHubLinkPerPage(RenderContext $renderContext): strin
262263
return null;
263264
}
264265

266+
267+
/**
268+
* @param array{env: RenderContext} $context
269+
*/
270+
public function getReportIssueLink(array $context): string
271+
{
272+
$renderContext = $this->getRenderContext($context);
273+
$reportButton = $this->themeSettings->getSettings('report_issue');
274+
if ($reportButton === 'none') {
275+
return '';
276+
}
277+
if (str_starts_with($reportButton, '/')) {
278+
return $this->urlGenerator->generateCanonicalOutputUrl($renderContext, $reportButton);
279+
}
280+
if (str_starts_with($reportButton, 'https://forge.typo3.org/')) {
281+
$reportButton = $this->enrichForgeLink($reportButton, $renderContext);
282+
return $reportButton;
283+
}
284+
if (str_starts_with($reportButton, 'https://github.com/')) {
285+
$reportButton = $this->enrichGithubReport($reportButton, $renderContext);
286+
return $reportButton;
287+
}
288+
if (str_starts_with($reportButton, 'https://gitlab.com/')) {
289+
return $reportButton;
290+
}
291+
if ($reportButton !== '') {
292+
$this->logger->warning('For security reasons only only "report-issue" links in the guides.xml to a local page (starting with "/") or to one of these 3 plattforms are allowed: https://forge.typo3.org/ https://github.com/ https://gitlab.com/');
293+
return '';
294+
}
295+
296+
$reportButton = $this->themeSettings->getSettings('project_issues');
297+
$reportButton = rtrim($reportButton, '/');
298+
299+
if (str_starts_with($reportButton, '')) {
300+
return '';
301+
}
302+
if (str_starts_with($reportButton, 'https://forge.typo3.org/')) {
303+
$reportButton = $this->enrichForgeLink($reportButton, $renderContext);
304+
return $reportButton;
305+
}
306+
if (str_starts_with($reportButton, 'https://github.com/')) {
307+
$reportButton = $this->enrichGithubReport($reportButton, $renderContext);
308+
return $reportButton;
309+
}
310+
if (str_starts_with($reportButton, 'https://gitlab.com/')) {
311+
if (str_ends_with($reportButton, '/issues')) {
312+
$reportButton .= '/new';
313+
}
314+
return $reportButton;
315+
}
316+
317+
$this->logger->warning('For security reasons only only "project_issues" links in the guides.xml to one of these 3 plattforms are allowed: https://forge.typo3.org/ https://github.com/ https://gitlab.com/');
318+
return '';
319+
}
320+
321+
/**
322+
* @param string $reportButton
323+
* @return string
324+
*/
325+
public function enrichGithubReport(string $reportButton, RenderContext $renderContext): string
326+
{
327+
if (str_ends_with($reportButton, '/issues')) {
328+
$reportButton .= '/new/choose';
329+
}
330+
if (str_ends_with($reportButton, '/new/choose') or str_ends_with($reportButton, '/new')) {
331+
$reportButton .= '?title=';
332+
$description = $this->getIssueTitle($renderContext);
333+
$reportButton .= urlencode($description);
334+
}
335+
return $reportButton;
336+
}
337+
338+
/**
339+
* @param string $reportButton
340+
* @param RenderContext $renderContext
341+
* @return string
342+
*/
343+
public function enrichForgeLink(string $reportButton, RenderContext $renderContext): string
344+
{
345+
if (str_ends_with($reportButton, '/issues')) {
346+
$reportButton .= '/new';
347+
}
348+
if (str_ends_with($reportButton, '/new')) {
349+
$reportButton .= '?issue[category_id]=1004&issue[subject]=';
350+
$description = $this->getIssueTitle($renderContext);
351+
$reportButton .= urlencode($description);
352+
$version = $this->typo3VersionService->getPreferredVersion();
353+
$reportButton .= '&issue[custom_field_values][4]=' . $version;
354+
}
355+
return $reportButton;
356+
}
357+
358+
/**
359+
* @param RenderContext $renderContext
360+
* @return string
361+
*/
362+
public function getIssueTitle(RenderContext $renderContext): string
363+
{
364+
return 'Problem on ' . $this->themeSettings->getSettings('project_home') . '/' . $renderContext->getCurrentFileName() . '.html';
365+
}
366+
265367
/**
266368
* @param array{env: RenderContext} $context
267369
* @return list<string>
@@ -478,4 +580,5 @@ public function isRenderedForDeployment(): bool
478580

479581
return false;
480582
}
583+
481584
}
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
<!DOCTYPE html>
2+
<html class="no-js" lang="en">
3+
<head>
4+
<title>Document Title — Lorem Ipsum documentation</title>
5+
6+
7+
<meta charset="utf-8">
8+
<meta content="width=device-width, initial-scale=1.0" name="viewport">
9+
<meta content="phpdocumentor/guides" name="generator">
10+
<meta content="Lorem Ipsum" name="docsearch:name">
11+
<meta content="" name="docsearch:package_type">
12+
<meta content="" name="docsearch:release">
13+
<meta content="" name="docsearch:version">
14+
<meta content="2023-01-01T12:00:00+00:00" name="docsearch:modified">
15+
<meta content="2023-01-01T12:00:00+00:00" name="dc.modified">
16+
<meta content="2023-01-01T12:00:00+00:00" property="article:modified_time">
17+
<link href="http://purl.org/dc/elements/1.1/" rel="schema.dc">
18+
<link href="_resources/css/theme.css" rel="stylesheet">
19+
<link href="https://docs.typo3.org/search/" rel="search" title="Search">
20+
<script src="https://typo3.azureedge.net/typo3infrastructure/universe/dist/webcomponents-loader.js"></script>
21+
<script src="https://typo3.azureedge.net/typo3infrastructure/universe/dist/typo3-universe.js" type="module"></script>
22+
<link href="report.html" rel="next" title="Report an issue"/>
23+
<link href="#" rel="top" title="Document Title"/>
24+
</head>
25+
<body>
26+
<div class="page">
27+
28+
<header>
29+
<div class="page-topbar">
30+
<div class="page-topbar-inner">
31+
<typo3-universe active="documentation">
32+
<div style="display: block; height: 44px; background-color: #313131;"></div>
33+
</typo3-universe>
34+
</div>
35+
</div>
36+
<div class="page-header">
37+
<div class="page-header-inner">
38+
<div class="row">
39+
<div class="col-sm-3 col-md-4 col-lg-6">
40+
<a class="logo" href="https://docs.typo3.org/" title="TYPO3 Documentation">
41+
<img alt="TYPO3 Logo" class="logo-image" src="_resources/img/typo3-logo.svg" width="484" height="130">
42+
</a>
43+
</div>
44+
<div class="col-sm-9 col-md-8 col-lg-6">
45+
<search role="search">
46+
<form action="https://docs.typo3.org/search/search" id="global-search-form" method="get">
47+
<div class="sr-only"><label for="globalsearchinput">TYPO3 documentation...</label></div>
48+
<div class="input-group mb-3 mt-sm-3">
49+
<select class="form-select search__scope" id="searchscope" name="scope">
50+
<option value="">Search all</option>
51+
</select>
52+
<input autocomplete="off" class="form-control shadow-none" id="globalsearchinput" name="q" placeholder="TYPO3 documentation..." type="text" value="">
53+
<button class="btn btn-light search__submit" type="submit"><i class="fa fa-search"></i>&nbsp;<span class="d-none d-md-inline">Search</span></button>
54+
</div>
55+
</form>
56+
</search>
57+
</div>
58+
</div>
59+
</div>
60+
</div>
61+
</header> <main class="page-main">
62+
<div class="page-main-inner">
63+
<div class="page-main-navigation">
64+
<nav>
65+
<input class="toc-checkbox" id="toggleToc" type="checkbox">
66+
67+
68+
<div class="toc-header">
69+
<div class="toc-title">
70+
<a class="toc-title-project" href="#">Lorem Ipsum</a>
71+
</div>
72+
<div class="toc-actions">
73+
<label class="toc-toggle" for="toggleToc">
74+
Menu
75+
</label>
76+
</div>
77+
</div> <div class="toc-collapse">
78+
<div aria-label="main navigation" class="toc" role="navigation">
79+
<div aria-label="Main navigation" class="main_menu" role="navigation">
80+
81+
<ul class="menu-level-1">
82+
<li class="">
83+
<a href="report.html">
84+
Report an issue
85+
</a></li> </ul>
86+
</div>
87+
<div aria-label="Meta navigation" class="main_menu d-block d-lg-none" role="navigation">
88+
<hr/>
89+
<p class="caption">Contributors Corner</p>
90+
<ul class="menu-level-1"> <li><a href="_sources/index.rst.txt" rel="nofollow noopener" target="_blank">
91+
View source of current document
92+
</a></li>
93+
<li><a href="https://docs.typo3.org/m/typo3/docs-how-to-document/main/en-us/WritingDocsOfficial/GithubMethod.html" rel="nofollow noopener" target="_blank">
94+
How to edit
95+
</a></li>
96+
</ul>
97+
</div>
98+
</div>
99+
</div>
100+
</nav>
101+
</div>
102+
<div class="page-main-content">
103+
<div class="rst-content"> <nav aria-label="breadcrumbs navigation" class="breadcrumb-bar" role="navigation">
104+
105+
<ol class="breadcrumb">
106+
<li aria-current="page" class="breadcrumb-item active">Document Title</li>
107+
</ol>
108+
<div class="breadcrumb-additions"> <a class="btn btn-sm btn-light" href="_sources/index.rst.txt" rel="nofollow noopener" target="_blank">
109+
<span class="btn-icon"><span class="fas fa-code"></span></span>
110+
<span class="btn-text">View source</span>
111+
</a>
112+
<a class="btn btn-sm btn-light" href="https://docs.typo3.org/m/typo3/docs-how-to-document/main/en-us/WritingDocsOfficial/GithubMethod.html" id="btnHowToEdit" rel="nofollow noopener" target="_blank">
113+
<span class="btn-icon"><span class="fas fa-info-circle"></span></span>
114+
<span class="btn-text">How to edit</span>
115+
</a>
116+
</div> </nav>
117+
118+
<article class="document" itemscope="itemscope" itemtype="http://schema.org/Article" role="main">
119+
<div itemprop="articleBody">
120+
<!-- content start -->
121+
<section class="section" id="document-title">
122+
<h1>Document Title<a class="headerlink" href="#document-title" data-bs-toggle="modal" data-bs-target="#linkReferenceModal" title="Reference this headline"></a></h1>
123+
124+
<p>Lorem Ipsum Dolor.</p>
125+
126+
<div class="toctree-wrapper compound">
127+
<ul class="menu-level">
128+
<li class="toc-item">
129+
<a href="report.html#report-an-issue">Report an issue</a>
130+
131+
132+
</li>
133+
</ul>
134+
</div>
135+
</section>
136+
<!-- content end -->
137+
</div>
138+
</article>
139+
140+
<nav aria-label="Page navigation">
141+
<ul class="pagination justify-content-center"><li class="page-item">
142+
<a class="page-link" href="report.html"
143+
title="Accesskey Alt(+Shift)+n">
144+
Next
145+
</a>
146+
</li>
147+
</ul>
148+
</nav>
149+
</div>
150+
</div>
151+
</div>
152+
</main>
153+
154+
<div class="modal fade" id="linkReferenceModal" tabindex="-1" aria-labelledby="linkReferenceModalLabel"
155+
aria-hidden="true" data-current-filename="index">
156+
<div class="modal-dialog">
157+
<div class="modal-content">
158+
<div class="modal-header">
159+
<h5 class="modal-title" id="linkReferenceModalLabel">Reference to the headline</h5>
160+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
161+
</div>
162+
<div class="modal-body">
163+
<div class="alert alert-success d-none" id="permalink-alert-success" role="alert"></div>
164+
<div class="mb-3">
165+
<label for="permalink-uri" class="col-form-label">Permalink</label>
166+
<div class="input-group">
167+
<input class="form-control code" id="permalink-uri" readonly>
168+
<button type="button" class="btn btn-outline-secondary copy-button" data-target="permalink-uri"><i class="far fa-clone"></i></button>
169+
</div>
170+
<p>Copy and freely share the link</p>
171+
</div>
172+
<div class="mb-3">
173+
<div class="alert alert-warning alert-permalink-rst" role="alert">This link target has no permanent anchor assigned.The link below can be used, but is prone to change if the page gets moved.
174+
</div>
175+
<label for="permalink-rst" class="col-form-label">reStructuredText (reST):</label>
176+
<div class="input-group">
177+
<textarea class="form-control code" id="permalink-rst" readonly></textarea>
178+
<button type="button" class="btn btn-outline-secondary copy-button" data-target="permalink-rst"><i class="far fa-clone"></i></button>
179+
</div>
180+
<p>Copy this link into your TYPO3 manual. </p>
181+
</div>
182+
<div class="mb-3">
183+
<label for="permalink-html" class="col-form-label">HTML:</label>
184+
<div class="input-group">
185+
<textarea class="form-control code" id="permalink-html" readonly></textarea>
186+
<button type="button" class="btn btn-outline-secondary copy-button" data-target="permalink-html"><i class="far fa-clone"></i></button>
187+
</div>
188+
</div>
189+
</div>
190+
<div class="modal-footer">
191+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
192+
</div>
193+
</div>
194+
</div>
195+
</div> <div class="modal fade" id="generalModal" tabindex="-1" aria-labelledby="linkReferenceModalLabel"
196+
aria-hidden="true" data-current-filename="index"
197+
>
198+
<div class="modal-dialog">
199+
<div class="modal-content">
200+
<div class="modal-header">
201+
<h5 class="modal-title" id="generalModalLabel"></h5>
202+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
203+
</div>
204+
<div class="modal-body">
205+
<div class="alert alert-success d-none" id="general-alert-success" role="alert"></div>
206+
<div id="generalModalContent">
207+
</div>
208+
</div>
209+
<div class="modal-footer justify-content-between">
210+
<div id="generalModalCustomButtons"></div>
211+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><i class="fa-regular fa-circle-xmark"></i>&nbsp;Close</button>
212+
</div>
213+
</div>
214+
</div>
215+
</div></div>
216+
217+
218+
<footer class="page-footer">
219+
<div class="frame frame-ruler-before frame-background-dark">
220+
<div class="frame-container">
221+
<div class="frame-inner">
222+
<ul class="footer-simplemenu">
223+
<li><a href="https://github.com/TYPO3-Documentation/render-guides/issues/new" rel="nofollow noopener" title="Issues"><span>Issues</span></a></li>
224+
</ul> <div class="footer-additional">
225+
<p class="text-center">Last rendered: Jan 01, 2023 12:00</p>
226+
</div>
227+
<div class="footer-meta">
228+
<ul class="footer-meta-navigation">
229+
<li><a href="https://typo3.org/legal-notice" rel="nofollow" target="_blank" title="Legal Notice">Legal Notice</a></li>
230+
<li><a href="https://typo3.org/privacy-policy" rel="nofollow" target="_blank" title="Privacy Policy">Privacy Policy</a></li>
231+
</ul>
232+
</div>
233+
</div>
234+
</div>
235+
</div>
236+
</footer>
237+
<script src="_resources/js/popper.min.js"></script>
238+
<script src="_resources/js/bootstrap.min.js"></script>
239+
<script src="_resources/js/theme.min.js"></script>
240+
241+
<!--
242+
Locally rendered. No tracking embedded.
243+
-->
244+
</body>
245+
</html>

0 commit comments

Comments
 (0)