Skip to content

Commit ccebffd

Browse files
[TASK] Improve AJAX version switcher to sort and group languages and links, document workflow (#583)
1 parent 8b720b8 commit ccebffd

File tree

20 files changed

+461
-19
lines changed

20 files changed

+461
-19
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
.. include:: /Includes.rst.txt
2+
3+
.. _AjaxVersions:
4+
5+
=====================
6+
AJAX version switcher
7+
=====================
8+
9+
Rendered documentation provides a version switcher on top of the
10+
navigation.
11+
12+
For documentation deployed on `docs.typo3.org` clicking on the version
13+
switcher will perform an AJAX API request that lists all available
14+
versions and languages for the current documentation.
15+
16+
For local rendering however, there are two issues that will lead to
17+
the version switcher not working properly:
18+
19+
* Rendered HTML files viewed via the `file:///` notation may not
20+
execute any JavaScript due to security considerations/configuration
21+
of your browser.
22+
* When viewing HTML files via `localhost` or a `.ddev.site` webserver,
23+
the AJAX call will fail due to `CORS <https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS>`__
24+
(Cross-Origin Resource Sharing) security restrictions.
25+
26+
Developers of the `render-guides` project may need to simulate menu rendering though.
27+
28+
For them, navigation can be proxied and simulated.
29+
30+
.. _AjaxVersions-proxy:
31+
32+
Making the proxy available
33+
==========================
34+
35+
When using the DDEV integration to view the documentation, the DocumentRoot of the
36+
DDEV webserver is set to `Documentation-GENERATED-temp`. This does not
37+
contain active PHP files by default.
38+
39+
The file :file:`packages/typo3-docs-theme/assets/js/versions-proxy.php` in the
40+
repository of this project (`<https://github.com/TYPO3-Documentation/render-guides>`)
41+
can act as a simple proxy. You can copy or symlink that file into your `Documentation-GENERATED-temp`
42+
directory, so that it is callable with a URL like:
43+
44+
.. code::
45+
46+
https://render-guides.ddev.site/versions-proxy.php?url=https://docs.typo3.org/m/typo3/tutorial-getting-started/12.4/en-us/Concepts/Index.html
47+
48+
The PHP proxy passes the URL parameter `url` on to the actual `docs.typo3.org` API endpoint,
49+
and returns its output locally.
50+
51+
Once the proxy PHP file is in place, the default values of the rendering will take effect
52+
already. See :ref:`AjaxVersions-data-attributes` on how to fine-tune this.
53+
54+
Details on how the version switcher is implemented
55+
==================================================
56+
57+
Local rendering is automatically detected via the absence of an environment variable
58+
`TYPO3AZUREEDGEURIVERSION` (see :ref:`deploy-azure-assets`).
59+
60+
This allows a Twig function `isRenderedForDeployment` (defined in
61+
:file:`packages/typo3-docs-theme/src/Twig/TwigExtension.php` of this repository) to
62+
conditionally generate output. The Twig template file
63+
`packages/typo3-docs-theme/resources/template/structure/navigation/navigationHeader.html.twig`
64+
makes use of that function to define some default HTML data-attributes for out-of-the-box
65+
version witcher simulation, once the PHP proxy URL can be called without a 404 error.
66+
67+
The JavaScript is contained in :file:`packages/typo3-docs-theme/assets/js/versions.js` and
68+
contains the code for parsing the JSON response of the API, and sorting the keys appropriately.
69+
More details can be found inside the code comments of that file.
70+
71+
When changing this JavaScript, the assets must be rebuilt (:bash:`ddev npm-build`) and
72+
documentation must be rendered with the built assets (:bash:`make docs`).
73+
74+
The JavaScript file also contains some logic to set names for known published translations.
75+
If a static name is not available, it is resolved to the ISO-code (like "de-de"). The
76+
TYPO3 Documentation team can not easily access active server-side code to get an automatic
77+
list of languages.
78+
79+
.. _AjaxVersions-data-attributes:
80+
Configuring HTML data-attributes
81+
================================
82+
83+
The following data-attributes on the HTML element :html:`<div id="toc-version">` are available:
84+
85+
* `data-override-url-self` - This is a full URL starting with `https://docs.typo3.org` which
86+
is used as the simulated page from which the version switching information is retrieved for.
87+
For example, `https://docs.typo3.org/m/typo3/tutorial-getting-started/12.4/en-us/Concepts/Index.html`.
88+
89+
* `data-override-url-proxy` - Points to the full URI of the :ref:`AjaxVersions-proxy` PHP proxy.
90+
This is called due to CORS reasons. The default of this attribute is set to
91+
`https://render-guides.ddev.site/versions-proxy.php?url=`. Unless this file is manually
92+
copied to this URL, the proxy will return a 404 failure and inform about the non-working
93+
version switcher.
94+
95+
Seeing the simulated output
96+
===========================
97+
98+
Once the PHP proxy is in place, open the rendered documentation HTML file in your DDEV/webserver
99+
environment (not using a `file:///` syntax, because then JavaScript may unavailable), for example
100+
101+
.. code::
102+
103+
https://render-guides.ddev.site/Developer/AjaxVersions.html
104+
105+
You can then also use the browser's JavaScript console to manipulate the used URLs for
106+
rendering, for example:
107+
108+
.. code::
109+
110+
document.getElementById('toc-version').setAttribute('data-override-url-self', 'https://docs.typo3.org/other/t3docs/render-guides/main/en-us/Developer/InterlinkInventories.html');
111+
112+
This must be performed before actually clicking the version switcher link, because
113+
the remote AJAX request is only performed once and then never again without reloading the page.

Documentation/Developer/Building.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ above, and then executes two composite steps:
200200
Note that we only have one central Docker container image entrypoint that can
201201
take arguments like `migrate` or `render` to trigger different actions.
202202

203+
.. _deploy-azure-assets:
203204

204205
GitHub workflow: deploy-azure-assets
205206
------------------------------------

Documentation/Developer/Index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ and the GitHub pipelines, while internally only using :file:`Makefile` syntax.
9292
Contributing
9393
ThemeCustomization
9494
InterlinkInventories
95+
AjaxVersions
9596

9697

9798
.. _phpDocumentor/guides: https://github.com/phpDocumentor/guides

Documentation/guides.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
>
77
<project
88
title="Render guides"
9+
version="main"
10+
release="main"
911
copyright="Since 2023 TYPO3 Documentation Team and Contributors"
1012
/>
1113
<extension
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
# This is a Proxy file to request a URL from docs.typo.org
4+
# and pass the result along to the local development.
5+
# It is used for debugging the docs.typo3.org/services/versionsJson.php
6+
# endpoint.
7+
# Since no active PHP files are part of the local DDEV instance by default,
8+
# you need to manually put that file into the document root:
9+
# $> ln -s ../packages/typo3-docs-theme/assets/js/versions-proxy.php Documentation-GENERATED-temp/versions-proxy.php
10+
11+
$proxyUrl = 'https://docs.typo3.org/services/versionsJson.php?url=' . urlencode($_REQUEST['url']);
12+
13+
$ch = curl_init();
14+
curl_setopt($ch, CURLOPT_URL, $proxyUrl);
15+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
16+
curl_setopt($ch, CURLOPT_HEADER, true);
17+
$response = curl_exec($ch);
18+
19+
if (curl_errno($ch) || $response === false) {
20+
header('404 Not Found');
21+
echo 'cURL error: ' . curl_error($ch);
22+
curl_close($ch);
23+
exit();
24+
}
25+
$response = (string)$response;
26+
27+
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
28+
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
29+
$headers = substr($response, 0, $header_size);
30+
$body = substr($response, $header_size);
31+
curl_close($ch);
32+
http_response_code($http_code);
33+
$headers_array = explode("\r\n", $headers);
34+
35+
foreach($headers_array as $header) {
36+
if (!empty($header) && !preg_match('/^Transfer-Encoding:/i', $header) && !preg_match('/^Content-Length:/i', $header)) {
37+
header($header);
38+
}
39+
}
40+
41+
echo $body;

0 commit comments

Comments
 (0)