mirror of
https://github.com/sissbruecker/linkding.git
synced 2026-03-06 18:03:14 +08:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1dd85538b | ||
|
|
c5aab3886e | ||
|
|
3f2739e5a6 | ||
|
|
f1ed89a0ba | ||
|
|
a59a7a777c | ||
|
|
9a5c535872 | ||
|
|
e6ebca1436 | ||
|
|
085d67e9f4 | ||
|
|
68825444fb | ||
|
|
b2ca16ec9c | ||
|
|
649f4154e5 | ||
|
|
d2e8a95e3c | ||
|
|
c3149409b0 | ||
|
|
4626fa1c67 | ||
|
|
6548e16baa | ||
|
|
c177de164a | ||
|
|
e9ecad38ac | ||
|
|
621aedd8eb | ||
|
|
4187141ac8 |
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,6 +1,31 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## (23/09/2024)
|
## v1.36.0 (02/10/2024)
|
||||||
|
|
||||||
|
### What's Changed
|
||||||
|
* Replace uBlock Origin with uBlock Origin Lite by @sissbruecker in https://github.com/sissbruecker/linkding/pull/866
|
||||||
|
* Add LAST_MODIFIED attribute when exporting by @ixzhao in https://github.com/sissbruecker/linkding/pull/860
|
||||||
|
* Return client error status code for invalid form submissions by @sissbruecker in https://github.com/sissbruecker/linkding/pull/849
|
||||||
|
* Fix header.svg text by @vladh in https://github.com/sissbruecker/linkding/pull/850
|
||||||
|
* Do not clear fields in POST requests (API behavior change) by @sissbruecker in https://github.com/sissbruecker/linkding/pull/852
|
||||||
|
* Prevent duplicates when editing by @sissbruecker in https://github.com/sissbruecker/linkding/pull/853
|
||||||
|
* Fix jumping details modal on back navigation by @sissbruecker in https://github.com/sissbruecker/linkding/pull/854
|
||||||
|
* Fix select dropdown menu background in dark theme by @sissbruecker in https://github.com/sissbruecker/linkding/pull/858
|
||||||
|
* Do not escape valid characters in custom CSS by @sissbruecker in https://github.com/sissbruecker/linkding/pull/863
|
||||||
|
* Simplify Docker build by @sissbruecker in https://github.com/sissbruecker/linkding/pull/865
|
||||||
|
* Improve error handling for auto tagging by @sissbruecker in https://github.com/sissbruecker/linkding/pull/855
|
||||||
|
* Bump rollup from 4.13.0 to 4.22.4 by @dependabot in https://github.com/sissbruecker/linkding/pull/851
|
||||||
|
* Bump rollup from 4.21.3 to 4.22.4 in /docs by @dependabot in https://github.com/sissbruecker/linkding/pull/856
|
||||||
|
|
||||||
|
### New Contributors
|
||||||
|
* @vladh made their first contribution in https://github.com/sissbruecker/linkding/pull/850
|
||||||
|
* @ixzhao made their first contribution in https://github.com/sissbruecker/linkding/pull/860
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/sissbruecker/linkding/compare/v1.35.0...v1.36.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v1.35.0 (23/09/2024)
|
||||||
|
|
||||||
### What's Changed
|
### What's Changed
|
||||||
* Add configuration options for pagination by @sissbruecker in https://github.com/sissbruecker/linkding/pull/835
|
* Add configuration options for pagination by @sissbruecker in https://github.com/sissbruecker/linkding/pull/835
|
||||||
|
|||||||
@@ -6,23 +6,38 @@ class DropdownBehavior extends Behavior {
|
|||||||
this.opened = false;
|
this.opened = false;
|
||||||
this.onClick = this.onClick.bind(this);
|
this.onClick = this.onClick.bind(this);
|
||||||
this.onOutsideClick = this.onOutsideClick.bind(this);
|
this.onOutsideClick = this.onOutsideClick.bind(this);
|
||||||
|
this.onEscape = this.onEscape.bind(this);
|
||||||
|
this.onFocusOut = this.onFocusOut.bind(this);
|
||||||
|
|
||||||
|
// Prevent opening the dropdown automatically on focus, so that it only
|
||||||
|
// opens on click then JS is enabled
|
||||||
|
this.element.style.setProperty("--dropdown-focus-display", "none");
|
||||||
|
this.element.addEventListener("keydown", this.onEscape);
|
||||||
|
this.element.addEventListener("focusout", this.onFocusOut);
|
||||||
|
|
||||||
this.toggle = element.querySelector(".dropdown-toggle");
|
this.toggle = element.querySelector(".dropdown-toggle");
|
||||||
|
this.toggle.setAttribute("aria-expanded", "false");
|
||||||
this.toggle.addEventListener("click", this.onClick);
|
this.toggle.addEventListener("click", this.onClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.close();
|
this.close();
|
||||||
this.toggle.removeEventListener("click", this.onClick);
|
this.toggle.removeEventListener("click", this.onClick);
|
||||||
|
this.element.removeEventListener("keydown", this.onEscape);
|
||||||
|
this.element.removeEventListener("focusout", this.onFocusOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
|
this.opened = true;
|
||||||
this.element.classList.add("active");
|
this.element.classList.add("active");
|
||||||
|
this.toggle.setAttribute("aria-expanded", "true");
|
||||||
document.addEventListener("click", this.onOutsideClick);
|
document.addEventListener("click", this.onOutsideClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
|
this.opened = false;
|
||||||
this.element.classList.remove("active");
|
this.element.classList.remove("active");
|
||||||
|
this.toggle.setAttribute("aria-expanded", "false");
|
||||||
document.removeEventListener("click", this.onOutsideClick);
|
document.removeEventListener("click", this.onOutsideClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +54,20 @@ class DropdownBehavior extends Behavior {
|
|||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEscape(event) {
|
||||||
|
if (event.key === "Escape" && this.opened) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.close();
|
||||||
|
this.toggle.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocusOut(event) {
|
||||||
|
if (!this.element.contains(event.relatedTarget)) {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerBehavior("ld-dropdown", DropdownBehavior);
|
registerBehavior("ld-dropdown", DropdownBehavior);
|
||||||
|
|||||||
2
bookmarks/static/robots.txt
Normal file
2
bookmarks/static/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
/* Dropdown */
|
/* Dropdown */
|
||||||
.dropdown {
|
.dropdown {
|
||||||
|
--dropdown-focus-display: block;
|
||||||
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@@ -20,9 +22,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active .menu,
|
&:focus-within .menu {
|
||||||
.dropdown-toggle:focus + .menu,
|
/* Use custom CSS property to allow disabling opening on focus when using JS */
|
||||||
.menu:hover {
|
display: var(--dropdown-focus-display);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active .menu {
|
||||||
|
/* Always show menu when class is added through JS */
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
{# Basic menu list #}
|
{# Basic menu list #}
|
||||||
<div class="hide-md">
|
<div class="hide-md">
|
||||||
<a href="{% url 'bookmarks:new' %}" class="btn btn-primary mr-2">Add bookmark</a>
|
<a href="{% url 'bookmarks:new' %}" class="btn btn-primary mr-2">Add bookmark</a>
|
||||||
<div class="dropdown">
|
<div ld-dropdown class="dropdown">
|
||||||
<button class="btn btn-link dropdown-toggle" tabindex="0">
|
<button class="btn btn-link dropdown-toggle" tabindex="0">
|
||||||
Bookmarks
|
Bookmarks
|
||||||
</button>
|
</button>
|
||||||
<ul class="menu">
|
<ul class="menu" role="list">
|
||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<a href="{% url 'bookmarks:index' %}" class="menu-link">Active</a>
|
<a href="{% url 'bookmarks:index' %}" class="menu-link">Active</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<!-- menu component -->
|
<!-- menu component -->
|
||||||
<ul class="menu">
|
<ul class="menu" role="list">
|
||||||
<li class="menu-item">
|
<li class="menu-item">
|
||||||
<a href="{% url 'bookmarks:index' %}" class="menu-link">Bookmarks</a>
|
<a href="{% url 'bookmarks:index' %}" class="menu-link">Bookmarks</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</form>
|
</form>
|
||||||
<div ld-dropdown class="search-options dropdown dropdown-right">
|
<div ld-dropdown class="search-options dropdown dropdown-right">
|
||||||
<button type="button" class="btn dropdown-toggle{% if search.has_modified_preferences %} badge{% endif %}">
|
<button type="button" aria-label="Search preferences"
|
||||||
|
class="btn dropdown-toggle{% if search.has_modified_preferences %} badge{% endif %}">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" stroke-width="2"
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" stroke-width="2"
|
||||||
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
@@ -41,8 +42,11 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if 'shared' in preferences_form.editable_fields %}
|
{% if 'shared' in preferences_form.editable_fields %}
|
||||||
<div class="form-group radio-group">
|
<div class="form-group radio-group" role="radiogroup" aria-labelledby="search-shared-label">
|
||||||
<div class="form-label{% if 'shared' in search.modified_params %} text-bold{% endif %}">Shared filter</div>
|
<label id="search-shared-label"
|
||||||
|
class="form-label{% if 'shared' in search.modified_params %} text-bold{% endif %}">
|
||||||
|
Shared filter
|
||||||
|
</label>
|
||||||
{% for radio in preferences_form.shared %}
|
{% for radio in preferences_form.shared %}
|
||||||
<label for="{{ radio.id_for_label }}" class="form-radio form-inline">
|
<label for="{{ radio.id_for_label }}" class="form-radio form-inline">
|
||||||
{{ radio.tag }}
|
{{ radio.tag }}
|
||||||
@@ -53,8 +57,11 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if 'unread' in preferences_form.editable_fields %}
|
{% if 'unread' in preferences_form.editable_fields %}
|
||||||
<div class="form-group radio-group">
|
<div class="form-group radio-group" role="radiogroup" aria-labelledby="search-unread-label">
|
||||||
<div class="form-label{% if 'unread' in search.modified_params %} text-bold{% endif %}">Unread filter</div>
|
<label id="search-unread-label"
|
||||||
|
class="form-label{% if 'unread' in search.modified_params %} text-bold{% endif %}">
|
||||||
|
Unread filter
|
||||||
|
</label>
|
||||||
{% for radio in preferences_form.unread %}
|
{% for radio in preferences_form.unread %}
|
||||||
<label for="{{ radio.id_for_label }}" class="form-radio form-inline">
|
<label for="{{ radio.id_for_label }}" class="form-radio form-inline">
|
||||||
{{ radio.tag }}
|
{{ radio.tag }}
|
||||||
|
|||||||
@@ -71,19 +71,15 @@ class BookmarkSearchTagTest(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
|
|||||||
radios = form.select(f'input[name="{name}"][type="radio"]')
|
radios = form.select(f'input[name="{name}"][type="radio"]')
|
||||||
self.assertTrue(len(radios) == 0)
|
self.assertTrue(len(radios) == 0)
|
||||||
|
|
||||||
def assertUnmodifiedLabel(self, html: str, text: str, id: str = ""):
|
def assertUnmodifiedLabel(self, html: str, text: str):
|
||||||
id_attr = f'for="{id}"' if id else ""
|
soup = self.make_soup(html)
|
||||||
tag = "label" if id else "div"
|
label = soup.find("label", string=lambda s: s and s.strip() == text)
|
||||||
needle = f'<{tag} class="form-label" {id_attr}>{text}</{tag}>'
|
self.assertEqual(label["class"], ["form-label"])
|
||||||
|
|
||||||
self.assertInHTML(needle, html)
|
def assertModifiedLabel(self, html: str, text: str):
|
||||||
|
soup = self.make_soup(html)
|
||||||
def assertModifiedLabel(self, html: str, text: str, id: str = ""):
|
label = soup.find("label", string=lambda s: s and s.strip() == text)
|
||||||
id_attr = f'for="{id}"' if id else ""
|
self.assertEqual(label["class"], ["form-label", "text-bold"])
|
||||||
tag = "label" if id else "div"
|
|
||||||
needle = f'<{tag} class="form-label text-bold" {id_attr}>{text}</{tag}>'
|
|
||||||
|
|
||||||
self.assertInHTML(needle, html)
|
|
||||||
|
|
||||||
def test_search_form_inputs(self):
|
def test_search_form_inputs(self):
|
||||||
# Without params
|
# Without params
|
||||||
@@ -190,54 +186,53 @@ class BookmarkSearchTagTest(TestCase, BookmarkFactoryMixin, HtmlTestMixin):
|
|||||||
# Without modifications
|
# Without modifications
|
||||||
url = "/test"
|
url = "/test"
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
|
soup = self.make_soup(rendered_template)
|
||||||
|
button = soup.select_one("button[aria-label='Search preferences']")
|
||||||
|
|
||||||
self.assertIn(
|
self.assertNotIn("badge", button["class"])
|
||||||
'<button type="button" class="btn dropdown-toggle">', rendered_template
|
|
||||||
)
|
|
||||||
|
|
||||||
# With modifications
|
# With modifications
|
||||||
url = "/test?sort=title_asc"
|
url = "/test?sort=title_asc"
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
|
soup = self.make_soup(rendered_template)
|
||||||
|
button = soup.select_one("button[aria-label='Search preferences']")
|
||||||
|
|
||||||
self.assertIn(
|
self.assertIn("badge", button["class"])
|
||||||
'<button type="button" class="btn dropdown-toggle badge">',
|
|
||||||
rendered_template,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Ignores non-preferences modifications
|
# Ignores non-preferences modifications
|
||||||
url = "/test?q=foo&user=john"
|
url = "/test?q=foo&user=john"
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
|
soup = self.make_soup(rendered_template)
|
||||||
|
button = soup.select_one("button[aria-label='Search preferences']")
|
||||||
|
|
||||||
self.assertIn(
|
self.assertNotIn("badge", button["class"])
|
||||||
'<button type="button" class="btn dropdown-toggle">', rendered_template
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_modified_labels(self):
|
def test_modified_labels(self):
|
||||||
# Without modifications
|
# Without modifications
|
||||||
url = "/test"
|
url = "/test"
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
|
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Sort by", "id_sort")
|
self.assertUnmodifiedLabel(rendered_template, "Sort by")
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Shared filter")
|
self.assertUnmodifiedLabel(rendered_template, "Shared filter")
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Unread filter")
|
self.assertUnmodifiedLabel(rendered_template, "Unread filter")
|
||||||
|
|
||||||
# Modified sort
|
# Modified sort
|
||||||
url = "/test?sort=title_asc"
|
url = "/test?sort=title_asc"
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
self.assertModifiedLabel(rendered_template, "Sort by", "id_sort")
|
self.assertModifiedLabel(rendered_template, "Sort by")
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Shared filter")
|
self.assertUnmodifiedLabel(rendered_template, "Shared filter")
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Unread filter")
|
self.assertUnmodifiedLabel(rendered_template, "Unread filter")
|
||||||
|
|
||||||
# Modified shared
|
# Modified shared
|
||||||
url = "/test?shared=yes"
|
url = "/test?shared=yes"
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Sort by", "id_sort")
|
self.assertUnmodifiedLabel(rendered_template, "Sort by")
|
||||||
self.assertModifiedLabel(rendered_template, "Shared filter")
|
self.assertModifiedLabel(rendered_template, "Shared filter")
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Unread filter")
|
self.assertUnmodifiedLabel(rendered_template, "Unread filter")
|
||||||
|
|
||||||
# Modified unread
|
# Modified unread
|
||||||
url = "/test?unread=yes"
|
url = "/test?unread=yes"
|
||||||
rendered_template = self.render_template(url)
|
rendered_template = self.render_template(url)
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Sort by", "id_sort")
|
self.assertUnmodifiedLabel(rendered_template, "Sort by")
|
||||||
self.assertUnmodifiedLabel(rendered_template, "Shared filter")
|
self.assertUnmodifiedLabel(rendered_template, "Shared filter")
|
||||||
self.assertModifiedLabel(rendered_template, "Unread filter")
|
self.assertModifiedLabel(rendered_template, "Unread filter")
|
||||||
|
|||||||
1199
docs/package-lock.json
generated
1199
docs/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/check": "^0.9.3",
|
"@astrojs/check": "^0.9.3",
|
||||||
"@astrojs/starlight": "^0.27.1",
|
"@astrojs/starlight": "^0.27.1",
|
||||||
"astro": "^4.15.8",
|
"astro": "^4.16.18",
|
||||||
"sharp": "^0.32.5",
|
"sharp": "^0.32.5",
|
||||||
"typescript": "^5.6.2"
|
"typescript": "^5.6.2"
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 189 KiB After Width: | Height: | Size: 189 KiB |
BIN
docs/public/donations/2024-10-04-django.png
Normal file
BIN
docs/public/donations/2024-10-04-django.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
BIN
docs/public/donations/2024-10-04-internet-archive.png
Normal file
BIN
docs/public/donations/2024-10-04-internet-archive.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 223 KiB |
BIN
docs/public/donations/2024-10-04-noyb.png
Normal file
BIN
docs/public/donations/2024-10-04-noyb.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
BIN
docs/public/donations/2024-10-04-singlefile.png
Normal file
BIN
docs/public/donations/2024-10-04-singlefile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
@@ -9,9 +9,35 @@ description: "Acknowledgements and thanks to contributors and sponsors"
|
|||||||
|
|
||||||
See the table below for a list of donations.
|
See the table below for a list of donations.
|
||||||
|
|
||||||
| Source | Description | Amount | Donated to |
|
<table>
|
||||||
|---------------------------------------|---------------------------------------------|---------|------------------------------------------------------------------|
|
<thead>
|
||||||
| [PikaPods](https://www.pikapods.com/) | Linkding hosting June 2022 - September 2023 | $163.50 | [Internet Archive](/2023-10-11-internet-archive.png) |
|
<tr>
|
||||||
|
<th>Source</th>
|
||||||
|
<th>Description</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
<th>Donated to</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://www.pikapods.com/">PikaPods</a></td>
|
||||||
|
<td>Linkding hosting June 2022 - September 2023</td>
|
||||||
|
<td>$163.50</td>
|
||||||
|
<td><a href="/donations/2023-10-11-internet-archive.png">Internet Archive</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><a href="https://www.pikapods.com/">PikaPods</a></td>
|
||||||
|
<td>Linkding hosting October 2023 - September 2024</td>
|
||||||
|
<td>$287.04</td>
|
||||||
|
<td>
|
||||||
|
<a href="/donations/2024-10-04-django.png">Django</a><br>
|
||||||
|
<a href="/donations/2024-10-04-singlefile.png">SingleFile</a><br>
|
||||||
|
<a href="/donations/2024-10-04-internet-archive.png">Internet Archive</a><br>
|
||||||
|
<a href="/donations/2024-10-04-noyb.png">NOYB</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
## JetBrains
|
## JetBrains
|
||||||
|
|
||||||
|
|||||||
@@ -6,17 +6,23 @@ description: "Community projects around linkding"
|
|||||||
This section lists community projects around using linkding, in alphabetical order. If you have a project that you want to share with the linkding community, feel free to [submit a PR](https://github.com/sissbruecker/linkding/edit/master/docs/src/content/docs/community.md) to add your project to this section.
|
This section lists community projects around using linkding, in alphabetical order. If you have a project that you want to share with the linkding community, feel free to [submit a PR](https://github.com/sissbruecker/linkding/edit/master/docs/src/content/docs/community.md) to add your project to this section.
|
||||||
|
|
||||||
- [aiolinkding](https://github.com/bachya/aiolinkding) A Python3, async library to interact with the linkding REST API. By [bachya](https://github.com/bachya)
|
- [aiolinkding](https://github.com/bachya/aiolinkding) A Python3, async library to interact with the linkding REST API. By [bachya](https://github.com/bachya)
|
||||||
|
- [cosmicding](https://github.com/vkhitrin/cosmicding) Desktop client built using [libcosmic](https://github.com/pop-os/libcosmic). By [vkhitrin](https://github.com/vkhitrin)
|
||||||
- [feed2linkding](https://codeberg.org/strubbl/feed2linkding) A commandline utility to add all web feed item links to linkding via API call. By [Strubbl](https://github.com/Strubbl)
|
- [feed2linkding](https://codeberg.org/strubbl/feed2linkding) A commandline utility to add all web feed item links to linkding via API call. By [Strubbl](https://github.com/Strubbl)
|
||||||
- [go-linkding](https://github.com/piero-vic/go-linkding) A Go client library to interact with the linkding REST API. By [piero-vic](https://github.com/piero-vic)
|
- [go-linkding](https://github.com/piero-vic/go-linkding) A Go client library to interact with the linkding REST API. By [piero-vic](https://github.com/piero-vic)
|
||||||
- [Helm Chart](https://charts.pascaliske.dev/charts/linkding/) Helm Chart for deploying linkding inside a Kubernetes cluster. By [pascaliske](https://github.com/pascaliske)
|
- [Helm Chart](https://charts.pascaliske.dev/charts/linkding/) Helm Chart for deploying linkding inside a Kubernetes cluster. By [pascaliske](https://github.com/pascaliske)
|
||||||
- [iOS Shortcut using API and Tagging](https://gist.github.com/andrewdolphin/a7dff49505e588d940bec55132fab8ad) An iOS shortcut using the Linkding API (no extra logins required) that pulls previously used tags and allows tagging at the time of link creation.
|
- [iOS Shortcut using API and Tagging](https://gist.github.com/andrewdolphin/a7dff49505e588d940bec55132fab8ad) An iOS shortcut using the Linkding API (no extra logins required) that pulls previously used tags and allows tagging at the time of link creation.
|
||||||
- [k8s + s3](https://github.com/jzck/linkding-k8s-s3) - Setup for hosting stateless linkding on k8s with sqlite replicated to s3. By [jzck](https://github.com/jzck)
|
- [k8s + s3](https://github.com/jzck/linkding-k8s-s3) - Setup for hosting stateless linkding on k8s with sqlite replicated to s3. By [jzck](https://github.com/jzck)
|
||||||
- [Linka!](https://github.com/cmsax/linka) Web app (also a PWA) for quickly searching & opening bookmarks in linkding, support multi keywords, exclude mode and other advance options. By [cmsax](https://github.com/cmsax)
|
- [Linka!](https://github.com/cmsax/linka) Web app (also a PWA) for quickly searching & opening bookmarks in linkding, support multi keywords, exclude mode and other advance options. By [cmsax](https://github.com/cmsax)
|
||||||
|
- [linkding-archiver](https://github.com/sebw/linkding-archiver) A Python application that integrates with SingleFile and Tube Archivist to archive your links and videos. By [sebw](https://github.com/sebw)
|
||||||
- [linkding-cli](https://github.com/bachya/linkding-cli) A command-line interface (CLI) to interact with the linkding REST API. Powered by [aiolinkding](https://github.com/bachya/aiolinkding). By [bachya](https://github.com/bachya)
|
- [linkding-cli](https://github.com/bachya/linkding-cli) A command-line interface (CLI) to interact with the linkding REST API. Powered by [aiolinkding](https://github.com/bachya/aiolinkding). By [bachya](https://github.com/bachya)
|
||||||
- [linkding-extension](https://github.com/jeroenpardon/linkding-extension) Chromium compatible extension that wraps the linkding bookmarklet. Tested with Chrome, Edge, Brave. By [jeroenpardon](https://github.com/jeroenpardon)
|
- [linkding-extension](https://github.com/jeroenpardon/linkding-extension) Chromium compatible extension that wraps the linkding bookmarklet. Tested with Chrome, Edge, Brave. By [jeroenpardon](https://github.com/jeroenpardon)
|
||||||
|
- [linkding-healthcheck](https://github.com/sebw/linkding-healthcheck) A Go application that checks the health of your bookmarks and add a tag on dead and problematic URLs. By [sebw](https://github.com/sebw)
|
||||||
- [linkding-injector](https://github.com/Fivefold/linkding-injector) Injects search results from linkding into the sidebar of search pages like google and duckduckgo. Tested with Firefox and Chrome. By [Fivefold](https://github.com/Fivefold)
|
- [linkding-injector](https://github.com/Fivefold/linkding-injector) Injects search results from linkding into the sidebar of search pages like google and duckduckgo. Tested with Firefox and Chrome. By [Fivefold](https://github.com/Fivefold)
|
||||||
- [Linkdy](https://github.com/JGeek00/linkdy): An open source mobile and desktop (not yet) client created with Flutter. Available at the [Google Play Store](https://play.google.com/store/apps/details?id=com.jgeek00.linkdy). By [JGeek00](https://github.com/JGeek00).
|
- [linkding-reminder](https://github.com/sebw/linkding-reminder) A Python application that will send an email reminder for links with a specific tag. By [sebw](https://github.com/sebw)
|
||||||
|
- [linkding-rs](https://github.com/zbrox/linkding-rs) A Rust client library to interact with the linkding REST API with cross platform support to be easily used in Android or iOS apps. By [zbrox](https://github.com/zbrox)
|
||||||
|
- [Linkdy](https://github.com/JGeek00/linkdy): An open-source Android and iOS client created with Flutter. Available on the [Google Play Store](https://play.google.com/store/apps/details?id=com.jgeek00.linkdy) and [App Store](https://apps.apple.com/us/app/linkdy/id6479930976). By [JGeek00](https://github.com/JGeek00).
|
||||||
- [LinkThing](https://apps.apple.com/us/app/linkthing/id1666031776) An iOS client for linkding. By [amoscardino](https://github.com/amoscardino)
|
- [LinkThing](https://apps.apple.com/us/app/linkthing/id1666031776) An iOS client for linkding. By [amoscardino](https://github.com/amoscardino)
|
||||||
- [Open all links bookmarklet](https://gist.github.com/ukcuddlyguy/336dd7339e6d35fc64a75ccfc9323c66) A browser bookmarklet to open all links on the current Linkding page in new tabs. By [ukcuddlyguy](https://github.com/ukcuddlyguy)
|
- [Open all links bookmarklet](https://gist.github.com/ukcuddlyguy/336dd7339e6d35fc64a75ccfc9323c66) A browser bookmarklet to open all links on the current Linkding page in new tabs. By [ukcuddlyguy](https://github.com/ukcuddlyguy)
|
||||||
- [Pinkt](https://github.com/fibelatti/pinboard-kotlin) An Android client for linkding. By [fibelatti](https://github.com/fibelatti)
|
- [Pinkt](https://github.com/fibelatti/pinboard-kotlin) An Android client for linkding. By [fibelatti](https://github.com/fibelatti)
|
||||||
- [Postman collection](https://gist.github.com/gingerbeardman/f0b42502f3bc9344e92ce63afd4360d3) a group of saved request templates for API testing. By [gingerbeardman](https://github.com/gingerbeardman)
|
- [Postman collection](https://gist.github.com/gingerbeardman/f0b42502f3bc9344e92ce63afd4360d3) a group of saved request templates for API testing. By [gingerbeardman](https://github.com/gingerbeardman)
|
||||||
|
- [serchding](https://github.com/ldwgchen/serchding) Full-text search for linkding. By [ldwgchen](https://github.com/ldwgchen)
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ You can also check the [Community section](/community) for other pre-made shortc
|
|||||||
The font size can be adjusted globally by adding the following CSS to the custom CSS field in the settings:
|
The font size can be adjusted globally by adding the following CSS to the custom CSS field in the settings:
|
||||||
|
|
||||||
```css
|
```css
|
||||||
html {
|
:root {
|
||||||
--font-size: 0.75rem;
|
--font-size: 0.75rem;
|
||||||
--font-size-sm: 0.7rem;
|
--font-size-sm: 0.7rem;
|
||||||
--font-size-lg: 0.9rem;
|
--font-size-lg: 0.9rem;
|
||||||
|
|||||||
@@ -268,3 +268,9 @@ When creating HTML archive snapshots, pass additional options to the `single-fil
|
|||||||
See `single-file --help` for complete list of arguments, or browse source: https://github.com/gildas-lormeau/single-file-cli/blob/master/options.js
|
See `single-file --help` for complete list of arguments, or browse source: https://github.com/gildas-lormeau/single-file-cli/blob/master/options.js
|
||||||
|
|
||||||
Example: `LD_SINGLEFILE_OPTIONS=--user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0"`
|
Example: `LD_SINGLEFILE_OPTIONS=--user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:124.0) Gecko/20100101 Firefox/124.0"`
|
||||||
|
|
||||||
|
### `LD_DISABLE_REQUEST_LOGS`
|
||||||
|
|
||||||
|
Values: `true` or `false` | Default = `false`
|
||||||
|
|
||||||
|
Set uWSGI [disable-logging](https://uwsgi-docs.readthedocs.io/en/latest/Options.html#disable-logging) parameter to disable request logs, except for requests with a client (4xx) or server (5xx) error response.
|
||||||
|
|||||||
10
package-lock.json
generated
10
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "linkding",
|
"name": "linkding",
|
||||||
"version": "1.35.0",
|
"version": "1.36.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "linkding",
|
"name": "linkding",
|
||||||
"version": "1.35.0",
|
"version": "1.36.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hotwired/turbo": "^8.0.6",
|
"@hotwired/turbo": "^8.0.6",
|
||||||
@@ -1310,9 +1310,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.7",
|
"version": "3.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "linkding",
|
"name": "linkding",
|
||||||
"version": "1.36.0",
|
"version": "1.37.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ click==8.1.7
|
|||||||
# via black
|
# via black
|
||||||
coverage==7.6.1
|
coverage==7.6.1
|
||||||
# via -r requirements.dev.in
|
# via -r requirements.dev.in
|
||||||
django==5.1.1
|
django==5.1.5
|
||||||
# via django-debug-toolbar
|
# via django-debug-toolbar
|
||||||
django-debug-toolbar==4.4.6
|
django-debug-toolbar==4.4.6
|
||||||
# via -r requirements.dev.in
|
# via -r requirements.dev.in
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ cryptography==43.0.1
|
|||||||
# josepy
|
# josepy
|
||||||
# mozilla-django-oidc
|
# mozilla-django-oidc
|
||||||
# pyopenssl
|
# pyopenssl
|
||||||
django==5.1.1
|
django==5.1.5
|
||||||
# via
|
# via
|
||||||
# -r requirements.in
|
# -r requirements.in
|
||||||
# django-registration
|
# django-registration
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ env = DJANGO_SETTINGS_MODULE=siteroot.settings.prod
|
|||||||
static-map = /static=static
|
static-map = /static=static
|
||||||
static-map = /static=data/favicons
|
static-map = /static=data/favicons
|
||||||
static-map = /static=data/previews
|
static-map = /static=data/previews
|
||||||
|
static-map = /robots.txt=static/robots.txt
|
||||||
processes = 2
|
processes = 2
|
||||||
threads = 2
|
threads = 2
|
||||||
pidfile = /tmp/linkding.pid
|
pidfile = /tmp/linkding.pid
|
||||||
@@ -18,6 +19,7 @@ if-env = LD_CONTEXT_PATH
|
|||||||
static-map = /%(_)static=static
|
static-map = /%(_)static=static
|
||||||
static-map = /%(_)static=data/favicons
|
static-map = /%(_)static=data/favicons
|
||||||
static-map = /%(_)static=data/previews
|
static-map = /%(_)static=data/previews
|
||||||
|
static-map = /%(_)robots.txt=static/robots.txt
|
||||||
endif =
|
endif =
|
||||||
|
|
||||||
if-env = LD_REQUEST_TIMEOUT
|
if-env = LD_REQUEST_TIMEOUT
|
||||||
@@ -29,3 +31,9 @@ endif =
|
|||||||
if-env = LD_LOG_X_FORWARDED_FOR
|
if-env = LD_LOG_X_FORWARDED_FOR
|
||||||
log-x-forwarded-for = %(_)
|
log-x-forwarded-for = %(_)
|
||||||
endif =
|
endif =
|
||||||
|
|
||||||
|
if-env = LD_DISABLE_REQUEST_LOGS=true
|
||||||
|
disable-logging = true
|
||||||
|
log-4xx = true
|
||||||
|
log-5xx = true
|
||||||
|
endif =
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.36.0
|
1.37.0
|
||||||
|
|||||||
Reference in New Issue
Block a user