mirror of
https://github.com/sissbruecker/linkding
synced 2025-02-16 20:38:24 +00:00
* use client-side navigation * update tests * add setting for enabling link prefetching * do not prefetch bookmark details * theme progress bar * cleanup behaviors * update test
390 lines
18 KiB
HTML
390 lines
18 KiB
HTML
{% extends "bookmarks/layout.html" %}
|
|
{% load widget_tweaks %}
|
|
|
|
{% block content %}
|
|
<div class="settings-page">
|
|
|
|
{% include 'settings/nav.html' %}
|
|
|
|
{# Profile section #}
|
|
{% if success_message %}
|
|
<div class="toast toast-success mb-4">{{ success_message }}</div>
|
|
{% endif %}
|
|
{% if error_message %}
|
|
<div class="toast toast-error mb-4">{{ error_message }}</div>
|
|
{% endif %}
|
|
|
|
<section class="content-area">
|
|
<h2>Profile</h2>
|
|
<p>
|
|
<a href="{% url 'change_password' %}">Change password</a>
|
|
</p>
|
|
<form action="{% url 'bookmarks:settings.update' %}" method="post" novalidate data-turbo="false">
|
|
{% csrf_token %}
|
|
<div class="form-group">
|
|
<label for="{{ form.theme.id_for_label }}" class="form-label">Theme</label>
|
|
{{ form.theme|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
Whether to use a light or dark theme, or automatically adjust the theme based on your system's settings.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.bookmark_date_display.id_for_label }}" class="form-label">Bookmark date format</label>
|
|
{{ form.bookmark_date_display|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
Whether to show bookmark dates as relative (how long ago), or as absolute dates. Alternatively the date can
|
|
be hidden.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.bookmark_description_display.id_for_label }}" class="form-label">Bookmark
|
|
description</label>
|
|
{{ form.bookmark_description_display|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
Whether to show bookmark descriptions and tags in the same line, or as separate blocks.
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="form-group {% if request.user_profile.bookmark_description_display == 'inline' %}d-hide{% endif %}">
|
|
<label for="{{ form.bookmark_description_max_lines.id_for_label }}" class="form-label">Bookmark description
|
|
max lines</label>
|
|
{{ form.bookmark_description_max_lines|add_class:"form-input width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
Limits the number of lines that are displayed for the bookmark description.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.display_url.id_for_label }}" class="form-checkbox">
|
|
{{ form.display_url }}
|
|
<i class="form-icon"></i> Show bookmark URL
|
|
</label>
|
|
<div class="form-input-hint">
|
|
When enabled, this setting displays the bookmark URL below the title.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.permanent_notes.id_for_label }}" class="form-checkbox">
|
|
{{ form.permanent_notes }}
|
|
<i class="form-icon"></i> Show notes permanently
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Whether to show bookmark notes permanently, without having to toggle them individually.
|
|
Alternatively the keyboard shortcut <code>e</code> can be used to temporarily show all notes.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="form-label">Bookmark actions</label>
|
|
<label for="{{ form.display_view_bookmark_action.id_for_label }}" class="form-checkbox">
|
|
{{ form.display_view_bookmark_action }}
|
|
<i class="form-icon"></i> View
|
|
</label>
|
|
<label for="{{ form.display_edit_bookmark_action.id_for_label }}" class="form-checkbox">
|
|
{{ form.display_edit_bookmark_action }}
|
|
<i class="form-icon"></i> Edit
|
|
</label>
|
|
<label for="{{ form.display_archive_bookmark_action.id_for_label }}" class="form-checkbox">
|
|
{{ form.display_archive_bookmark_action }}
|
|
<i class="form-icon"></i> Archive
|
|
</label>
|
|
<label for="{{ form.display_remove_bookmark_action.id_for_label }}" class="form-checkbox">
|
|
{{ form.display_remove_bookmark_action }}
|
|
<i class="form-icon"></i> Remove
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Which actions to display for each bookmark.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.bookmark_link_target.id_for_label }}" class="form-label">Open bookmarks in</label>
|
|
{{ form.bookmark_link_target|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
Whether to open bookmarks a new page or in the same page.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.tag_search.id_for_label }}" class="form-label">Tag search</label>
|
|
{{ form.tag_search|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
In strict mode, tags must be prefixed with a hash character (#).
|
|
In lax mode, tags can also be searched without the hash character.
|
|
Note that tags without the hash character are indistinguishable from search terms, which means the search
|
|
result will also include bookmarks where a search term matches otherwise.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.tag_grouping.id_for_label }}" class="form-label">Tag grouping</label>
|
|
{{ form.tag_grouping|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
In alphabetical mode, tags will be grouped by the first letter.
|
|
If disabled, tags will not be grouped.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<details {% if form.auto_tagging_rules.value %}open{% endif %}>
|
|
<summary>
|
|
<span class="form-label d-inline-block">Auto Tagging</span>
|
|
</summary>
|
|
<label for="{{ form.auto_tagging_rules.id_for_label }}" class="text-assistive">Auto Tagging</label>
|
|
<div>
|
|
{{ form.auto_tagging_rules|add_class:"form-input monospace"|attr:"rows:6" }}
|
|
</div>
|
|
</details>
|
|
<div class="form-input-hint">
|
|
Automatically adds tags to bookmarks based on predefined rules.
|
|
Each line is a single rule that maps a URL to one or more tags. For example:
|
|
<pre>youtube.com video
|
|
reddit.com/r/Music music reddit</pre>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.enable_favicons.id_for_label }}" class="form-checkbox">
|
|
{{ form.enable_favicons }}
|
|
<i class="form-icon"></i> Enable Favicons
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Automatically loads favicons for bookmarked websites and displays them next to each bookmark.
|
|
Enabling this feature automatically downloads all missing favicons.
|
|
By default, this feature uses a <b>Google service</b> to download favicons.
|
|
If you don't want to use this service, check the <a
|
|
href="https://github.com/sissbruecker/linkding/blob/master/docs/Options.md#ld_favicon_provider"
|
|
target="_blank">options documentation</a> on how to configure a custom favicon provider.
|
|
Icons are downloaded in the background, and it may take a while for them to show up.
|
|
</div>
|
|
{% if request.user_profile.enable_favicons and enable_refresh_favicons %}
|
|
<button class="btn mt-2" name="refresh_favicons">Refresh Favicons</button>
|
|
{% endif %}
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.enable_preview_images.id_for_label }}" class="form-checkbox">
|
|
{{ form.enable_preview_images }}
|
|
<i class="form-icon"></i> Enable Preview Images
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Automatically loads preview images for bookmarked websites and displays them next to each bookmark.
|
|
Enabling this feature automatically downloads all missing preview images.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.web_archive_integration.id_for_label }}" class="form-label">Internet Archive
|
|
integration</label>
|
|
{{ form.web_archive_integration|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
Enabling this feature will automatically create snapshots of bookmarked websites on the <a
|
|
href="https://web.archive.org/" target="_blank" rel="noopener">Internet Archive Wayback
|
|
Machine</a>.
|
|
This allows to preserve, and later access the website as it was at the point in time it was bookmarked, in
|
|
case it goes offline or its content is modified.
|
|
Please consider donating to the <a href="https://archive.org/donate" target="_blank"
|
|
rel="noopener">Internet Archive</a> if you make use of this feature.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.enable_sharing.id_for_label }}" class="form-checkbox">
|
|
{{ form.enable_sharing }}
|
|
<i class="form-icon"></i> Enable bookmark sharing
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Allows to share bookmarks with other users, and to view shared bookmarks.
|
|
Disabling this feature will hide all previously shared bookmarks from other users.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ form.enable_public_sharing.id_for_label }}" class="form-checkbox">
|
|
{{ form.enable_public_sharing }}
|
|
<i class="form-icon"></i> Enable public bookmark sharing
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Makes shared bookmarks publicly accessible, without requiring a login.
|
|
That means that anyone with a link to this instance can view shared bookmarks via the <a
|
|
href="{% url 'bookmarks:shared' %}">shared bookmarks page</a>.
|
|
</div>
|
|
</div>
|
|
{% if has_snapshot_support %}
|
|
<div class="form-group">
|
|
<label for="{{ form.enable_automatic_html_snapshots.id_for_label }}" class="form-checkbox">
|
|
{{ form.enable_automatic_html_snapshots }}
|
|
<i class="form-icon"></i> Automatically create HTML snapshots
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Automatically creates HTML snapshots when adding bookmarks. Alternatively, when disabled, snapshots can be
|
|
created manually in the details view of a bookmark.
|
|
</div>
|
|
<button class="btn mt-2" name="create_missing_html_snapshots">Create missing HTML snapshots</button>
|
|
</div>
|
|
{% endif %}
|
|
<div class="form-group">
|
|
<label for="{{ form.default_mark_unread.id_for_label }}" class="form-checkbox">
|
|
{{ form.default_mark_unread }}
|
|
<i class="form-icon"></i> Create bookmarks as unread by default
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Sets the default state for the "Mark as unread" option when creating a new bookmark.
|
|
Setting this option will make all new bookmarks default to unread.
|
|
This can be overridden when creating each new bookmark.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<details {% if form.custom_css.value %}open{% endif %}>
|
|
<summary>
|
|
<span class="form-label d-inline-block">Custom CSS</span>
|
|
</summary>
|
|
<label for="{{ form.custom_css.id_for_label }}" class="text-assistive">Custom CSS</label>
|
|
<div>
|
|
{{ form.custom_css|add_class:"form-input monospace"|attr:"rows:6" }}
|
|
</div>
|
|
</details>
|
|
<div class="form-input-hint">
|
|
Allows to add custom CSS to the page.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<input type="submit" name="update_profile" value="Save" class="btn btn-primary btn-wide mt-2">
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
{# Global settings section #}
|
|
{% if global_settings_form %}
|
|
<section class="content-area">
|
|
<h2>Global settings</h2>
|
|
<form action="{% url 'bookmarks:settings.update' %}" method="post" novalidate data-turbo="false">
|
|
{% csrf_token %}
|
|
<div class="form-group">
|
|
<label for="{{ global_settings_form.landing_page.id_for_label }}" class="form-label">Landing page</label>
|
|
{{ global_settings_form.landing_page|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
The page that unauthenticated users are redirected to when accessing the root URL.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ global_settings_form.guest_profile_user.id_for_label }}" class="form-label">Guest user
|
|
profile</label>
|
|
{{ global_settings_form.guest_profile_user|add_class:"form-select width-25 width-sm-100" }}
|
|
<div class="form-input-hint">
|
|
The user profile to use for users that are not logged in. This will affect how publicly shared bookmarks
|
|
are displayed regarding theme, bookmark list settings, etc. You can either use your own profile or create
|
|
a dedicated user for this purpose. By default, a standard profile with fixed settings is used.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="{{ global_settings_form.enable_link_prefetch.id_for_label }}" class="form-checkbox">
|
|
{{ global_settings_form.enable_link_prefetch }}
|
|
<i class="form-icon"></i> Enable prefetching links on hover
|
|
</label>
|
|
<div class="form-input-hint">
|
|
Prefetches internal links when hovering over them. This can improve the perceived performance when
|
|
navigating application, but also increases the load on the server as well as bandwidth usage.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<input type="submit" name="update_global_settings" value="Save" class="btn btn-primary btn-wide mt-2">
|
|
</div>
|
|
</form>
|
|
</section>
|
|
{% endif %}
|
|
|
|
{# Import section #}
|
|
<section class="content-area">
|
|
<h2>Import</h2>
|
|
<p>Import bookmarks and tags in the Netscape HTML format. This will execute a sync where new bookmarks are
|
|
added and existing ones are updated.</p>
|
|
<form method="post" enctype="multipart/form-data" action="{% url 'bookmarks:settings.import' %}">
|
|
{% csrf_token %}
|
|
<div class="form-group">
|
|
<label for="import_map_private_flag" class="form-checkbox">
|
|
<input type="checkbox" id="import_map_private_flag" name="map_private_flag">
|
|
<i class="form-icon"></i> Import public bookmarks as shared
|
|
</label>
|
|
<div class="form-input-hint">
|
|
When importing bookmarks from a service that supports marking bookmarks as public or private (using the
|
|
<code>PRIVATE</code> attribute), enabling this option will import all bookmarks that are marked as not
|
|
private as shared bookmarks.
|
|
Otherwise, all bookmarks will be imported as private bookmarks.
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="input-group width-75 width-md-100">
|
|
<input class="form-input" type="file" name="import_file">
|
|
<input type="submit" class="input-group-btn btn btn-primary" value="Upload">
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</section>
|
|
|
|
{# Export section #}
|
|
<section class="content-area">
|
|
<h2>Export</h2>
|
|
<p>Export all bookmarks in Netscape HTML format.</p>
|
|
<a class="btn btn-primary" target="_blank" href="{% url 'bookmarks:settings.export' %}">Download (.html)</a>
|
|
{% if export_error %}
|
|
<div class="has-error">
|
|
<p class="form-input-hint">
|
|
{{ export_error }}
|
|
</p>
|
|
</div>
|
|
{% endif %}
|
|
</section>
|
|
|
|
{# About section #}
|
|
<section class="content-area about">
|
|
<h2>About</h2>
|
|
<table class="table">
|
|
<tbody>
|
|
<tr>
|
|
<td>Version</td>
|
|
<td>{{ version_info }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td rowspan="3" style="vertical-align: top">Links</td>
|
|
<td><a href="https://github.com/sissbruecker/linkding/"
|
|
target="_blank">GitHub</a></td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="https://github.com/sissbruecker/linkding#documentation"
|
|
target="_blank">Documentation</a></td>
|
|
</tr>
|
|
<tr>
|
|
<td><a href="https://github.com/sissbruecker/linkding/blob/master/CHANGELOG.md"
|
|
target="_blank">Changelog</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
</div>
|
|
|
|
<script>
|
|
(function init() {
|
|
const enableSharing = document.getElementById("{{ form.enable_sharing.id_for_label }}");
|
|
const enablePublicSharing = document.getElementById("{{ form.enable_public_sharing.id_for_label }}");
|
|
const bookmarkDescriptionDisplay = document.getElementById("{{ form.bookmark_description_display.id_for_label }}");
|
|
const bookmarkDescriptionMaxLines = document.getElementById("{{ form.bookmark_description_max_lines.id_for_label }}");
|
|
|
|
// Automatically disable public bookmark sharing if bookmark sharing is disabled
|
|
function updatePublicSharing() {
|
|
if (enableSharing.checked) {
|
|
enablePublicSharing.disabled = false;
|
|
} else {
|
|
enablePublicSharing.disabled = true;
|
|
enablePublicSharing.checked = false;
|
|
}
|
|
}
|
|
|
|
updatePublicSharing();
|
|
enableSharing.addEventListener("change", updatePublicSharing);
|
|
|
|
// Automatically hide the bookmark description max lines input if the description display is set to inline
|
|
function updateBookmarkDescriptionMaxLines() {
|
|
if (bookmarkDescriptionDisplay.value === "inline") {
|
|
bookmarkDescriptionMaxLines.closest(".form-group").classList.add("d-hide");
|
|
} else {
|
|
bookmarkDescriptionMaxLines.closest(".form-group").classList.remove("d-hide");
|
|
}
|
|
}
|
|
|
|
updateBookmarkDescriptionMaxLines();
|
|
bookmarkDescriptionDisplay.addEventListener("change", updateBookmarkDescriptionMaxLines);
|
|
})();
|
|
</script>
|
|
|
|
{% endblock %}
|