Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.

[Update] Support Page Sections & Sphinx Domains #19

Merged
merged 43 commits into from
Jul 15, 2019

Conversation

dojutsu-user
Copy link
Member

@dojutsu-user dojutsu-user commented Jun 29, 2019

Demo

Imgur
(https://imgur.com/a/18MrgzN)

Related PR in readthedocs.org -- readthedocs/readthedocs.org#5829

@dojutsu-user dojutsu-user mentioned this pull request Jun 30, 2019
@dojutsu-user dojutsu-user removed Needed: documentation Documentation is required PR: work in progress Pull request is not ready for full review labels Jun 30, 2019
outer_div.appendChild(section_content);
section_link.appendChild(outer_div);
content.appendChild(section_link);
content.appendChild(createDomNode("br", { class: "br-for-hits" }));
Copy link
Member

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.

Copy link
Member Author

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.

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.

Copy link
Member Author

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) {
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member Author

@dojutsu-user dojutsu-user Jul 2, 2019

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.

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.

Copy link
Member Author

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.

@dojutsu-user dojutsu-user added the PR: work in progress Pull request is not ready for full review label Jul 3, 2019
Copy link
Member

@ericholscher ericholscher left a 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.

<!-- 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>
Copy link
Member

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

Copy link
Member Author

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) + " ...";
Copy link
Member

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?

Copy link
Member Author

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] + " ...";
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were getting only one result per section. So there has to be only one element in the array.
But I have refactored the code now and it is much better. We can show as many results from a section as we want. Here's a demo:
Peek 2019-07-09 13-42
I have used it with maximum 3 results from a section

Copy link
Member Author

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];
}
}
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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 "-"
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* </a>
* <br class="br-for-hits">
*
* </div>
Copy link
Member

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") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be else if ?

@dojutsu-user
Copy link
Member Author

@ericholscher
I have updated the PR.

Copy link
Member

@ericholscher ericholscher left a 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) + " ..."
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the PR.

@dojutsu-user
Copy link
Member Author

@ericholscher
I have also updated the PR to include minified files now.

@dojutsu-user
Copy link
Member Author

@ericholscher
This is ready to be merged I think.

@dojutsu-user dojutsu-user mentioned this pull request Jul 11, 2019
Copy link
Member

@ericholscher ericholscher left a 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
Copy link
Member

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.

for file in CUSTOM_ASSETS_FILES:
if file.endswith('.min.js'):
app.add_js_file(file)
if file.endswith('.min.css'):
Copy link
Member

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.

@@ -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
Copy link
Member

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.

@dojutsu-user
Copy link
Member Author

@ericholscher
I have updated the PR.
I have added a configuration variable - RTD_SPHINX_SEARCH_FILE_TYPE whose possible values are - MINIFIED and UN_MINIFIED. User can set these two values in their conf.py and the corresponding css and js files will get added in the docs.
For now, the default value is set to UN_MINIFIED for debugging purpose.
We will change this value once we decide to ship it.
Also, the tests for the same are added.

Copy link
Member

@ericholscher ericholscher left a 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 👍


def setup(app):

app.add_config_value('RTD_SPHINX_SEARCH_FILE_TYPE', 'UN_MINIFIED', 'html')
Copy link
Member

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.

Copy link
Member

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.

Copy link
Member Author

@dojutsu-user dojutsu-user Jul 12, 2019

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)?

os.path.join('css', 'rtd_sphinx_search.min.css'),
]
CUSTOM_ASSETS_FILES = {
'MINIFIED': [
Copy link
Member

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.

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
Copy link
Member

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.

Copy link
Member

@ericholscher ericholscher left a 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.

@dojutsu-user
Copy link
Member Author

@ericholscher
Updated the docs.

@ericholscher ericholscher merged commit dff4877 into master Jul 15, 2019
@dojutsu-user dojutsu-user deleted the update-extension-with-sections branch July 15, 2019 18:43
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
PR: work in progress Pull request is not ready for full review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants