BookStackApp / BookStack

A platform to create documentation/wiki content built with PHP & Laravel
https://www.bookstackapp.com/
MIT License
15.43k stars 1.94k forks source link

Ability to create Glossary (in-line definitions) for words... #5316

Closed kristiandg closed 1 week ago

kristiandg commented 1 week ago

Describe the feature you'd like

The ability to create a Glossary, and have words that match the Glossary auto-underlined within a Book/Page, so when the user hovers over that underlined word, a small popup appears describing that item.

In the pictures below, you can see that the word "DNS" has been placed in the Glossary of this example website, and is auto-underlined wherever that word appears.

Definition - underlined

When you hover over that word, it then displays the definition for the user:

Definition - expanded

(In the example pics, there's also a note of who created the dictionary entry, as well as the option to vote on the description. I don't care about that portion of the feature - others might though - but in general, the ability to define a list of words you'd want to provide a definition for, and hover over the word to read the definition).

Because BookStack is so versatile, it would be highly limiting to assign definitions globally for the server. For example, one book may have DNS as Domain Name System, and another book may have DNS as Distributed Normal Slouchiness. :), I'm thinking either a definition list per book (though that seems like a lot of redundant work), or (ideally) a section within BookStack to build/manage glossary terms (naming each glossary), and when you edit the book, you can apply one (or many) to that book. The reason for "many" is that you could have a Glossary of "technical terms" and apply it to the book, but then you could also have another glossary for a product-specific item, and apply it to the book as well. Whereas if you could only apply one, you may end up having to create duplicate terms in several glossaries. By being able to assign multiple, you could create very specific glossaries for sub-sections of an item, and all those that apply to the book, then get assigned.

Describe the benefits this would bring to existing BookStack users

This would allow the user to get detailed descriptions of the meaning of a word without having to leave the site.

Can the goal of this request already be achieved via other means?

As far as I know, no such function exists within BookStack that I have found or read in documentation.

Have you searched for an existing open/closed issue?

How long have you been using BookStack?

Under 3 months

Additional context

WIKI does something similar to this, by having clickable links instead. I personally don't like the clickable links, because they look like off-page resources. The underline option, to me, is much cleaner.

ssddanbrown commented 1 week ago

Thanks for the request @kristiandg, but I would consider this a duplicate of #428 so will likely close this off.

It's probably possible to create a JavaScript hack though which looks up from a specific glossary page(s) for display in the desired manner. If desired, I could maybe whip a quick example but it just won't be officially supported at all.

kristiandg commented 1 week ago

I never thought of that. I’m also not skilled in coding but would be very appreciative if you could. That would be wonderful. On Nov 11, 2024, at 2:55 PM, Dan Brown @.***> wrote: Thanks for the request @kristiandg, but I would consider this a duplicate of #428 so will likely close this off. It's probably possible to create a JavaScript hack though which looks up from a specific glossary page(s) for display in the desired manner. If desired, I could maybe whip a quick example but it just won't be officially supported at all.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>

ssddanbrown commented 1 week ago

Okay, here's a basic example I've spent some time on. To keep the scope reasonable and to limit spending loads of time, there's some important limitations:

Here's the code:

View Code

```html ```

Add all of that the the "Custom HTML Head Content" customization setting. This will look up to a global glossary, defined via a single page on line 2 of the code (tweak this URL to the path of your own global glossary page, but keep the path format the same) while also looking up a page of URL slug (typically name) Glossary in the book for the current page you're viewing.

Glossary pages should have their content written like so:

Term: Description for term

# Example
VPS: A virtual private server (VPS) is a virtual machine sold as a service by an Internet hosting service.

Cat: A type of small house tiger that constantly demands food.

Terms are matched case-insensitive. Glossaries are cached in the browser to prevent needing a lookup on each page load. They can be force reloaded by simply viewing the changed glossary page.

Note: there may be further bugs and limitations of this, I've only quickly tested and this if all unofficial hackery.

Let me know if that works for you. If it does, I may clean it up and add it to our hacks site for others to easily use.

kristiandg commented 1 week ago

@ssddanbrown , THANK YOU SO MUCH!!!

I want to make sure I'm doing the URL replacement properly. const urlPath = window./books/global-glossary(/^.*?\/books\//, '/books/');

Is the above correct, or do I need the full Server URL (since the rest appears to be coded as relative path, I figured this would work). In that book, I created a page called "glossary" and built one test entry:

Screenshot 2024-11-12 at 9 08 03 AM

Permission-wise, I have the access to view that Glossary page, so that shouldn't be a limiting factor.

Here's where I pasted your code:

Screenshot 2024-11-12 at 9 10 11 AM

In my test book, I've used the term VPN in a couple of locations, but am not seeing it bubble up or highlight. I have no doubt I'm doing something wrong.

ssddanbrown commented 1 week ago

Is the above correct,

No, sorry, I should have been more clear, it's line 2 overall, so the value of the defaultGlossaryPage variable. Edit: To add more context, you just need to change the my-book and main-glossary parts of that text to match the URL sub-path for your main global/default/fallback glossary page. Should not need to touch any other lines.

kristiandg commented 1 week ago

Oh, for god sakes. LOL. You were crystal clear (line 2 - line 2 - jeez). I just hadn't had my coffee yet.

Works beautifully. THANK YOU SO MUCH.

Even the nice little touch with the cursor becoming a ? - VERY NICE. :)

JNR8 commented 1 day ago

After implementting a global glossary to test this out I have come across a few issues:

1: Terms in a header are highlighted, when perhaps they should not be.
2: The term being highlighted is duplicated (but not all the time, see attached image). image

3: Terms are not always displayed. Different browsers have different results. MS Edge for example throws an exception:

Uncaught (in promise) QuotaExceededError: Failed to execute 'setItem' on 'Storage': Setting the value of 'bsglossary:/books/global-glossary/page/index' exceeded the quota.
    at addTermMapToStorage (9th-to-8th-kyu-red:193:29)
    at getGlossaryFromPath (9th-to-8th-kyu-red:183:9)
    at async Promise.all (index 0)
    at async getMergedGlossariesForPage (9th-to-8th-kyu-red:135:49)
    at async highlightTermsOnPage (9th-to-8th-kyu-red:85:26)