Skip to content

Commit 2658ec6

Browse files
committed
Updates
1 parent 0b21391 commit 2658ec6

File tree

1 file changed

+34
-35
lines changed

1 file changed

+34
-35
lines changed

docs/dev/design/better-doc-urls-handling.rst

+34-35
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,21 @@ Alternative implementation
3939
--------------------------
4040

4141
Instead of trying to map a URL to a view,
42-
we first analyze the canonical project (given from the subdomain),
43-
and based on that we map each part of the URL (parts are the result of splitting the URL on ``/``)
44-
to the *current* project.
42+
we first analyze the root project (given from the subdomain),
43+
and based on that we map each part of the URL to the *current* project and version.
4544

46-
This will allow us to re-use this code in our resolver
45+
This will allow us to re-use this code in our unresolver
4746
without the need to override the Django's urlconf at runtime,
4847
or guessing a project only by the structure of its URL.
4948

5049
Terminology:
5150

52-
Canonical project
51+
Root project
5352
The project from where the documentation
54-
is served (the parent project of a subproject or translation).
53+
is served (usually the parent project of a subproject or translation).
5554
Current project
5655
The project that owns the current file being served
5756
(a subproject, a translation, etc).
58-
URL part
59-
The result of splitting the URL on ``/``.
6057
Requested file
6158
The final path to the file that we need to serve from the current project.
6259

@@ -66,9 +63,9 @@ Look up process
6663
Proxito will process all documentation requests from a single *docs serve* view,
6764
exluding ``/_`` URLs.
6865

69-
This view then will process the current URL using the canonical project as follows:
66+
This view then will process the current URL using the root project as follows:
7067

71-
- Check if the canonical project has translations
68+
- Check if the root project has translations
7269
(the project itself is a translation if isn't a single version project),
7370
and the first part is a language code and the second is a version.
7471

@@ -80,7 +77,7 @@ This view then will process the current URL using the canonical project as follo
8077

8178
- If the subproject prefix or the alias don't match, we continue.
8279
- If they match, we try to match the rest of the URL for translations/versions and single versions
83-
(i.e, we don't search for subprojects) and we use the subproject as the new *canonical project*.
80+
(i.e, we don't search for subprojects) and we use the subproject as the new *root project*.
8481

8582
- Check if the project is a single version.
8683
Here we just try to serve the rest of the URL as the file.
@@ -109,14 +106,14 @@ Doesn't seem useful to do so.
109106

110107
So, what we need is have a way to specify a prefix only.
111108
We would have a prefix used for translations and another one used for subprojects.
112-
These prefixes will be set in the canonical project.
109+
These prefixes will be set in the root project.
113110

114111
The look up order would be as follow:
115112

116-
- If the canonical project has a custom prefix, and the current URL matches that prefix,
113+
- If the root project has a custom prefix, and the current URL matches that prefix,
117114
remove the prefix and follow the translations and single version look up process.
118115
We exclude subprojects from it, i.e, we don't check for ``{prefix}/projects``.
119-
- If the canonical project has subprojects and a custom subprojects prefix (``projects`` by default),
116+
- If the root project has subprojects and a custom subprojects prefix (``projects`` by default),
120117
and if the current URL matches that prefix,
121118
and the next part of the URL matches a subproject alias,
122119
continue with the subproject look up process.
@@ -128,8 +125,8 @@ The next examples are organized in the following way:
128125

129126
- First there is a list of the projects involved,
130127
with their available versions.
131-
- The first project would be the canonical project.
132-
- The other projects will be related to the canonical project
128+
- The first project would be the root project.
129+
- The other projects will be related to the root project
133130
(their relationship is given by their name).
134131
- Next we will have a table of the requests,
135132
and their result.
@@ -412,29 +409,32 @@ This is a simplified version of the implementation,
412409
there are some small optimizations and validations that will be in the
413410
final implementation.
414411

412+
In the final implementation we will be using regular expressions to extract
413+
the parts from the URL.
414+
415415
.. code-block:: python
416416
417417
from readthedocs.projects.models import Project
418-
418+
419419
LANGUAGES = {"es", "en"}
420-
420+
421421
def pop_parts(path, n):
422422
if path[0] == '/':
423423
path = path[1:]
424424
parts = path.split('/', maxsplit=n)
425425
start, end = parts[:n], parts[n:]
426426
end = end[0] if end else ''
427427
return start, end
428-
429-
428+
429+
430430
def resolve(canonical_project: Project, path: str, check_subprojects=True):
431431
prefix = '/'
432432
if canonical_project.prefix:
433433
prefix = canonical_project.prefix
434434
subproject_prefix = "/projects"
435435
if canonical_project.subproject_prefix:
436436
subproject_prefix = canonical_project.subproject_prefix
437-
437+
438438
# Multiversion project.
439439
if path.startswith(prefix):
440440
new_path = path.removeprefix(prefix)
@@ -450,7 +450,7 @@ final implementation.
450450
if version:
451451
return project, version, new_path
452452
return project, None, None
453-
453+
454454
# Subprojects.
455455
if check_subprojects and path.startswith(subproject_prefix):
456456
new_path = path.removeprefix(subproject_prefix)
@@ -463,7 +463,7 @@ final implementation.
463463
path=new_path,
464464
check_subprojects=False,
465465
)
466-
466+
467467
# Single project.
468468
if path.startswith(prefix):
469469
new_path = path.removeprefix(prefix)
@@ -474,28 +474,28 @@ final implementation.
474474
if version:
475475
return canonical_project, version, new_path
476476
return canonical_project, None, None
477-
477+
478478
return None, None, None
479-
480-
479+
480+
481481
def view(canonical_project, path):
482482
current_project, version, file = resolve(
483483
canonical_project=canonical_project,
484484
path=path,
485485
)
486486
if current_project and version:
487487
return serve(current_project, version, file)
488-
488+
489489
if current_project:
490490
return serve_404(current_project)
491-
491+
492492
return serve_404(canonical_project)
493-
494-
493+
494+
495495
def serve_404(project, version=None):
496496
pass
497-
498-
497+
498+
499499
def serve(project, version, file):
500500
pass
501501
@@ -504,8 +504,7 @@ Performance
504504
~~~~~~~~~~~
505505

506506
Performance is mainly driven by the number of database lookups.
507-
There is an additional impact of splitting and joining the paths,
508-
but those are linear operations, and can be optimized to make then constant (i.e. using ``maxsplit=4``).
507+
There is an additional impact performing a regex lookup.
509508

510509
- A single version project:
511510

@@ -546,7 +545,7 @@ Questions
546545
- robots and sitemap
547546
- The ``page`` redirect
548547

549-
I'd say we shouldn't, I can't think of a reason why this should be supported.
548+
This can be useful for people that proxy us from another path.
550549

551550
- Should we use the urlconf from the subproject when processing it?
552551
This is an URL like ``/projects/subproject/custom/prefix/en/latest/index.html``.

0 commit comments

Comments
 (0)