-
Notifications
You must be signed in to change notification settings - Fork 13
[Update] Support Page Sections & Sphinx Domains #19
Conversation
outer_div.appendChild(section_content); | ||
section_link.appendChild(outer_div); | ||
content.appendChild(section_link); | ||
content.appendChild(createDomNode("br", { class: "br-for-hits" })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really dislike this way of creating HTML. Is it possible for us to use a JS template language for this rendering, instead of all being in code? I feel that would be much, much cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I searched on the internet and found a very small and easy to use library -- squirrelly.js.
I have updated the PR to make use of it.
I think we can use it in other places also. So I'll be updating the code and use it where ever it proves to be effective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a particularly strong opinion but sphinx docs already rely on underscore which has built-in templating. It may not be the right fit but it could avoid an external dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davidfischer
Thanks.
I have removed the external dependency and used the uderscore.js for it.
} | ||
} | ||
|
||
if (domains !== undefined && domains !== null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we always showing sections before domains in this logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
It is because we are getting the results of sections and domains separately.
sections results are sorted and domains results are sorted -- but there is no sorting present which invloves both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe ES should return the score for each object, and we're removing it in the web API. We could probably be passing along the score to the JS, so that we could use it more smartly for sorting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Score is present in each result.
Where should the sorting be done? server side or client side?
I think it's better to do it in server side as we will be using the same structure and then we have to do sorting everywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a server side sort is reasonable so that the search results on readthedocs.org and in-doc search mostly match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have implemented a server side sort. But I'm still concerned about its efficiency as I have not implemented any algorithm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looked over all the code (not the CSS) and it looks good. Just some simplification and refactors that should make it simpler.
docs/custom-design.rst
Outdated
<!-- Results from other pages --> | ||
<div class="search__result__single"><div>...</div></div> | ||
<div class="search__result__single"><div>...</div></div> | ||
<div class="search__result__single"><div>...</div></div> | ||
</div> | ||
</div> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should delete this content until we settle on the final HTML, then we can add it back? Alternatively, we could use literalinclude
from Sphinx to include this directly from the HTML: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-literalinclude
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have removed it for now and we can target these things things in a separate PR to imrpove the docs and other things.
I don't think that we can use literalinclude
here because content is being dynamically generated and removed from the DOM.
} | ||
|
||
let section_content = | ||
sectionData._source.content.substring(0, 100) + " ..."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to substring this here? Perhaps we should do it in the API instead. I don't have a strong feeling here though -- why are we only using 100 chars?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also don't have a particular opinion here.
But I think if we preprocess this on server side, it will reduce the size of the fetched data. So preprocessing this might decrease the time to get the results from server. What are your thoughts on this?
I used the substring with 100
because I think it is just sufficient data from a page which don't have any highlighted content.
We can increase or decrease this as per our choice. I have used this in other places also.
sectionData.highlight["sections.content"].length >= 1 | ||
) { | ||
section_content = | ||
"... " + sectionData.highlight["sections.content"][0] + " ..."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we're accessing only the first item of the list here? Should this be a constant about how many to include?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently I have used the approach of getting the value at index 0 directly everywhere.
I will be refactoring them also. (search.html and main site search)
domain_type_display = | ||
domainData.highlight["domains.type_display"][0]; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we write a function to abstract these 3 functions that do the same thing? get_highlight_list_data('domains.display_name
)` or similar?
} | ||
if ( | ||
typeof domain_doc_display === "string" && | ||
domain_doc_display.length > 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add an _is_string
function or similar that does this?
if (domainData.highlight !== undefined && domainData.highlight !== null) { | ||
if ( | ||
domainData.highlight["domains.name"] !== undefined && | ||
domainData.highlight["domains.name"].length >= 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add an _is_list
function that does this?
let domain_subheading = ""; | ||
if ( | ||
typeof domain_display_name === "string" && | ||
domain_display_name.length >= 2 // >= 2 because many display_names have values "-" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we fix indexing to not store this data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can.
I will look into this more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ericholscher
This is fixed now -- readthedocs/readthedocs.org@f988302
* </a> | ||
* <br class="br-for-hits"> | ||
* | ||
* </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep this in the docs, we don't need it here. It takes up a lot of space.
page_link | ||
); | ||
} else { | ||
if (type === "domains") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be else if
?
@ericholscher |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is much better. I think we're really close to merging. 👍
section_content = | ||
"... " + sectionData.highlight["sections.content"][0] + " ..."; | ||
let section_content = [ | ||
sectionData._source.content.substring(0, 100) + " ..." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see 100
be a constant defined at the top of the file, at least. We can keep that for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the PR.
@ericholscher |
@ericholscher |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed its ready to merge, just a few nitpicks, then feel free to merge.
MANIFEST.in
Outdated
include sphinx_search/_static/js/rtd_sphinx_search.min.js | ||
include sphinx_search/_static/css/rtd_sphinx_search.css |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do think we should include these as well as the minified ones. People generally like to be able to debug against non-minified source.
sphinx_search/extension.py
Outdated
for file in CUSTOM_ASSETS_FILES: | ||
if file.endswith('.min.js'): | ||
app.add_js_file(file) | ||
if file.endswith('.min.css'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should have a setting that specifies minified or non-minified files here? We can ship like it is, but I almost always prefer full versions when doing dev.
tests/test_extension.py
Outdated
@@ -36,9 +36,9 @@ def test_static_files_injected_in_html(selenium, app, status, warning): | |||
page_source = selenium.page_source | |||
|
|||
assert ( | |||
page_source.count('rtd_sphinx_search.js') == 1 | |||
page_source.count('rtd_sphinx_search.min.js') == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these should be variables, not strings put thoughout the file.
@ericholscher |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this addition. I think it makes sense with some convention changes 👍
sphinx_search/extension.py
Outdated
|
||
def setup(app): | ||
|
||
app.add_config_value('RTD_SPHINX_SEARCH_FILE_TYPE', 'UN_MINIFIED', 'html') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe Sphinx uses lower-case config values by convention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also should be documented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the documentation changes be done in another PR (the one with the API reference)?
sphinx_search/extension.py
Outdated
os.path.join('css', 'rtd_sphinx_search.min.css'), | ||
] | ||
CUSTOM_ASSETS_FILES = { | ||
'MINIFIED': [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these should also be lowercase.
sphinx_search/extension.py
Outdated
def setup(app): | ||
def inject_static_files(app): | ||
"""Inject correct CSS and JS files based on the value of ``RTD_SPHINX_SEARCH_FILE_TYPE``.""" | ||
file_type = app.config.RTD_SPHINX_SEARCH_FILE_TYPE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should check the incoming value for being one of the two we expect, and give users a good error if not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is ready to merge. The only thing left is to document the new setting.
@ericholscher |
Demo
(https://imgur.com/a/18MrgzN)
Related PR in readthedocs.org -- readthedocs/readthedocs.org#5829