# Related content

**URL:** <https://discourse.gohugo.io/t/related-content/169>\
**Category:** dev\
**Created:** [October 3, 2014, 8:08am UTC](https://discourse.gohugo.io/t/related-content/169 "2014-10-03T08:08:56Z")\
**Posts on this page:** 8\
**Page:** 2

<div class="post-metadata">

**Author:** ![moorereason](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/moorereason/32/592_2.png) [@moorereason](https://discourse.gohugo.io/u/moorereason)\
**Post date:** [January 5, 2016, 8:27pm UTC](https://discourse.gohugo.io/t/related-content/169/21 "2016-01-05T20:27:42Z")

</div>

For anyone wanting to pick this up and work on it, a few weeks ago I submitted [a PR](https://github.com/bbalet/stopwords/pull/1) to @bbalet’s `stopwords` repo that significantly improves its performance by working with byte slices instead of strings. He’s yet to respond, but we can fork and move on if we want. After working on `stopwords`, I appreciate his work. I think he’s just too busy to work on it, and I’m too busy right now to take it to the next step.

Having said that, I wanted to share my thoughts. I was thinking that we could implement interfaces for this:

```auto
type WordStopper interface {
    RemoveStopWords(content []byte, lang string) (cleaned []byte)
}

type ContentRelater interface {
    Simhash(content []byte) uint64
    Distance(x, y uint64) int
}

```

Then implement those interfaces with `stopwords` and [simhash](https://github.com/mfonda/simhash). The interfaces would let us swap out the implementation on the fly with [something else](https://github.com/dgryski/go-simstore/blob/master/simhash/simhash.go) later if we wanted to or even open it up to plugins later. Which means we need to make good choices about constructing and naming the interface.

---

<div class="post-metadata">

**Author:** ![wpk](https://avatars.discourse-cdn.com/v4/letter/w/838e76/32.png) [@wpk](https://discourse.gohugo.io/u/wpk)\
**Post date:** [February 18, 2016, 2:18pm UTC](https://discourse.gohugo.io/t/related-content/169/22 "2016-02-18T14:18:40Z")

</div>

Hi,

Having related posts integrated in Hugo would be so valuable!

I would like to toss in an idea about this. As I see it, the Taxonomies provide a semantic layer overarching the content layer.

So far this discussion has focussed on fast and efficient content representation for Pages using hashes. And although the hashes lend themselves fairly well for direct 1-on-1 document comparison, just tagging on Taxonomies in a sorted/weighted fashion feels extremely kludgy.

If I get the SimHash function right, the hash of two documents appended should be the same as/extremely close to the sum/average of the individual hashes (like `2 * hash("doc A doc B") == hash("doc A") + hash("doc B")`). It might be a weighted sum, but in any case it is very simple and instantly computed.

Taxonomy Terms provide a way for the authors to organise/segment their pages. As a result, each term defines a subset of all pages. So a natural representation for a Term would then be the sum of the content hashes of pages in its subset. The resulting hash is the content representation for that term.

Assuming the site defines N taxonomy terms, we can compare each page hash to N term hashes, creating a new representation for pages as vectors of length N. It tells you how much the post relates to each semantic concept.

Now, instead of comparing two document hashes, one would compare two N-vectors. I think cosine-similarity is a good metric here which is fast (not as fast as Hamming distance). In any case, this should be a much more natural way to incorporate the taxonomy structure in the “page relatedness” measure.

I think the overhead will be small compared to the improvement of related documents, but I understand Hugo’s focus is on speed. Just wanted to share the idea.

---

<div class="post-metadata">

**Author:** ![andreyg](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/andreyg/32/2384_2.png) [@andreyg](https://discourse.gohugo.io/u/andreyg)\
**Post date:** [January 8, 2017, 3:20am UTC](https://discourse.gohugo.io/t/related-content/169/23 "2017-01-08T03:20:07Z")

</div>

Hey @bep, has anyone taken care of this feature?

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [January 8, 2017, 9:25am UTC](https://discourse.gohugo.io/t/related-content/169/24 "2017-01-08T09:25:08Z")

</div>

No…

---

<div class="post-metadata">

**Author:** ![andreyg](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/andreyg/32/2384_2.png) [@andreyg](https://discourse.gohugo.io/u/andreyg)\
**Post date:** [January 8, 2017, 7:00pm UTC](https://discourse.gohugo.io/t/related-content/169/25 "2017-01-08T19:00:10Z")

</div>

@bep mind to point to the right place in code as a starting point? I keep migrating my website to Hugo and I need this feature. I’ll see if I can implement it.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [January 8, 2017, 7:28pm UTC](https://discourse.gohugo.io/t/related-content/169/26 "2017-01-08T19:28:34Z")

</div>

> [@andreyg](#):
>
> as a starting point?

`hugolib.Page` – but this is a hard task to get right (it has been discussed before). Finding the correct “starting point” is the trivial part.

I suggest that you sketch a plan/design and discuss it here before you spend too much time implementing something.

---

<div class="post-metadata">

**Author:** ![andreyg](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/andreyg/32/2384_2.png) [@andreyg](https://discourse.gohugo.io/u/andreyg)\
**Post date:** [January 8, 2017, 8:36pm UTC](https://discourse.gohugo.io/t/related-content/169/27 "2017-01-08T20:36:54Z")

</div>

@bep sounds good. Thank you.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [August 31, 2017, 7:49am UTC](https://discourse.gohugo.io/t/related-content/169/28 "2017-08-31T07:49:16Z")

</div>

See (and comment if you want) on this:

[https://github.com/gohugoio/hugo/pull/3815#issuecomment-326216823](https://github.com/gohugoio/hugo/pull/3815#issuecomment-326216823)

[Previous page](https://discourse.gohugo.io/t/related-content/169.md?page=1)
