{"id":13696076,"url":"https://github.com/pelican-plugins/similar-posts","last_synced_at":"2025-10-27T14:31:15.361Z","repository":{"id":52542681,"uuid":"140533417","full_name":"pelican-plugins/similar-posts","owner":"pelican-plugins","description":"Pelican plugin to list similar posts to articles, based on a vector space model.","archived":false,"fork":false,"pushed_at":"2024-12-31T12:00:45.000Z","size":53,"stargazers_count":19,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-07T05:31:17.273Z","etag":null,"topics":["blog","gensim","pelican","pelican-plugins","python","similarity","tags","tf-idf"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pelican-plugins.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"justinmayer","liberapay":"pelican"}},"created_at":"2018-07-11T06:46:59.000Z","updated_at":"2025-07-26T14:21:08.000Z","dependencies_parsed_at":"2024-04-08T02:51:09.172Z","dependency_job_id":"84ce37a5-9be2-496b-9e79-025da264d5f1","html_url":"https://github.com/pelican-plugins/similar-posts","commit_stats":{"total_commits":27,"total_committers":4,"mean_commits":6.75,"dds":"0.37037037037037035","last_synced_commit":"6b660bcbc9546fb096409c8a343e7556df1141dc"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pelican-plugins/similar-posts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fsimilar-posts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fsimilar-posts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fsimilar-posts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fsimilar-posts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pelican-plugins","download_url":"https://codeload.github.com/pelican-plugins/similar-posts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pelican-plugins%2Fsimilar-posts/sbom","scorecard":{"id":726834,"data":{"date":"2025-08-11","repo":{"name":"github.com/pelican-plugins/similar-posts","commit":"033df772aec10b9b4db8152f5841918e8ee315ed"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/23 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/main.yml:58","Warn: no topLevel permission defined: .github/workflows/main.yml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/similar-posts/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/similar-posts/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/similar-posts/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/similar-posts/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/similar-posts/main.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:67: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/similar-posts/main.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:90: update your workflow using https://app.stepsecurity.io/secureworkflow/pelican-plugins/similar-posts/main.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:74","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:75","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/main.yml:50"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 1.0.0 not signed: https://api.github.com/repos/pelican-plugins/similar-posts/releases/34250528","Warn: release artifact 1.0.0 does not have provenance: https://api.github.com/repos/pelican-plugins/similar-posts/releases/34250528"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 9 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T13:04:14.877Z","repository_id":52542681,"created_at":"2025-08-22T13:04:14.878Z","updated_at":"2025-08-22T13:04:14.878Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281130785,"owners_count":26448694,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-26T02:00:06.575Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blog","gensim","pelican","pelican-plugins","python","similarity","tags","tf-idf"],"created_at":"2024-08-02T18:00:36.072Z","updated_at":"2025-10-27T14:31:15.016Z","avatar_url":"https://github.com/pelican-plugins.png","language":"Python","funding_links":["https://github.com/sponsors/justinmayer","https://liberapay.com/pelican"],"categories":["Plugins"],"sub_categories":["Migrated to new architecture"],"readme":"Similar Posts: A Plugin for Pelican\n===================================\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/pelican-plugins/similar-posts/main.yml?branch=main)](https://github.com/pelican-plugins/similar-posts/actions)\n[![PyPI Version](https://img.shields.io/pypi/v/pelican-similar-posts)](https://pypi.org/project/pelican-similar-posts/)\n[![Downloads](https://img.shields.io/pypi/dm/pelican-similar-posts)](https://pypi.org/project/pelican-similar-posts/)\n![License](https://img.shields.io/pypi/l/pelican-similar-posts?color=blue)\n\n**Similar Posts** is a [Pelican](https://getpelican.com/) plugin that adds the `similar_posts` variable to every published article's context.\n\nThe inputs to the similarity measurement algorithm are article tags. Thus, for this plugin to be of any use, at least some of your articles must have a `tags` element in their [metadata](http://docs.getpelican.com/en/stable/content.html#file-metadata).\n\nThe `similar_posts` variable is a list of `Article` objects, or an empty list if no articles could be found with at least one tag in common with the given article. The list is sorted by descending similarity, then by descending date.\n\nRequirements\n------------\n\nThis plugin is compatible with Python 3.9 through 3.12. Python 3.13+ is not currently supported due to incompatibilities with one or more of the dependencies listed below.\n\nIt depends on [Gensim](https://radimrehurek.com/gensim/index.html), which has its own dependencies such as [NumPy](http://www.numpy.org/), [SciPy](https://www.scipy.org/), and [`smart_open`](https://pypi.org/project/smart_open/).\n\nInstallation\n------------\n\nThis plugin can be installed via:\n\n    python -m pip install pelican-similar-posts\n\nAs long as you have not explicitly added a `PLUGINS` setting to your Pelican settings file, then the newly-installed plugin should be automatically detected and enabled. Otherwise, you must add `similar_posts` to your existing `PLUGINS` list. For more information, please see the [How to Use Plugins](https://docs.getpelican.com/en/latest/plugins.html#how-to-use-plugins) documentation.\n\nConfiguration\n-------------\n\nBy default, up to five articles are listed. You may customize this value by defining `SIMILAR_POSTS_MAX_COUNT` in your Pelican settings file. For example:\n\n```python\nSIMILAR_POSTS_MAX_COUNT = 10\n```\n\nYou may also define `SIMILAR_POSTS_MIN_SCORE` in the settings file. It defaults to .0001. A value of 1.0 would restrict the list of similar posts to articles that have the same set of tags. Any value greater than 0.0 acts as a similarity threshold, but to play with this you'll probably have to find a proper value empirically. When running Pelican with the `--debug` option, extra messages show the scores of the similar posts.\n\nYou can output the `similar_posts` variable in your article template. This might look like the following:\n\n```html+jinja\n{% if article.similar_posts %}\n    \u003cul\u003e\n    {% for similar in article.similar_posts %}\n        \u003cli\u003e\u003ca href=\"{{ SITEURL }}/{{ similar.url }}\"\u003e{{ similar.title }}\u003c/a\u003e\u003c/li\u003e\n    {% endfor %}\n    \u003c/ul\u003e\n{% endif %}\n```\n\nSimilarity Score\n----------------\n\nThe measure of similarity is based on the [vector space model](https://en.wikipedia.org/wiki/Vector_space_model), which represents text documents as vectors. Each vector component corresponds to one of the terms that exists in the corpus. Thus the corpus may be represented as a matrix whose lines correspond to documents, and whose columns correspond to terms.\n\nIn this implementation, terms (tags) are weighted using the [tf-idf model](https://en.wikipedia.org/wiki/Tf–idf), which essentially means that terms that are rare across the whole corpus have greater values than those that are very common. The idea is that a term that is present in a great number of documents does not provide much specificity; it does not help relate a document to another in particular as much as a term that occurs in only a few documents.\n\nSay we have a corpus with five terms. A document's vector might look like:\n\n    [.9, .1, .0, .0, .3]\n\nThis document has three terms. The first one has a high value, meaning it is relatively rare across the whole corpus. The second one has a low value, meaning it is much more common. The next two terms are absent from this document, while the last term is present and also somewhat common in the corpus, although not as common as the second term. If, for example, another document contains only the first and last terms, it should be considered more relevant to this document than another that would have just the first and second terms, or just the second and last terms.\n\nWe measure the similarity of two documents by computing the cosine of the angle between their unit vectors. The resulting \"score\" is bounded in [0, 1]. Two vectors with the same orientation have a [cosine similarity](https://en.wikipedia.org/wiki/Cosine_similarity) of 1. The lower the value, the greater the angle between the vectors; the more \"dissimilar\" the documents are.\n\nComparison with the *Related Posts* plugin\n------------------------------------------\n\nThe [Related Posts plugin](https://github.com/pelican-plugins/related-posts) relates articles that have the greatest number of tags in common, without any tag weighting. If many articles match with the same number of tags, they all get the same score. On most web sites, the list of recommended articles is short, so the most relevant ones will often be left out if all have the same score.\n\nPerhaps to circumvent this problem, the plugin allows one to manually link related posts by slug. However, that creates a content maintenance burden; old posts will not link to newer ones, unless they are manually edited to add them.\n\nContributing\n------------\n\nContributions are welcome and much appreciated. Every little bit helps. You can contribute by improving the documentation, adding missing features, and fixing bugs. You can also help out by reviewing and commenting on [existing issues][].\n\nTo start contributing to this plugin, review the [Contributing to Pelican][] documentation, beginning with the **Contributing Code** section.\n\n[existing issues]: https://github.com/pelican-plugins/similar-posts/issues\n[Contributing to Pelican]: https://docs.getpelican.com/en/latest/contribute.html\n\nLicense\n-------\n\nThis project is licensed under the General Public License (GPL) 3.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpelican-plugins%2Fsimilar-posts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpelican-plugins%2Fsimilar-posts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpelican-plugins%2Fsimilar-posts/lists"}