Update theme ans bones according to KT theme

This commit is contained in:
Knah Tsaeb 2025-04-18 10:57:05 +02:00
parent ecf9074e98
commit 505f2f08c3
63 changed files with 1762 additions and 11263 deletions

Binary file not shown.

Before

(image error) Size: 18 KiB

Binary file not shown.

Before

(image error) Size: 41 KiB

Binary file not shown.

Before

(image error) Size: 6.9 KiB

View file

@ -1,718 +0,0 @@
import Awesomplete from 'awesomplete';
import he from 'he';
/**
* Find a parent element according to its tag and its attributes
*
* @param element Element where to start the search
* @param tagName Expected parent tag name
* @param attributes Associative array of expected attributes (name=>value).
*
* @returns Found element or null.
*/
function findParent(element, tagName, attributes) {
const parentMatch = (key) => attributes[key] !== '' && element.getAttribute(key).indexOf(attributes[key]) !== -1;
while (element) {
if (element.tagName.toLowerCase() === tagName) {
if (Object.keys(attributes).find(parentMatch)) {
return element;
}
}
element = element.parentElement;
}
return null;
}
/**
* Ajax request to refresh the CSRF token.
*/
function refreshToken(basePath, callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', `${basePath}/admin/token`);
xhr.onload = () => {
const elements = document.querySelectorAll('input[name="token"]');
[...elements].forEach((element) => {
element.setAttribute('value', xhr.responseText);
});
if (callback) {
callback(xhr.response);
}
};
xhr.send();
}
function createAwesompleteInstance(element, separator, tags = []) {
const awesome = new Awesomplete(Awesomplete.$(element));
// Tags are separated by separator. Ignore leading search flags
awesome.filter = (text, input) => {
let filterFunc = Awesomplete.FILTER_CONTAINS;
let term = input.match(new RegExp(`[^${separator}]*$`))[0];
const termFlagged = term.replace(/^[-~+]/, '');
if (term !== termFlagged) {
term = termFlagged;
filterFunc = Awesomplete.FILTER_STARTSWITH;
}
return filterFunc(text, term);
};
// Insert new selected tag in the input
awesome.replace = (text) => {
const before = awesome.input.value.match(new RegExp(`^(.+${separator}+)?[-~+]?|`))[0];
awesome.input.value = `${before}${text}${separator}`;
};
// Highlight found items
awesome.item = (text, input) => Awesomplete.ITEM(text, input.match(new RegExp(`[^${separator}]*$`))[0]);
// Don't display already selected items
// WARNING: pseudo classes does not seem to work with string litterals...
const reg = new RegExp(`([^${separator}]+)${separator}`, 'g');
let match;
awesome.data = (item, input) => {
while ((match = reg.exec(input))) {
if (item === match[1]) {
return '';
}
}
return item;
};
awesome.minChars = 1;
if (tags.length) {
awesome.list = tags;
}
return awesome;
}
/**
* Update awesomplete list of tag for all elements matching the given selector
*
* @param selector CSS selector
* @param tags Array of tags
* @param instances List of existing awesomplete instances
* @param separator Tags separator character
*/
function updateAwesompleteList(selector, tags, instances, separator) {
if (instances.length === 0) {
// First load: create Awesomplete instances
const elements = document.querySelectorAll(selector);
[...elements].forEach((element) => {
instances.push(createAwesompleteInstance(element, separator, tags));
});
} else {
// Update awesomplete tag list
instances.map((item) => {
item.list = tags;
return item;
});
}
return instances;
}
/**
* Add the class 'hidden' to city options not attached to the current selected continent.
*
* @param cities List of <option> elements
* @param currentContinent Current selected continent
* @param reset Set to true to reset the selected value
*/
function hideTimezoneCities(cities, currentContinent, reset = null) {
let first = true;
if (reset == null) {
reset = false;
}
[...cities].forEach((option) => {
if (option.getAttribute('data-continent') !== currentContinent) {
option.className = 'hidden';
} else {
option.className = '';
if (reset === true && first === true) {
option.setAttribute('selected', 'selected');
first = false;
}
}
});
}
/**
* Retrieve an element up in the tree from its class name.
*/
function getParentByClass(el, className) {
const p = el.parentNode;
if (p == null || p.classList.contains(className)) {
return p;
}
return getParentByClass(p, className);
}
function toggleHorizontal() {
[...document.getElementById('shaarli-menu').querySelectorAll('.menu-transform')].forEach((el) => {
el.classList.toggle('pure-menu-horizontal');
});
}
function toggleMenu(menu) {
// set timeout so that the panel has a chance to roll up
// before the menu switches states
if (menu.classList.contains('open')) {
setTimeout(toggleHorizontal, 500);
} else {
toggleHorizontal();
}
menu.classList.toggle('open');
document.getElementById('menu-toggle').classList.toggle('x');
}
function closeMenu(menu) {
if (menu.classList.contains('open')) {
toggleMenu(menu);
}
}
function toggleFold(button, description, thumb) {
// Switch fold/expand - up = fold
if (button.classList.contains('fa-chevron-up')) {
button.title = document.getElementById('translation-expand').innerHTML;
if (description != null) {
description.style.display = 'none';
}
if (thumb != null) {
thumb.style.display = 'none';
}
} else {
button.title = document.getElementById('translation-fold').innerHTML;
if (description != null) {
description.style.display = 'block';
}
if (thumb != null) {
thumb.style.display = 'block';
}
}
button.classList.toggle('fa-chevron-down');
button.classList.toggle('fa-chevron-up');
}
function removeClass(element, classname) {
element.className = element.className.replace(new RegExp(`(?:^|\\s)${classname}(?:\\s|$)`), ' ');
}
function init(description) {
function resize() {
/* Fix jumpy resizing: https://stackoverflow.com/a/18262927/1484919 */
const scrollTop = window.pageYOffset
|| (document.documentElement || document.body.parentNode || document.body).scrollTop;
description.style.height = 'auto';
description.style.height = `${description.scrollHeight + 10}px`;
window.scrollTo(0, scrollTop);
}
/* 0-timeout to get the already changed text */
function delayedResize() {
window.setTimeout(resize, 0);
}
const observe = (element, event, handler) => {
element.addEventListener(event, handler, false);
};
observe(description, 'change', resize);
observe(description, 'cut', delayedResize);
observe(description, 'paste', delayedResize);
observe(description, 'drop', delayedResize);
observe(description, 'keydown', delayedResize);
resize();
}
(() => {
const basePath = document.querySelector('input[name="js_base_path"]').value;
const tagsSeparatorElement = document.querySelector('input[name="tags_separator"]');
const tagsSeparator = tagsSeparatorElement ? tagsSeparatorElement.value || ' ' : ' ';
/**
* Handle responsive menu.
* Source: http://purecss.io/layouts/tucked-menu-vertical/
*/
const menu = document.getElementById('shaarli-menu');
const WINDOW_CHANGE_EVENT = ('onorientationchange' in window) ? 'orientationchange' : 'resize';
const menuToggle = document.getElementById('menu-toggle');
if (menuToggle != null) {
menuToggle.addEventListener('click', () => toggleMenu(menu));
}
window.addEventListener(WINDOW_CHANGE_EVENT, () => closeMenu(menu));
/**
* Fold/Expand shaares description and thumbnail.
*/
const foldAllButtons = document.getElementsByClassName('fold-all');
const foldButtons = document.getElementsByClassName('fold-button');
[...foldButtons].forEach((foldButton) => {
// Retrieve description
let description = null;
let thumbnail = null;
const linklistItem = getParentByClass(foldButton, 'linklist-item');
if (linklistItem != null) {
description = linklistItem.querySelector('.linklist-item-description');
thumbnail = linklistItem.querySelector('.linklist-item-thumbnail');
if (description != null || thumbnail != null) {
foldButton.style.display = 'inline';
}
}
foldButton.addEventListener('click', (event) => {
event.preventDefault();
toggleFold(event.target, description, thumbnail);
});
});
if (foldAllButtons != null) {
[].forEach.call(foldAllButtons, (foldAllButton) => {
foldAllButton.addEventListener('click', (event) => {
event.preventDefault();
const state = foldAllButton.firstElementChild.getAttribute('class').indexOf('down') !== -1 ? 'down' : 'up';
[].forEach.call(foldButtons, (foldButton) => {
if ((foldButton.firstElementChild.classList.contains('fa-chevron-up') && state === 'down')
|| (foldButton.firstElementChild.classList.contains('fa-chevron-down') && state === 'up')
) {
return;
}
// Retrieve description
let description = null;
let thumbnail = null;
const linklistItem = getParentByClass(foldButton, 'linklist-item');
if (linklistItem != null) {
description = linklistItem.querySelector('.linklist-item-description');
thumbnail = linklistItem.querySelector('.linklist-item-thumbnail');
if (description != null || thumbnail != null) {
foldButton.style.display = 'inline';
}
}
toggleFold(foldButton.firstElementChild, description, thumbnail);
});
foldAllButton.firstElementChild.classList.toggle('fa-chevron-down');
foldAllButton.firstElementChild.classList.toggle('fa-chevron-up');
foldAllButton.title = state === 'down'
? document.getElementById('translation-fold-all').innerHTML
: document.getElementById('translation-expand-all').innerHTML;
});
});
}
/**
* Confirmation message before deletion.
*/
const deleteLinks = document.querySelectorAll('.confirm-delete');
[...deleteLinks].forEach((deleteLink) => {
deleteLink.addEventListener('click', (event) => {
const type = event.currentTarget.getAttribute('data-type') || 'link';
if (!confirm(document.getElementById(`translation-delete-${type}`).innerHTML)) {
event.preventDefault();
}
});
});
/**
* Close alerts
*/
const closeLinks = document.querySelectorAll('.pure-alert-close');
[...closeLinks].forEach((closeLink) => {
closeLink.addEventListener('click', (event) => {
const alert = getParentByClass(event.target, 'pure-alert-closable');
alert.style.display = 'none';
});
});
/**
* New version dismiss.
* Hide the message for one week using localStorage.
*/
const newVersionDismiss = document.getElementById('new-version-dismiss');
const newVersionMessage = document.querySelector('.new-version-message');
if (newVersionMessage != null
&& localStorage.getItem('newVersionDismiss') != null
&& parseInt(localStorage.getItem('newVersionDismiss'), 10) + (7 * 24 * 60 * 60 * 1000) > (new Date()).getTime()
) {
newVersionMessage.style.display = 'none';
}
if (newVersionDismiss != null) {
newVersionDismiss.addEventListener('click', () => {
localStorage.setItem('newVersionDismiss', (new Date()).getTime().toString());
});
}
const hiddenReturnurl = document.getElementsByName('returnurl');
if (hiddenReturnurl != null) {
hiddenReturnurl.value = window.location.href;
}
/**
* Autofocus text fields
*/
const autofocusElements = document.querySelectorAll('.autofocus');
let breakLoop = false;
[].forEach.call(autofocusElements, (autofocusElement) => {
if (autofocusElement.value === '' && !breakLoop) {
autofocusElement.focus();
breakLoop = true;
}
});
/**
* Handle sub menus/forms
*/
const openers = document.getElementsByClassName('subheader-opener');
if (openers != null) {
[...openers].forEach((opener) => {
opener.addEventListener('click', (event) => {
event.preventDefault();
const id = opener.getAttribute('data-open-id');
const sub = document.getElementById(id);
if (sub != null) {
[...document.getElementsByClassName('subheader-form')].forEach((element) => {
if (element !== sub) {
removeClass(element, 'open');
}
});
sub.classList.toggle('open');
const autofocus = sub.querySelector('.autofocus');
if (autofocus) {
autofocus.focus();
}
}
});
});
}
/**
* Remove CSS target padding (for fixed bar)
*/
if (location.hash !== '') {
const anchor = document.getElementById(location.hash.substr(1));
if (anchor != null) {
const padsize = anchor.clientHeight;
window.scroll(0, window.scrollY - padsize);
anchor.style.paddingTop = '0';
}
}
/**
* Text area resizer
*/
const description = document.getElementById('lf_description');
if (description != null) {
init(description);
// Submit editlink form with CTRL + Enter in the text area.
description.addEventListener('keydown', (event) => {
if (event.ctrlKey && event.keyCode === 13) {
document.getElementById('button-save-edit').click();
}
});
}
/**
* Bookmarklet alert
*/
const bookmarkletLinks = document.querySelectorAll('.bookmarklet-link');
const bkmMessage = document.getElementById('bookmarklet-alert');
[].forEach.call(bookmarkletLinks, (link) => {
link.addEventListener('click', (event) => {
event.preventDefault();
alert(bkmMessage.value);
});
});
const continent = document.getElementById('continent');
const city = document.getElementById('city');
if (continent != null && city != null) {
continent.addEventListener('change', () => {
hideTimezoneCities(city, continent.options[continent.selectedIndex].value, true);
});
hideTimezoneCities(city, continent.options[continent.selectedIndex].value, false);
}
/**
* Bulk actions
*/
const linkCheckboxes = document.querySelectorAll('.link-checkbox');
const bar = document.getElementById('actions');
[...linkCheckboxes].forEach((checkbox) => {
checkbox.style.display = 'inline-block';
checkbox.addEventListener('change', () => {
const linkCheckedCheckboxes = document.querySelectorAll('.link-checkbox:checked');
const count = [...linkCheckedCheckboxes].length;
if (count === 0 && bar.classList.contains('open')) {
bar.classList.toggle('open');
} else if (count > 0 && !bar.classList.contains('open')) {
bar.classList.toggle('open');
}
});
});
const deleteButton = document.getElementById('actions-delete');
const token = document.getElementById('token');
if (deleteButton != null && token != null) {
deleteButton.addEventListener('click', (event) => {
event.preventDefault();
const links = [];
const linkCheckedCheckboxes = document.querySelectorAll('.link-checkbox:checked');
[...linkCheckedCheckboxes].forEach((checkbox) => {
links.push({
id: checkbox.value,
title: document.querySelector(`.linklist-item[data-id="${checkbox.value}"] .linklist-link`).innerHTML,
});
});
let message = `Are you sure you want to delete ${links.length} links?\n`;
message += 'This action is IRREVERSIBLE!\n\nTitles:\n';
const ids = [];
links.forEach((item) => {
message += ` - ${item.title}\n`;
ids.push(item.id);
});
if (window.confirm(message)) {
window.location = `${basePath}/admin/shaare/delete?id=${ids.join('+')}&token=${token.value}`;
}
});
}
const changeVisibilityButtons = document.querySelectorAll('.actions-change-visibility');
if (changeVisibilityButtons != null && token != null) {
[...changeVisibilityButtons].forEach((button) => {
button.addEventListener('click', (event) => {
event.preventDefault();
const visibility = event.target.getAttribute('data-visibility');
const links = [];
const linkCheckedCheckboxes = document.querySelectorAll('.link-checkbox:checked');
[...linkCheckedCheckboxes].forEach((checkbox) => {
links.push({
id: checkbox.value,
title: document.querySelector(`.linklist-item[data-id="${checkbox.value}"] .linklist-link`).innerHTML,
});
});
const ids = links.map((item) => item.id);
window.location = (
`${basePath}/admin/shaare/visibility?token=${token.value}&newVisibility=${visibility}&id=${ids.join('+')}`
);
});
});
}
['add', 'delete'].forEach((action) => {
const subHeader = document.getElementById(`bulk-tag-action-${action}`);
if (subHeader) {
subHeader.querySelectorAll('a.button').forEach((link) => {
if (!link.classList.contains('action')) {
return;
}
subHeader.querySelector('input[name="tag"]').addEventListener('keypress', (event) => {
if (event.keyCode === 13) { // enter
link.click();
}
});
link.addEventListener('click', (event) => {
event.preventDefault();
const ids = [];
const linkCheckedCheckboxes = document.querySelectorAll('.link-checkbox:checked');
[...linkCheckedCheckboxes].forEach((checkbox) => {
ids.push(checkbox.value);
});
subHeader.querySelector('input[name="id"]').value = ids.join(' ');
subHeader.querySelector('form').submit();
});
});
}
});
/**
* Select all button
*/
const selectAllButtons = document.querySelectorAll('.select-all-button');
[...selectAllButtons].forEach((selectAllButton) => {
selectAllButton.addEventListener('click', (e) => {
e.preventDefault();
const checked = selectAllButton.classList.contains('filter-off');
[...selectAllButtons].forEach((selectAllButton2) => {
selectAllButton2.classList.toggle('filter-off');
selectAllButton2.classList.toggle('filter-on');
});
[...linkCheckboxes].forEach((linkCheckbox) => {
linkCheckbox.checked = checked;
linkCheckbox.dispatchEvent(new Event('change'));
});
});
});
/**
* Tag list operations
*
* TODO: support error code in the backend for AJAX requests
*/
const tagList = document.querySelector('input[name="taglist"]');
let existingTags = tagList ? tagList.value.split(' ') : [];
let awesomepletes = [];
// Display/Hide rename form
const renameTagButtons = document.querySelectorAll('.rename-tag');
[...renameTagButtons].forEach((rename) => {
rename.addEventListener('click', (event) => {
event.preventDefault();
const block = findParent(event.target, 'div', { class: 'tag-list-item' });
const form = block.querySelector('.rename-tag-form');
if (form.style.display === 'none' || form.style.display === '') {
form.style.display = 'block';
} else {
form.style.display = 'none';
}
block.querySelector('input').focus();
});
});
// Rename a tag with an AJAX request
const renameTagSubmits = document.querySelectorAll('.validate-rename-tag');
[...renameTagSubmits].forEach((rename) => {
rename.addEventListener('click', (event) => {
event.preventDefault();
const block = findParent(event.target, 'div', { class: 'tag-list-item' });
const input = block.querySelector('.rename-tag-input');
const totag = input.value.replace('/"/g', '\\"');
if (totag.trim() === '') {
return;
}
const refreshedToken = document.getElementById('token').value;
const fromtag = block.getAttribute('data-tag');
const fromtagUrl = block.getAttribute('data-tag-url');
const xhr = new XMLHttpRequest();
xhr.open('POST', `${basePath}/admin/tags`);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = () => {
if (xhr.status !== 200) {
alert(`An error occurred. Return code: ${xhr.status}`);
location.reload();
} else {
block.setAttribute('data-tag', totag);
block.setAttribute('data-tag-url', encodeURIComponent(totag));
input.setAttribute('name', totag);
input.setAttribute('value', totag);
findParent(input, 'div', { class: 'rename-tag-form' }).style.display = 'none';
block.querySelector('a.tag-link').innerHTML = he.encode(totag);
block
.querySelector('a.tag-link')
.setAttribute('href', `${basePath}/?searchtags=${encodeURIComponent(totag)}`);
block
.querySelector('a.count')
.setAttribute('href', `${basePath}/add-tag/${encodeURIComponent(totag)}`);
block
.querySelector('a.rename-tag')
.setAttribute('href', `${basePath}/admin/tags?fromtag=${encodeURIComponent(totag)}`);
// Refresh awesomplete values
existingTags = existingTags.map((tag) => (tag === fromtag ? totag : tag));
awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes, tagsSeparator);
}
};
xhr.send(`renametag=1&fromtag=${fromtagUrl}&totag=${encodeURIComponent(totag)}&token=${refreshedToken}`);
refreshToken(basePath);
});
});
// Validate input with enter key
const renameTagInputs = document.querySelectorAll('.rename-tag-input');
[...renameTagInputs].forEach((rename) => {
rename.addEventListener('keypress', (event) => {
if (event.keyCode === 13) { // enter
findParent(event.target, 'div', { class: 'tag-list-item' }).querySelector('.validate-rename-tag').click();
}
});
});
// Delete a tag with an AJAX query (alert popup confirmation)
const deleteTagButtons = document.querySelectorAll('.delete-tag');
[...deleteTagButtons].forEach((rename) => {
rename.style.display = 'inline';
rename.addEventListener('click', (event) => {
event.preventDefault();
const block = findParent(event.target, 'div', { class: 'tag-list-item' });
const tag = block.getAttribute('data-tag');
const tagUrl = block.getAttribute('data-tag-url');
const refreshedToken = document.getElementById('token').value;
if (confirm(`Are you sure you want to delete the tag "${tag}"?`)) {
const xhr = new XMLHttpRequest();
xhr.open('POST', `${basePath}/admin/tags`);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = () => {
block.remove();
};
xhr.send(`deletetag=1&fromtag=${tagUrl}&token=${refreshedToken}`);
refreshToken(basePath);
existingTags = existingTags.filter((tagItem) => tagItem !== tag);
awesomepletes = updateAwesompleteList('.rename-tag-input', existingTags, awesomepletes, tagsSeparator);
}
});
});
const autocompleteFields = document.querySelectorAll('input[data-multiple]');
[...autocompleteFields].forEach((autocompleteField) => {
awesomepletes.push(createAwesompleteInstance(autocompleteField, tagsSeparator));
});
const exportForm = document.querySelector('#exportform');
if (exportForm != null) {
exportForm.addEventListener('submit', (event) => {
event.preventDefault();
refreshToken(basePath, () => {
event.target.submit();
});
});
}
const bulkCreationButton = document.querySelector('.addlink-batch-show-more-block');
if (bulkCreationButton != null) {
const toggleBulkCreationVisibility = (showMoreBlockElement, formElement) => {
if (bulkCreationButton.classList.contains('pure-u-0')) {
showMoreBlockElement.classList.remove('pure-u-0');
formElement.classList.add('pure-u-0');
} else {
showMoreBlockElement.classList.add('pure-u-0');
formElement.classList.remove('pure-u-0');
}
};
const bulkCreationForm = document.querySelector('.addlink-batch-form-block');
toggleBulkCreationVisibility(bulkCreationButton, bulkCreationForm);
bulkCreationButton.querySelector('a').addEventListener('click', (e) => {
e.preventDefault();
toggleBulkCreationVisibility(bulkCreationButton, bulkCreationForm);
});
// Force to send falsy value if the checkbox is not checked.
const privateButton = bulkCreationForm.querySelector('input[type="checkbox"][name="private"]');
const privateHiddenButton = bulkCreationForm.querySelector('input[type="hidden"][name="private"]');
privateButton.addEventListener('click', () => {
privateHiddenButton.disabled = !privateHiddenButton.disabled;
});
privateHiddenButton.disabled = privateButton.checked;
}
})();

View file

@ -1,81 +0,0 @@
/**
* Change the position counter of a row.
*
* @param elem Element Node to change.
* @param toPos int New position.
*/
function changePos(elem, toPos) {
const elemName = elem.getAttribute('data-line');
elem.setAttribute('data-order', toPos);
const hiddenInput = document.querySelector(`[name="order_${elemName}"]`);
hiddenInput.setAttribute('value', toPos);
}
/**
* Move a row up or down.
*
* @param pos Element Node to move.
* @param move int Move: +1 (down) or -1 (up)
*/
function changeOrder(pos, move) {
const newpos = parseInt(pos, 10) + move;
let lines = document.querySelectorAll(`[data-order="${pos}"]`);
const changelines = document.querySelectorAll(`[data-order="${newpos}"]`);
// If we go down reverse lines to preserve the rows order
if (move > 0) {
lines = [].slice.call(lines).reverse();
}
for (let i = 0; i < lines.length; i += 1) {
const parent = changelines[0].parentNode;
changePos(lines[i], newpos);
changePos(changelines[i], parseInt(pos, 10));
const changeItem = move < 0 ? changelines[0] : changelines[changelines.length - 1].nextSibling;
parent.insertBefore(lines[i], changeItem);
}
}
/**
* Move a row up in the table.
*
* @param pos int row counter.
*
* @return false
*/
function orderUp(pos) {
if (pos !== 0) {
changeOrder(pos, -1);
}
}
/**
* Move a row down in the table.
*
* @param pos int row counter.
*
* @returns false
*/
function orderDown(pos) {
const lastpos = parseInt(document.querySelector('[data-order]:last-child').getAttribute('data-order'), 10);
if (pos !== lastpos) {
changeOrder(pos, 1);
}
}
(() => {
/**
* Plugin admin order
*/
const orderPA = document.querySelectorAll('.order');
[...orderPA].forEach((link) => {
link.addEventListener('click', (event) => {
event.preventDefault();
if (event.target.classList.contains('order-up')) {
orderUp(parseInt(event.target.parentNode.parentNode.getAttribute('data-order'), 10));
} else if (event.target.classList.contains('order-down')) {
orderDown(parseInt(event.target.parentNode.parentNode.getAttribute('data-order'), 10));
}
});
});
})();

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,25 @@
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-light-dark.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/admonition-note.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/admonition-warning.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-arrow-left-circle.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-arrow-right-circle.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-cancel.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-check-with-border.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-check.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-chevron-up.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-clock.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-earth.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-edit.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-external-link.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-feed.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-logout.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-light-dark.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-link.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-logout.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-note.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-pin.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-search.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-secret.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-share.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-tag.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-tags.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-trash.svg
vendor/knah-tsaeb/kt-color-scheme/public/assets/icons/ui-user.svg

113
composer.lock generated
View file

@ -1051,11 +1051,11 @@
},
{
"name": "knah-tsaeb/kt-color-scheme",
"version": "1.0.7",
"version": "1.0.17",
"source": {
"type": "git",
"url": "https://forge.leslibres.org/knah-tsaeb/kt-color-scheme",
"reference": "643e2f88368990cbe814c573d0986de1ba9ed149"
"reference": "59080a0576307961092ba0d0a9f9d049e257e76b"
},
"require-dev": {
"matthiasmullie/minify": "^1.3"
@ -1092,7 +1092,7 @@
"icon",
"svg"
],
"time": "2025-03-19T11:20:00+00:00"
"time": "2025-04-17T07:38:04+00:00"
},
{
"name": "myclabs/deep-copy",
@ -1699,16 +1699,17 @@
"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
"reference": "af199f9f0a8c465dd03b06977d83d5b5cbe32a3a"
"reference": "6c54d20ae795b83ecf3f826311d7f488cd1ef005"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/af199f9f0a8c465dd03b06977d83d5b5cbe32a3a",
"reference": "af199f9f0a8c465dd03b06977d83d5b5cbe32a3a",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/6c54d20ae795b83ecf3f826311d7f488cd1ef005",
"reference": "6c54d20ae795b83ecf3f826311d7f488cd1ef005",
"shasum": ""
},
"conflict": {
"3f/pygmentize": "<1.2",
"adaptcms/adaptcms": "<=1.3",
"admidio/admidio": "<4.3.12",
"adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3",
"aheinze/cockpit": "<2.2",
@ -1733,7 +1734,8 @@
"andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5",
"apache-solr-for-typo3/solr": "<2.8.3",
"apereo/phpcas": "<1.6",
"api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3",
"api-platform/core": "<3.4.17|>=4.0.0.0-alpha1,<4.0.22",
"api-platform/graphql": "<3.4.17|>=4.0.0.0-alpha1,<4.0.22",
"appwrite/server-ce": "<=1.2.1",
"arc/web": "<3",
"area17/twill": "<1.2.5|>=2,<2.5.3",
@ -1749,6 +1751,7 @@
"awesome-support/awesome-support": "<=6.0.7",
"aws/aws-sdk-php": "<3.288.1",
"azuracast/azuracast": "<0.18.3",
"b13/seo_basics": "<0.8.2",
"backdrop/backdrop": "<1.27.3|>=1.28,<1.28.2",
"backpack/crud": "<3.4.9",
"backpack/filemanager": "<2.0.2|>=3,<3.0.9",
@ -1764,6 +1767,7 @@
"bbpress/bbpress": "<2.6.5",
"bcosca/fatfree": "<3.7.2",
"bedita/bedita": "<4",
"bednee/cooluri": "<1.0.30",
"bigfork/silverstripe-form-capture": ">=3,<3.1.1",
"billz/raspap-webgui": "<=3.1.4",
"bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3",
@ -1780,6 +1784,7 @@
"brotkrueml/typo3-matomo-integration": "<1.3.2",
"buddypress/buddypress": "<7.2.1",
"bugsnag/bugsnag-laravel": ">=2,<2.0.2",
"bvbmedia/multishop": "<2.0.39",
"bytefury/crater": "<6.0.2",
"cachethq/cachet": "<2.5.1",
"cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10",
@ -1798,6 +1803,7 @@
"civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3",
"ckeditor/ckeditor": "<4.25",
"clickstorm/cs-seo": ">=6,<6.7|>=7,<7.4|>=8,<8.3|>=9,<9.2",
"co-stack/fal_sftp": "<0.2.6",
"cockpit-hq/cockpit": "<2.7|==2.7",
"codeception/codeception": "<3.1.3|>=4,<4.1.22",
"codeigniter/framework": "<3.1.9",
@ -1805,9 +1811,10 @@
"codeigniter4/shield": "<1.0.0.0-beta8",
"codiad/codiad": "<=2.8.4",
"codingms/additional-tca": ">=1.7,<1.15.17|>=1.16,<1.16.9",
"commerceteam/commerce": ">=0.9.6,<0.9.9",
"components/jquery": ">=1.0.3,<3.5",
"composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7",
"concrete5/concrete5": "<9.4.0.0-RC1-dev",
"concrete5/concrete5": "<9.4.0.0-RC2-dev",
"concrete5/core": "<8.5.8|>=9,<9.1",
"contao-components/mediaelement": ">=2.14.2,<2.21.1",
"contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4",
@ -1836,7 +1843,11 @@
"desperado/xml-bundle": "<=0.1.7",
"dev-lancer/minecraft-motd-parser": "<=1.0.5",
"devgroup/dotplant": "<2020.09.14-dev",
"digimix/wp-svg-upload": "<=1",
"directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2",
"dl/yag": "<3.0.1",
"dmk/webkitpdf": "<1.1.4",
"dnadesign/silverstripe-elemental": "<5.3.12",
"doctrine/annotations": "<1.2.7",
"doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2",
"doctrine/common": "<2.4.3|>=2.5,<2.5.1",
@ -1849,9 +1860,25 @@
"dolibarr/dolibarr": "<19.0.2|==21.0.0.0-beta",
"dompdf/dompdf": "<2.0.4",
"doublethreedigital/guest-entries": "<3.1.2",
"drupal/core": ">=6,<6.38|>=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8",
"drupal/ai": "<1.0.5",
"drupal/alogin": "<2.0.6",
"drupal/cache_utility": "<1.2.1",
"drupal/config_split": "<1.10|>=2,<2.0.2",
"drupal/core": ">=6,<6.38|>=7,<7.102|>=8,<10.3.14|>=10.4,<10.4.5|>=11,<11.0.13|>=11.1,<11.1.5",
"drupal/core-recommended": ">=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8",
"drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8",
"drupal/formatter_suite": "<2.1",
"drupal/gdpr": "<3.0.1|>=3.1,<3.1.2",
"drupal/google_tag": "<1.8|>=2,<2.0.8",
"drupal/ignition": "<1.0.4",
"drupal/link_field_display_mode_formatter": "<1.6",
"drupal/matomo": "<1.24",
"drupal/oauth2_client": "<4.1.3",
"drupal/oauth2_server": "<2.1",
"drupal/obfuscate": "<2.0.1",
"drupal/rapidoc_elements_field_formatter": "<1.0.1",
"drupal/spamspan": "<3.2.1",
"drupal/tfa": "<1.10",
"duncanmcclean/guest-entries": "<3.1.2",
"dweeves/magmi": "<=0.7.24",
"ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2",
@ -1881,7 +1908,7 @@
"ezsystems/ezplatform-http-cache": "<2.3.16",
"ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.35",
"ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8",
"ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev|>=3.3,<3.3.40",
"ezsystems/ezplatform-richtext": ">=2.3,<2.3.26|>=3.3,<3.3.40",
"ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15",
"ezsystems/ezplatform-user": ">=1,<1.0.1",
"ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31",
@ -1935,6 +1962,8 @@
"funadmin/funadmin": "<=5.0.2",
"gaoming13/wechat-php-sdk": "<=1.10.2",
"genix/cms": "<=1.1.11",
"georgringer/news": "<1.3.3",
"geshi/geshi": "<1.0.8.11-dev",
"getformwork/formwork": "<1.13.1|>=2.0.0.0-beta1,<2.0.0.0-beta4",
"getgrav/grav": "<1.7.46",
"getkirby/cms": "<=3.6.6.5|>=3.7,<=3.7.5.4|>=3.8,<=3.8.4.3|>=3.9,<=3.9.8.1|>=3.10,<=3.10.1|>=4,<=4.3",
@ -1944,7 +1973,7 @@
"gilacms/gila": "<=1.15.4",
"gleez/cms": "<=1.3|==2",
"globalpayments/php-sdk": "<2",
"goalgorilla/open_social": "<12.3.8|>=12.4,<12.4.5|>=13.0.0.0-alpha1,<13.0.0.0-alpha11",
"goalgorilla/open_social": "<12.3.11|>=12.4,<12.4.10|>=13.0.0.0-alpha1,<13.0.0.0-alpha11",
"gogentooss/samlbase": "<1.2.7",
"google/protobuf": "<3.15",
"gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3",
@ -1967,7 +1996,7 @@
"hyn/multi-tenant": ">=5.6,<5.7.2",
"ibexa/admin-ui": ">=4.2,<4.2.3|>=4.6,<4.6.14",
"ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.6|>=4.6,<4.6.2",
"ibexa/fieldtype-richtext": ">=4.6,<4.6.10",
"ibexa/fieldtype-richtext": ">=4.6,<4.6.19",
"ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3",
"ibexa/http-cache": ">=4.6,<4.6.14",
"ibexa/post-install": "<1.0.16|>=4.6,<4.6.14",
@ -1983,7 +2012,7 @@
"illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75",
"imdbphp/imdbphp": "<=5.1.1",
"impresscms/impresscms": "<=1.4.5",
"impresspages/impresspages": "<=1.0.12",
"impresspages/impresspages": "<1.0.13",
"in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3",
"in2code/ipandlanguageredirect": "<5.1.2",
"in2code/lux": "<17.6.1|>=18,<24.0.2",
@ -1996,25 +2025,30 @@
"islandora/islandora": ">=2,<2.4.1",
"ivankristianto/phpwhois": "<=4.3",
"jackalope/jackalope-doctrine-dbal": "<1.7.4",
"jambagecom/div2007": "<0.10.2",
"james-heinrich/getid3": "<1.9.21",
"james-heinrich/phpthumb": "<1.7.12",
"jasig/phpcas": "<1.3.3",
"jbartels/wec-map": "<3.0.3",
"jcbrand/converse.js": "<3.3.3",
"joelbutcher/socialstream": "<5.6|>=6,<6.2",
"johnbillion/wp-crontrol": "<1.16.2",
"joomla/application": "<1.0.13",
"joomla/archive": "<1.1.12|>=2,<2.0.1",
"joomla/database": ">=1,<2.2|>=3,<3.4",
"joomla/filesystem": "<1.6.2|>=2,<2.0.1",
"joomla/filter": "<1.4.4|>=2,<2.0.1",
"joomla/framework": "<1.5.7|>=2.5.4,<=3.8.12",
"joomla/input": ">=2,<2.0.2",
"joomla/joomla-cms": ">=2.5,<3.9.12",
"joomla/joomla-cms": "<3.9.12|>=4,<4.4.13|>=5,<5.2.6",
"joomla/joomla-platform": "<1.5.4",
"joomla/session": "<1.3.1",
"joyqi/hyper-down": "<=2.4.27",
"jsdecena/laracom": "<2.0.9",
"jsmitty12/phpwhois": "<5.1",
"juzaweb/cms": "<=3.4",
"jweiland/events2": "<8.3.8|>=9,<9.0.6",
"jweiland/kk-downloader": "<1.2.2",
"kazist/phpwhois": "<=4.2.6",
"kelvinmo/simplexrd": "<3.1.1",
"kevinpapst/kimai2": "<1.16.7",
@ -2071,6 +2105,7 @@
"mainwp/mainwp": "<=4.4.3.3",
"mantisbt/mantisbt": "<=2.26.3",
"marcwillmann/turn": "<0.3.3",
"matomo/matomo": "<1.11",
"matyhtf/framework": "<3.0.6",
"mautic/core": "<5.2.3",
"mautic/core-lib": ">=1.0.0.0-beta,<4.4.13|>=5.0.0.0-alpha,<5.1.1",
@ -2082,6 +2117,7 @@
"mediawiki/data-transfer": ">=1.39,<1.39.11|>=1.41,<1.41.3|>=1.42,<1.42.2",
"mediawiki/matomo": "<2.4.3",
"mediawiki/semantic-media-wiki": "<4.0.2",
"mehrwert/phpmyadmin": "<3.2",
"melisplatform/melis-asset-manager": "<5.0.1",
"melisplatform/melis-cms": "<5.0.1",
"melisplatform/melis-front": "<5.0.1",
@ -2141,6 +2177,7 @@
"october/october": "<=3.6.4",
"october/rain": "<1.0.472|>=1.1,<1.1.2",
"october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.15",
"oliverklee/phpunit": "<3.5.15",
"omeka/omeka-s": "<4.0.3",
"onelogin/php-saml": "<2.10.4",
"oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5",
@ -2174,6 +2211,7 @@
"pear/archive_tar": "<1.4.14",
"pear/auth": "<1.2.4",
"pear/crypt_gpg": "<1.6.7",
"pear/http_request2": "<2.7",
"pear/pear": "<=1.10.1",
"pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1",
"personnummer/personnummer": "<3.0.2",
@ -2199,7 +2237,7 @@
"phpxmlrpc/extras": "<0.6.1",
"phpxmlrpc/phpxmlrpc": "<4.9.2",
"pi/pi": "<=2.5",
"pimcore/admin-ui-classic-bundle": "<1.7.4",
"pimcore/admin-ui-classic-bundle": "<1.7.6",
"pimcore/customer-management-framework-bundle": "<4.2.1",
"pimcore/data-hub": "<1.2.4",
"pimcore/data-importer": "<1.8.9|>=1.9,<1.9.3",
@ -2207,7 +2245,8 @@
"pimcore/ecommerce-framework-bundle": "<1.0.10",
"pimcore/perspective-editor": "<1.5.1",
"pimcore/pimcore": "<11.5.4",
"pixelfed/pixelfed": "<0.11.11",
"piwik/piwik": "<1.11",
"pixelfed/pixelfed": "<0.12.5",
"plotly/plotly.js": "<2.25.2",
"pocketmine/bedrock-protocol": "<8.0.2",
"pocketmine/pocketmine-mp": "<5.25.2",
@ -2232,6 +2271,7 @@
"ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2",
"ptrofimov/beanstalk_console": "<1.7.14",
"pubnub/pubnub": "<6.1",
"punktde/pt_extbase": "<1.5.1",
"pusher/pusher-php-server": "<2.2.1",
"pwweb/laravel-core": "<=0.3.6.0-beta",
"pxlrbt/filament-excel": "<1.1.14|>=2.0.0.0-alpha,<2.3.3",
@ -2264,12 +2304,12 @@
"serluck/phpwhois": "<=4.2.6",
"sfroemken/url_redirect": "<=1.2.1",
"sheng/yiicms": "<1.2.1",
"shopware/core": "<=6.5.8.12|>=6.6,<=6.6.5",
"shopware/platform": "<=6.5.8.12|>=6.6,<=6.6.5",
"shopware/core": "<6.5.8.17-dev|>=6.6,<6.6.10.3-dev|>=6.7.0.0-RC1-dev,<6.7.0.0-RC2-dev",
"shopware/platform": "<6.5.8.17-dev|>=6.6,<6.6.10.3-dev|>=6.7.0.0-RC1-dev,<6.7.0.0-RC2-dev",
"shopware/production": "<=6.3.5.2",
"shopware/shopware": "<=5.7.17",
"shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev",
"shopxo/shopxo": "<=6.1",
"shopxo/shopxo": "<=6.4",
"showdoc/showdoc": "<2.10.4",
"shuchkin/simplexlsx": ">=1.0.12,<1.1.13",
"silverstripe-australia/advancedreports": ">=1,<=2",
@ -2278,7 +2318,7 @@
"silverstripe/cms": "<4.11.3",
"silverstripe/comments": ">=1.3,<3.1.1",
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
"silverstripe/framework": "<5.3.8",
"silverstripe/framework": "<5.3.23",
"silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3",
"silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1",
"silverstripe/recipe-cms": ">=4.5,<4.5.3",
@ -2301,7 +2341,9 @@
"simplesamlphp/xml-security": "==1.6.11",
"simplito/elliptic-php": "<1.0.6",
"sitegeist/fluid-components": "<3.5",
"sjbr/sr-feuser-register": "<2.6.2",
"sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3",
"sjbr/static-info-tables": "<2.3.1",
"slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1",
"slim/slim": "<2.6",
"slub/slub-events": "<3.0.3",
@ -2329,6 +2371,7 @@
"sulu/sulu": "<1.6.44|>=2,<2.5.21|>=2.6,<2.6.5",
"sumocoders/framework-user-bundle": "<1.4",
"superbig/craft-audit": "<3.0.2",
"svewap/a21glossary": "<=0.4.10",
"swag/paypal": "<5.4.4",
"swiftmailer/swiftmailer": "<6.2.5",
"swiftyedit/swiftyedit": "<1.2",
@ -2381,7 +2424,7 @@
"t3/dce": "<0.11.5|>=2.2,<2.6.2",
"t3g/svg-sanitizer": "<1.0.3",
"t3s/content-consent": "<1.0.3|>=2,<2.0.2",
"tastyigniter/tastyigniter": "<3.3",
"tastyigniter/tastyigniter": "<4",
"tcg/voyager": "<=1.8",
"tecnickcom/tc-lib-pdf-font": "<2.6.4",
"tecnickcom/tcpdf": "<6.8",
@ -2416,6 +2459,7 @@
"typo3/cms-dashboard": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
"typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1",
"typo3/cms-extensionmanager": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
"typo3/cms-felogin": ">=4.2,<4.2.3",
"typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1",
"typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2",
"typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5",
@ -2440,21 +2484,24 @@
"uvdesk/core-framework": "<=1.1.1",
"vanilla/safecurl": "<0.9.2",
"verbb/comments": "<1.5.5",
"verbb/formie": "<2.1.6",
"verbb/formie": "<=2.1.43",
"verbb/image-resizer": "<2.0.9",
"verbb/knock-knock": "<1.2.8",
"verot/class.upload.php": "<=2.1.6",
"vertexvaar/falsftp": "<0.2.6",
"villagedefrance/opencart-overclocked": "<=1.11.1",
"vova07/yii2-fileapi-widget": "<0.1.9",
"vrana/adminer": "<4.8.1",
"vufind/vufind": ">=2,<9.1.1",
"waldhacker/hcaptcha": "<2.1.2",
"wallabag/tcpdf": "<6.2.22",
"wallabag/wallabag": "<2.6.7",
"wallabag/wallabag": "<2.6.11",
"wanglelecc/laracms": "<=1.0.3",
"wapplersystems/a21glossary": "<=0.4.10",
"web-auth/webauthn-framework": ">=3.3,<3.3.4|>=4.5,<4.9",
"web-auth/webauthn-lib": ">=4.5,<4.9",
"web-feet/coastercms": "==5.5",
"web-tp3/wec_map": "<3.0.3",
"webbuilders-group/silverstripe-kapost-bridge": "<0.4",
"webcoast/deferred-image-processing": "<1.0.2",
"webklex/laravel-imap": "<5.3",
@ -2480,15 +2527,15 @@
"xataface/xataface": "<3",
"xpressengine/xpressengine": "<3.0.15",
"yab/quarx": "<2.4.5",
"yeswiki/yeswiki": "<=4.4.5",
"yeswiki/yeswiki": "<4.5.2",
"yetiforce/yetiforce-crm": "<6.5",
"yidashi/yii2cmf": "<=2",
"yii2mod/yii2-cms": "<1.9.2",
"yiisoft/yii": "<1.1.29",
"yiisoft/yii2": "<2.0.49.4-dev",
"yiisoft/yii": "<1.1.31",
"yiisoft/yii2": "<2.0.52",
"yiisoft/yii2-authclient": "<2.2.15",
"yiisoft/yii2-bootstrap": "<2.0.4",
"yiisoft/yii2-dev": "<2.0.43",
"yiisoft/yii2-dev": "<=2.0.45",
"yiisoft/yii2-elasticsearch": "<2.0.5",
"yiisoft/yii2-gii": "<=2.2.4",
"yiisoft/yii2-jui": "<2.0.4",
@ -2570,7 +2617,7 @@
"type": "tidelift"
}
],
"time": "2025-03-19T17:05:08+00:00"
"time": "2025-04-17T15:05:22+00:00"
},
{
"name": "sebastian/cli-parser",
@ -3537,16 +3584,16 @@
},
{
"name": "squizlabs/php_codesniffer",
"version": "3.12.0",
"version": "3.12.2",
"source": {
"type": "git",
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
"reference": "2d1b63db139c3c6ea0c927698e5160f8b3b8d630"
"reference": "6d4cf6032d4b718f168c90a96e36c7d0eaacb2aa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/2d1b63db139c3c6ea0c927698e5160f8b3b8d630",
"reference": "2d1b63db139c3c6ea0c927698e5160f8b3b8d630",
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/6d4cf6032d4b718f168c90a96e36c7d0eaacb2aa",
"reference": "6d4cf6032d4b718f168c90a96e36c7d0eaacb2aa",
"shasum": ""
},
"require": {
@ -3617,7 +3664,7 @@
"type": "thanks_dev"
}
],
"time": "2025-03-18T05:04:51+00:00"
"time": "2025-04-13T04:10:18+00:00"
},
{
"name": "theseer/tokenizer",

View file

@ -1,40 +0,0 @@
<?php
namespace Favicon;
/**
* DataAccess is a wrapper used to read/write data locally or remotly
* Aside from SOLID principles, this wrapper is also useful to mock remote resources in unit tests
* Note: remote access warning are silenced because we don't care if a website is unreachable
**/
class DataAccess {
public function retrieveUrl($url) {
$this->set_context();
return @file_get_contents($url);
}
public function retrieveHeader($url) {
$this->set_context();
return @get_headers($url, TRUE);
}
public function saveCache($file, $data) {
file_put_contents($file, $data);
}
public function readCache($file) {
return file_get_contents($file);
}
private function set_context() {
stream_context_set_default(
array(
'http' => array(
'method' => 'GET',
'timeout' => 10,
'header' => "User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:20.0; Favicon; +https://github.com/ArthurHoaro/favicon) Gecko/20100101 Firefox/32.0\r\n",
)
)
);
}
}

View file

@ -1,293 +0,0 @@
<?php
namespace Favicon;
class Favicon
{
protected $url = '';
protected $cacheDir;
protected $cacheTimeout;
protected $dataAccess;
public function __construct($args = array())
{
if (isset($args['url'])) {
$this->url = $args['url'];
}
$this->cacheDir = __DIR__ . '/../../resources/cache';
$this->dataAccess = new DataAccess();
}
public function cache($args = array()) {
if (isset($args['dir'])) {
$this->cacheDir = $args['dir'];
}
if (!empty($args['timeout'])) {
$this->cacheTimeout = $args['timeout'];
} else {
$this->cacheTimeout = 0;
}
}
public static function baseUrl($url, $path = false)
{
$return = '';
if (!$url = parse_url($url)) {
return FALSE;
}
// Scheme
$scheme = isset($url['scheme']) ? strtolower($url['scheme']) : null;
if ($scheme != 'http' && $scheme != 'https') {
return FALSE;
}
$return .= "{$scheme}://";
// Username and password
if (isset($url['user'])) {
$return .= $url['user'];
if (isset($url['pass'])) {
$return .= ":{$url['pass']}";
}
$return .= '@';
}
// Hostname
if( !isset($url['host']) ) {
return FALSE;
}
$return .= $url['host'];
// Port
if (isset($url['port'])) {
$return .= ":{$url['port']}";
}
// Path
if( $path && isset($url['path']) ) {
$return .= $url['path'];
}
$return .= '/';
return $return;
}
public function info($url)
{
if(empty($url) || $url === false) {
return false;
}
$max_loop = 5;
// Discover real status by following redirects.
$loop = TRUE;
while ($loop && $max_loop-- > 0) {
$headers = $this->dataAccess->retrieveHeader($url);
$exploded = explode(' ', $headers[0]);
if( !isset($exploded[1]) ) {
return false;
}
list(,$status) = $exploded;
switch ($status) {
case '301':
case '302':
$url = $headers['Location'];
break;
default:
$loop = FALSE;
break;
}
}
return array('status' => $status, 'url' => $url);
}
public function endRedirect($url) {
$out = $this->info($url);
return !empty($out['url']) ? $out['url'] : false;
}
/**
* Find remote (or cached) favicon
* @return favicon URL, false if nothing was found
**/
public function get($url = '')
{
// URLs passed to this method take precedence.
if (!empty($url)) {
$this->url = $url;
}
// Get the base URL without the path for clearer concatenations.
$original = rtrim($this->baseUrl($this->url, true), '/');
$url = rtrim($this->endRedirect($this->baseUrl($this->url, false)), '/');
if(($favicon = $this->checkCache($url)) || ($favicon = $this->getFavicon($url))) {
$base = true;
}
elseif(($favicon = $this->checkCache($original)) || ($favicon = $this->getFavicon($original, false))) {
$base = false;
}
else
return false;
// Save cache if necessary
$cache = $this->cacheDir . '/' . md5($base ? $url : $original);
if ($this->cacheTimeout && !file_exists($cache) || (is_writable($cache) && time() - filemtime($cache) > $this->cacheTimeout)) {
$this->dataAccess->saveCache($cache, $favicon);
}
return $favicon;
}
private function getFavicon($url, $checkDefault = true) {
$favicon = false;
if(empty($url)) {
return false;
}
// Try /favicon.ico first.
if( $checkDefault ) {
$info = $this->info("{$url}/favicon.ico");
if ($info['status'] == '200') {
$favicon = $info['url'];
}
}
// See if it's specified in a link tag in domain url.
if (!$favicon) {
$favicon = $this->getInPage($url);
}
// Make sure the favicon is an absolute URL.
if( $favicon && filter_var($favicon, FILTER_VALIDATE_URL) === false ) {
$favicon = $url . '/' . $favicon;
}
// Sometimes people lie, so check the status.
// And sometimes, it's not even an image. Sneaky bastards!
// If cacheDir isn't writable, that's not our problem
if ($favicon && is_writable($this->cacheDir) && !$this->checkImageMType($favicon)) {
$favicon = false;
}
return $favicon;
}
private function getInPage($url) {
$html = $this->dataAccess->retrieveUrl("{$url}/");
preg_match('!<head.*?>.*</head>!ims', $html, $match);
if(empty($match) || count($match) == 0) {
return false;
}
$head = $match[0];
$dom = new \DOMDocument();
// Use error supression, because the HTML might be too malformed.
if (@$dom->loadHTML($head)) {
$links = $dom->getElementsByTagName('link');
foreach ($links as $link) {
if ($link->hasAttribute('rel') && strtolower($link->getAttribute('rel')) == 'shortcut icon') {
return $link->getAttribute('href');
} elseif ($link->hasAttribute('rel') && strtolower($link->getAttribute('rel')) == 'icon') {
return $link->getAttribute('href');
} elseif ($link->hasAttribute('href') && strpos($link->getAttribute('href'), 'favicon') !== FALSE) {
return $link->getAttribute('href');
}
}
}
return false;
}
private function checkCache($url) {
if ($this->cacheTimeout) {
$cache = $this->cacheDir . '/' . md5($url);
if (file_exists($cache) && is_readable($cache) && (time() - filemtime($cache) < $this->cacheTimeout)) {
return $this->dataAccess->readCache($cache);
}
}
return false;
}
private function checkImageMType($url) {
$tmpFile = $this->cacheDir . '/tmp.ico';
$fileContent = $this->dataAccess->retrieveUrl($url);
$this->dataAccess->saveCache($tmpFile, $fileContent);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$isImage = strpos(finfo_file($finfo, $tmpFile), 'image') !== false;
finfo_close($finfo);
unlink($tmpFile);
return $isImage;
}
/**
* @return mixed
*/
public function getCacheDir()
{
return $this->cacheDir;
}
/**
* @param mixed $cacheDir
*/
public function setCacheDir($cacheDir)
{
$this->cacheDir = $cacheDir;
}
/**
* @return mixed
*/
public function getCacheTimeout()
{
return $this->cacheTimeout;
}
/**
* @param mixed $cacheTimeout
*/
public function setCacheTimeout($cacheTimeout)
{
$this->cacheTimeout = $cacheTimeout;
}
/**
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* @param string $url
*/
public function setUrl($url)
{
$this->url = $url;
}
/**
* @param DataAccess $dataAccess
*/
public function setDataAccess($dataAccess)
{
$this->dataAccess = $dataAccess;
}
}

View file

@ -22,7 +22,7 @@ function myShaarli_init($conf) {
$conf->set('thumbnails.mode', 'none');
return array($error);
}
if (!in_array($conf->get('resource.theme'), ['myShaarli', 'myShaarli_Columns'])) {
if (!in_array($conf->get('resource.theme'), ['myShaarli', 'myShaarli_Columns', 'myShaarli_V2'])) {
$error = 'myShaarli plugin: ' .
'This plugin need modification of template. Use myShaarli theme for test.';
$conf->set('thumbnails.mode', 'none');
@ -72,10 +72,13 @@ function hook_myShaarli_render_linklist($data, $conf) {
'href' => '?searchtags=note',
'title' => 'Note',
),
'html' => '<i class="fa fa-sticky-note"> </i>',
'html' => '<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="tpl/myShaarli/sprites/default.svg#ui-note"></use>
</svg>',
);
if (isset($_GET['searchtags']) && $_GET['searchtags'] === 'note') {
$action['on'] = true;
$action['attr']['href'] = '?';
} else {
$action['off'] = true;
}
@ -114,7 +117,7 @@ function hook_myShaarli_render_linklist($data, $conf) {
function hook_myShaarli_render_picwall($data, $conf) {
$thumUrl = $conf->get('plugins.ExternalThumbshot_URL');
$thumUrl = $conf->get('plugins.ExternalThumbshot_URL');
if (!empty($conf->get('plugins.ExternalThumbshot_KEY'))) {
$key = $conf->get('plugins.ExternalThumbshot_KEY');
}

View file

@ -1,2 +1,2 @@
<label for="lf_origin"><i>Origin</i></label><br>
<input type="text" name="lf_origin" id="lf_origin" value="%s" class="lf_input" value="https://aijam.com"><br>
<label for="lf_origin">Origin</label>
<input type="text" name="lf_origin" id="lf_origin" value="%s" class="lf_input">

View file

@ -1 +1,4 @@
<input type="checkbox" name="readitlater" id="readitlater_%s" %s /><label for="readitlater_%s"> Read it later</label><br>
<label for="readitlater_%s">
<input type="checkbox" name="readitlater" id="readitlater_%s" %s />
Read it later
</label>

View file

@ -5,77 +5,49 @@
</head>
<body>
{include="page.header"}
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div id="addlink-form" class="page-form page-form-light pure-u-lg-1-3 pure-u-22-24">
<div id="addlink-form" class="addlink-form section">
<h2 class="window-title">{"Shaare a new link"|t}</h2>
<form method="GET" action="{$base_path}/admin/shaare" name="addform" class="addform">
<div>
<label for="shaare">{'URL or leave empty to post a note'|t}</label>
<input type="text" name="post" id="shaare" class="autofocus">
</div>
<div>
<input type="submit" value="{'Add link'|t}">
</div>
<p>
<input type="submit" value="{'Add link'|t}">
</p>
</form>
<div class="addlink-batch-show-more-block pure-u-0">
<a href="#">{'BULK CREATION'|t} <svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-plus-circle"></use></svg></a>
</div>
</div>
<div class="addlink-batch-form-block addlink-form section">
{if="empty($async_metadata)"}
<p>
{'Metadata asynchronous retrieval is disabled.'|t}
{'We recommend that you enable the setting <em>general > enable_async_metadata</em> in your configuration file to use bulk link creation.'|t}
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-close-circle"></use></svg>
</p>
{/if}
<h2 class="window-title">{"Shaare multiple new links"|t}</h2>
<form method="POST" action="{$base_path}/admin/shaare-batch" name="batch-addform" class="batch-addform">
<label for="urls">{'Add one URL per line to create multiple bookmarks.'|t}</label>
<textarea name="urls" id="urls"></textarea>
<label for="tags">{'Tags'|t}</label>
<input type="text" name="tags" id="tags" class="lf_input"
data-list="{loop="$tags"}{$key}, {/loop}" data-multiple data-autofirst autocomplete="off">
<input type="hidden" name="private" value="0">
<label for="lf_private"></label><input type="checkbox" name="private" {if="$default_private_links"} checked="checked"{/if}>
&nbsp; {'Private'|t}</label>
<p>
<input type="hidden" name="token" value="{$token}">
<input type="submit" value="{'Add links'|t}">
</p>
</form>
</div>
</div>
<div class="pure-g addlink-batch-show-more-block pure-u-0">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div class="pure-u-lg-1-3 pure-u-22-24 addlink-batch-show-more">
<a href="#">{'BULK CREATION'|t}&nbsp;<i class="fa fa-plus-circle" aria-hidden="true"></i></a>
</div>
</div>
<div class="addlink-batch-form-block">
{if="empty($async_metadata)"}
<div class="pure-g pure-alert pure-alert-warning pure-alert-closable">
<div class="pure-u-2-24"></div>
<div class="pure-u-20-24">
<p>
{'Metadata asynchronous retrieval is disabled.'|t}
{'We recommend that you enable the setting <em>general > enable_async_metadata</em> in your configuration file to use bulk link creation.'|t}
</p>
</div>
<div class="pure-u-2-24">
<i class="fa fa-times pure-alert-close"></i>
</div>
</div>
{/if}
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div id="batch-addlink-form" class="page-form page-form-light pure-u-lg-1-3 pure-u-22-24">
<h2 class="window-title">{"Shaare multiple new links"|t}</h2>
<form method="POST" action="{$base_path}/admin/shaare-batch" name="batch-addform" class="batch-addform">
<div>
<label for="urls">{'Add one URL per line to create multiple bookmarks.'|t}</label>
<textarea name="urls" id="urls"></textarea>
<div>
<label for="tags">{'Tags'|t}</label>
</div>
<div>
<input type="text" name="tags" id="tags" class="lf_input"
data-list="{loop="$tags"}{$key}, {/loop}" data-multiple data-autofirst autocomplete="off">
</div>
<div>
<input type="hidden" name="private" value="0">
<input type="checkbox" name="private" {if="$default_private_links"} checked="checked"{/if}>
&nbsp; <label for="lf_private">{'Private'|t}</label>
</div>
</div>
<div>
<input type="hidden" name="token" value="{$token}">
<input type="submit" value="{'Add links'|t}">
</div>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
</html>

View file

@ -1,28 +1,29 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div id="addlink-form" class="page-form page-form-light pure-u-lg-1-3 pure-u-22-24">
<h2 class="window-title">{"Change password"|t}</h2>
<form method="POST" action="{$base_path}/admin/password" name="changepasswordform" id="changepasswordform">
<div>
<input type="password" name="oldpassword" aria-label="{'Current password'|t}" placeholder="{'Current password'|t}" class="autofocus">
</div>
<div>
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<section>
<h2>{"Change password"|t}</h2>
<form method="POST" action="{$base_path}/admin/password" name="changepasswordform" id="changepasswordform">
<label>{'Current password'|t}</label>
<input type="password" name="oldpassword" aria-label="{'Current password'|t}"
placeholder="{'Current password'|t}" class="autofocus">
<label>{'New password'|t}</label>
<input type="password" name="setpassword" aria-label="{'New password'|t}" placeholder="{'New password'|t}">
</div>
<input type="hidden" name="token" value="{$token}">
<div>
<input type="hidden" name="token" value="{$token}">
<input type="submit" value="{'Change'|t}">
</div>
</form>
</div>
</div>
{include="page.footer"}
</body>
</html>
</form>
</section>
{include="page.footer"}
</body>
</html>

View file

@ -1,66 +1,63 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<section>
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div id="addlink-form" class="page-form page-form-light pure-u-lg-1-3 pure-u-22-24">
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<section>
<h2 class="window-title">{"Manage tags"|t}</h2>
<form method="POST" action="{$base_path}/admin/tags" name="changetag" id="changetag">
<div>
<input type="text" name="fromtag" aria-label="{'Tag'|t}" placeholder="{'Tag'|t}" value="{$fromtag}"
list="tagsList" autocomplete="off" class="awesomplete autofocus" data-minChars="1">
<datalist id="tagsList">
{loop="$tags"}<option>{$key}</option>{/loop}
</datalist>
</div>
<div>
<input type="text" name="totag" aria-label="{'New name'|t}" placeholder="{'New name'|t}"
list="toTagsList" autocomplete="off" class="awesomplete" data-minChars="1">
<datalist id="toTagsList">
{loop="$tags"}<option>{$key}</option>{/loop}
</datalist>
</div>
<div><i class="fa fa-info-circle" aria-hidden="true"></i> {'Case sensitive'|t}</div>
<label for="fromtag">{'Tag'|t}</label>
<input type="text" name="fromtag" aria-label="{'Tag'|t}" placeholder="{'Tag'|t}" value="{$fromtag}"
list="tagsList" autocomplete="off" class="awesomplete autofocus" data-minChars="1" id="fromtag">
<datalist id="tagsList">
{loop="$tags"}<option>{$key}</option>{/loop}
</datalist>
<label for="totag">{'New name'|t}</label>
<input type="text" name="totag" aria-label="{'New name'|t}" placeholder="{'New name'|t}" list="toTagsList"
autocomplete="off" class="awesomplete" data-minChars="1" id="totag">
<datalist id="toTagsList">
{loop="$tags"}<option>{$key}</option>{/loop}
</datalist>
<p><svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon">
<use href="{$asset_path}/sprites/default.svg#admonition-note"></use>
</svg> {'Case sensitive'|t}</p>
<input type="hidden" name="token" value="{$token}">
<div>
<input type="submit" value="{'Rename tag'|t}" name="renametag">
<input type="submit" value="{'Delete tag'|t}" name="deletetag"
class="button button-red confirm-delete" data-type="tag">
</div>
<input type="submit" value="{'Delete tag'|t}" name="deletetag" class="error confirm-delete" data-type="tag">
<input type="submit" value="{'Rename tag'|t}" name="renametag" class="success">
</form>
</section>
<p>{'You can also edit tags in the'|t} <a href="{$base_path}/tags/list?sort=usage">{'tag list'|t}</a>.</p>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div class="page-form page-form-light pure-u-lg-1-3 pure-u-22-24">
<section>
<h2 class="window-title">{"Change tags separator"|t}</h2>
<form method="POST" action="{$base_path}/admin/tags/change-separator" name="changeseparator" id="changeseparator">
<p>
{'Your current tag separator is'|t} <code>{$tags_separator}</code>{if="!empty($tags_separator_desc)"} ({$tags_separator_desc}){/if}.
</p>
<div>
<input type="text" name="separator" placeholder="{'New separator'|t}"
id="separator">
</div>
<input type="hidden" name="token" value="{$token}">
<div>
<input type="submit" value="{'Save'|t}" name="saveseparator">
</div>
<p>
<aside class="admonition adm-warning">
<header><svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon warning">
<use href="{$asset_path}/sprites/default.svg#admonition-warning"></use>
</svg> Note</header>
{'Note that hashtags won\'t fully work with a non-whitespace separator.'|t}
</aside>
<p>
{'Your current tag separator is'|t}
<strong>&nbsp;{$tags_separator}&nbsp;</strong>{if="!empty($tags_separator_desc)"}
({$tags_separator_desc}){/if}
</p>
<label for="separator">{'New separator'|t}</label>
<input type="text" name="separator" placeholder="{'New separator'|t}" id="separator">
<input type="hidden" name="token" value="{$token}">
<input type="submit" value="{'Save'|t}" name="saveseparator">
</form>
</div>
</div>
</section>
{include="page.footer"}
</body>
</html>
</section>
{include="page.footer"}
</body>
</html>

View file

@ -1,325 +1,147 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
{$ratioLabel='5-12'}
{$ratioLabelMobile='7-8'}
{$ratioInput='7-12'}
{$ratioInputMobile='1-8'}
<head>
{include="includes"}
</head>
<form method="POST" action="{$base_path}/admin/configure" name="configform" id="configform">
<div class="pure-g">
<div class="pure-u-lg-1-8 pure-u-1-24"></div>
<div class="pure-u-lg-3-4 pure-u-22-24 page-form page-form-complete">
<body>
{include="page.header"}
<section>
<h2 class="window-title">{'Configure'|t}</h2>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
<div class="form-label">
<label for="title">
<span class="label-name">Shaarli {'title'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-7-12 pure-u-1">
<div class="form-input">
<input type="text" name="title" id="title" size="50" value="{$title}">
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
<div class="form-label">
<label for="titleLink">
<span class="label-name">{'Home link'|t}</span><br>
<span class="label-desc">{'Default value'|t}: {$base_path}/</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-1">
<div class="form-input">
<input type="text" name="titleLink" id="titleLink" size="50" value="{$titleLink}">
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
<div class="form-label">
<label for="titleLink">
<span class="label-name">{'Themes'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-1">
<div class="form-input">
<select name="theme" id="theme" class="align">
{loop="$theme_available"}
<option value="{$value}"
{if="$value===$theme"}
selected="selected"
{/if}
>
{$value|ucfirst}
</option>
{/loop}
</select>
</div>
</div>
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
<div class="form-label">
<label for="formatter">
<span class="label-name">{'Description formatter'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-1">
<div class="form-input">
<select name="formatter" id="formatter" class="align">
{loop="$formatter_available"}
<option value="{$value}"
{if="$value===$formatter"}
selected="selected"
{/if}
>
{$value|ucfirst}
</option>
{/loop}
</select>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
<div class="form-label">
<label for="language">
<span class="label-name">{'Languages'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-1">
<div class="form-input">
<select name="language" id="language" class="align">
{loop="$languages"}
<option value="{$key}"
{if="$key===$language"}
selected="selected"
{/if}
>
{$value}
</option>
{/loop}
</select>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-1 ">
<div class="form-label">
<label>
<span class="label-name">{'Timezone'|t}</span><br>
<span class="label-desc">{'Continent'|t} &middot; {'City'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-1 ">
<div class="form-input">
<div class="timezone">
<select id="continent" name="continent">
{loop="$continents"}
{if="$key !== 'selected'"}
<option value="{$value}" {if="$continents.selected === $value"}selected{/if}>
{$value}
</option>
{/if}
{/loop}
</select>
<select id="city" name="city">
{loop="$cities"}
{if="$key !== 'selected'"}
<option value="{$value.city}"
{if="$cities.selected === $value.city"}selected{/if}
data-continent="{$value.continent}">
{$value.city}
</option>
{/if}
{/loop}
</select>
</div>
</div>
</div>
</div>
<div class="clear"></div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile} ">
<div class="form-label">
<label for="disablesessionprotection">
<span class="label-name">{'Disable session cookie hijacking protection'|t}</span><br>
<span class="label-desc">
{'Check this if you get disconnected or if your IP address changes often'|t}
</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile} ">
<div class="form-input">
<input type="checkbox" name="disablesessionprotection" id="disablesessionprotection"
{if="$session_protection_disabled"}checked{/if}>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile} ">
<div class="form-label">
<label for="privateLinkByDefault">
<span class="label-name">{'Private links by default'|t}</span><br>
<span class="label-desc">{'All new links are private by default'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile} ">
<div class="form-input">
<input type="checkbox" name="privateLinkByDefault" id="privateLinkByDefault"
{if="$private_links_default"}checked{/if}/>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile} ">
<div class="form-label">
<label for="enableRssPermalinks">
<span class="label-name">{'RSS direct links'|t}</span><br>
<span class="label-desc">{'Check this to use direct URL instead of permalink in feeds'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile} ">
<div class="form-input">
<input type="checkbox" name="enableRssPermalinks" id="enableRssPermalinks"
{if="$enable_rss_permalinks"}checked{/if}/>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile}">
<div class="form-label">
<label for="hidePublicLinks">
<span class="label-name">{'Hide public links'|t}</span><br>
<span class="label-desc">{'Do not show any links if the user is not logged in'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
<div class="form-input">
<input type="checkbox" name="hidePublicLinks" id="hidePublicLinks"
{if="$hide_public_links"}checked{/if}/>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile}">
<div class="form-label">
<label for="updateCheck">
<span class="label-name">{'Check for updates'|t}</span><br>
<span class="label-desc">{'Notify me when a new release is ready'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
<div class="form-input">
<input type="checkbox" name="updateCheck" id="updateCheck"
{if="$enable_update_check"}checked{/if}/>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile}">
<div class="form-label">
<label for="retrieveDescription">
<span class="label-name">{'Automatically retrieve description for new bookmarks'|t}</span><br>
<span class="label-desc">{'Shaarli will try to retrieve the description from meta HTML headers'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
<div class="form-input">
<input type="checkbox" name="retrieveDescription" id="retrieveDescription"
{if="$retrieve_description"}checked{/if}/>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile}">
<div class="form-label">
<label for="enableApi">
<span class="label-name">{'Enable REST API'|t}</span><br>
<span class="label-desc">{'Allow third party software to use Shaarli such as mobile application'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
<div class="form-input">
<input type="checkbox" name="enableApi" id="enableApi"
{if="$api_enabled"}checked{/if}/>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
<div class="form-label">
<label for="apiSecret">
<span class="label-name">{'REST API secret'|t}</span><br>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
<div class="form-input">
<input type="text" name="apiSecret" id="apiSecret" size="50" value="{$api_secret}">
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile}">
<div class="form-label">
<label for="enableThumbnails">
<span class="label-name">{'Enable thumbnails'|t}</span><br>
<span class="label-desc">
{if="! $gd_enabled"}
{'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}
{elseif="$thumbnails_enabled"}
<a href="{$base_path}/admin/thumbnails">{'Synchronize thumbnails'|t}</a>
{/if}
</span>
</label>
</div>
</div>
<div class="pure-u-lg-{$ratioInput} pure-u-{$ratioInputMobile}">
<div class="form-input">
<select name="enableThumbnails" id="enableThumbnails" class="align">
<option value="all" {if="$thumbnails_mode=='all'"}selected{/if}>
{'All'|t}
</option>
<option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
{'Only common media hosts'|t}
</option>
<option value="none" {if="$thumbnails_mode=='none'"}selected{/if}>
{'None'|t}
</option>
</select>
</div>
</div>
</div>
<div class="center">
<form method="POST" action="{$base_path}/admin/configure" name="configform" id="configform">
<label for="title">Shaarli {'title'|t}</label>
<input type="text" name="title" id="title" value="{$title}">
<label for="titleLink">{'Home link'|t}</label>
<input type="text" name="titleLink" id="titleLink" size="50" value="{$titleLink}">
<label for="titleLink">{'Themes'|t}</label>
<select name="theme" id="theme">
{loop="$theme_available"}
<option value="{$value}" {if="$value===$theme"} selected="selected" {/if}>
{$value|ucfirst}
</option>
{/loop}
</select>
<label for="formatter">{'Description formatter'|t}</label>
<select name="formatter" id="formatter">
{loop="$formatter_available"}
<option value="{$value}" {if="$value===$formatter"} selected="selected" {/if}>
{$value|ucfirst}
</option>
{/loop}
</select>
<label for="language">{'Languages'|t}</label>
<select name="language" id="language">
{loop="$languages"}
<option value="{$key}" {if="$key===$language"} selected="selected" {/if}>
{$value}
</option>
{/loop}
</select>
<label for="continent">{'Continent'|t}</label>
<select id="continent" name="continent">
{loop="$continents"}
{if="$key !== 'selected'"}
<option value="{$value}" {if="$continents.selected === $value"}selected{/if}>
{$value}
</option>
{/if}
{/loop}
</select>
<label for="city">{'City'|t}</label>
<select id="city" name="city">
{loop="$cities"}
{if="$key !== 'selected'"}
<option value="{$value.city}" {if="$cities.selected === $value.city"}selected{/if}
data-continent="{$value.continent}">
{$value.city}
</option>
{/if}
{/loop}
</select>
<label for="disablesessionprotection">
<input type="checkbox" name="disablesessionprotection" id="disablesessionprotection"
{if="$session_protection_disabled"}checked{/if}>
{'Disable session cookie hijacking protection'|t}
</label>
<small>{'Check this if you get disconnected or if your IP address changes often'|t}</small>
<label for="privateLinkByDefault">
<input type="checkbox" name="privateLinkByDefault" id="privateLinkByDefault" {if="$private_links_default"}checked{/if}>
{'Private links by default'|t}
</label>
<small>{'All new links are private by default'|t}</small>
<label for="enableRssPermalinks">
<input type="checkbox" name="enableRssPermalinks" id="enableRssPermalinks" {if="$enable_rss_permalinks"}checked{/if}>
{'RSS direct links'|t}
</label>
<small>{'Check this to use direct URL instead of permalink in feeds'|t}</small>
<label for="hidePublicLinks">
<input type="checkbox" name="hidePublicLinks" id="hidePublicLinks" {if="$hide_public_links"}checked{/if}>
{'Hide public links'|t}
</label>
<small>{'Do not show any links if the user is not logged in'|t}</small>
<label for="updateCheck">
<input type="checkbox" name="updateCheck" id="updateCheck" {if="$enable_update_check"}checked{/if}>
{'Check for updates'|t}
</label>
<small>{'Notify me when a new release is ready'|t}</small>
<label for="retrieveDescription">
<input type="checkbox" name="retrieveDescription" id="retrieveDescription" {if="$retrieve_description"}checked{/if}>
{'Automatically retrieve description for new bookmarks'|t}
</label>
<small>{'Shaarli will try to retrieve the description from meta HTML headers'|t}</small>
<label for="enableApi">
<input type="checkbox" name="enableApi" id="enableApi" {if="$api_enabled"}checked{/if}>
{'Enable REST API'|t}
</label>
<small>{'Allow third party software to use Shaarli such as mobile application'|t}</small>
<label for="apiSecret">
{'REST API secret'|t}<br>
</label>
<input type="text" name="apiSecret" id="apiSecret" size="50" value="{$api_secret}">
<label for="enableThumbnails">
{'Enable thumbnails'|t}<br>
{if="! $gd_enabled"}
{'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}
{elseif="$thumbnails_enabled"}
<a href="{$base_path}/admin/thumbnails">{'Synchronize thumbnails'|t}</a>
{/if}
</label>
<select name="enableThumbnails" id="enableThumbnails">
<option value="all" {if="$thumbnails_mode=='all'"}selected{/if}>
{'All'|t}
</option>
<option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
{'Only common media hosts'|t}
</option>
<option value="none" {if="$thumbnails_mode=='none'"}selected{/if}>
{'None'|t}
</option>
</select>
<input type="submit" value="{'Save'|t}" name="save">
</div>
</div>
</div>
<input type="hidden" name="token" value="{$token}">
</form>
{include="page.footer"}
</body>
</html>
<input type="hidden" name="token" value="{$token}">
</form>
</section>
{include="page.footer"}
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -1,567 +1,379 @@
:root {
color-scheme: dark light;
--primary: #cc2027;
--primary-darken: #8E161B;
--primary-lighten: #D64C52;
--primary-text-contrast: #FFF;
--secondary: #20ccc5;
--secondary-darken: #168E89;
--secondary-lighten: #4CD6D0;
--secondary-text-contrast: #000;
--error: #c43933;
--error-darken: #892723;
--error-lighten: #CF605B;
--error-text-contrast: #FFF;
--info: #206ccc;
--info-darken: #164B8E;
--info-lighten: #4C89D6;
--info-text-contrast: #FFF;
--success: #7dcc20;
--success-darken: #578E16;
--success-lighten: #97D64C;
--success-text-contrast: #000;
--warning: #cc5e20;
--warning-darken: #8E4116;
--warning-lighten: #D67E4C;
--warning-text-contrast: #FFF;
--divider: light-dark(#B2AFAF, #454343);
--background-color: light-dark(#fffbfb, #171414);
--background-color-darken: light-dark(#B2AFAF, #100E0E);
--background-color-lighten: light-dark(#FFFBFB, #454343);
--background-secondary-color: #ebebeb;
--light-background-color: #fffbfb;
--dark-background-color: #171414;
--header-background-color: light-dark(#171414, #fffbfb);
--header-background-color-darken: light-dark(#100E0E, #B2AFAF);
--header-background-color-lighten: light-dark(#454343, #FFFBFB);
--header-text-color: light-dark(#fffbfb, #171414);
--header-text-color-secondary: #ffffffb3;
--header-text-color-disable: var(--divider);
--text-color: light-dark(#171414, #fffbfb);
--text-color-secondary: #ffffffb3;
--text-color-disable: light-dark(#454343, #B2AFAF);
--light-text-color: #171414;
--dark-text-color: #fffbfb;
--text-color-inverse: light-dark(#fffbfb, #171414);
--text-color-secondary-inverse: #ffffffb3;
--text-color-disable-inverse: var(--divider);
--box-shadow-light: .4rem .4rem 0px .1rem #B2AFAF;
--box-shadow-dark: .4rem .4rem 0px .1rem #454343;
--box-shadow-auto: .4rem .4rem 0px .1rem var(--divider);
--h1-color: var(--primary);
--h2-color: #c33d35;
--h3-color: #b94f44;
--h4-color: #ae5e52;
--h5-color: #a16a61;
--h6-color: #927671;
--font-size: 1.2em;
--default-space: .2em;
}
[data-theme="dark"] {
color-scheme: dark;
}
[data-theme="light"] {
color-scheme: light;
}
[data-theme="dark"] {
--background-color: #171414;
--text-color: #fffbfb;
--text-color-inverse: #171414;
}
[data-theme="light"] {
--background-color: #fffbfb;
--text-color: #171414;
--text-color-inverse: #fffbfb;
}
* {
box-sizing: border-box;
}
:root {
--main-color: var(--primary);
--dark-main-color: var(--primary-darken);
}
html {
scroll-behavior: smooth;
}
body {
background-color: var(--background-color);
color: var(--text-color);
width: 80vw;
margin: 0 auto;
min-height: 100vh;
min-height: 100dvh;
text-rendering: optimizeSpeed;
background-color: var(--background-color-auto);
}
a {
transition: .2s linear, border .2s linear;
main {
font-size: .8rem;
}
h1 {
font-size: calc(var(--font-size) * 1.6);
h1::before,
h2::before {
content: none;
}
.shaarli-menu {
background-color: var(--primary);
.pure-u-0 {
display: none !important;
}
.tag-sort a.button {
border: 2px solid var(--text-color);
border-radius: 5px;
padding: 3px 10px;
text-decoration: none;
color: var(--text-color);
font-weight: bold;
background-color: transparent;
.markdown p+p {
margin: var(--default-space) 0 0 !important;
}
.subheader-form {
padding: calc(var(--default-space)*6) 0;
width: 80vw;
border: var(--default-space) solid var(--text-color);
.markdown p {
margin: var(--default-space) 0 0 !important;
}
.subheader-form {
height: auto;
}
/* Awesomplete */
.subheader-form a.button,
.tag-sort a.button {
border-color: var(--text-color);
color: var(--text-color);
}
.subheader-form a.button:hover,
.tag-sort a.button:hover {
border-color: var(--text-color-inverse);
color: var(--text-color-inverse);
}
.linklist-pages a,
.daily-entry .daily-entry-title a {
color: var(--primary);
}
.linklist-pages a:hover,
.daily-entry .daily-entry-title a {
color: var(--primary-darken);
}
.linkcount {
color: var(--text-color);
}
#link-count-content {
background-color: var(--background-color-lighten);
}
.linklist-filters {
padding-left: .3em;
margin: unset;
color: var(--primary);
font-size: unset;
}
.linklist-filters a:hover {
color: var(--text-color);
background: var(--primary);
}
.linksperpage {
color: var(--text-color)
}
.linksperpage a {
width: auto;
}
.linksperpage a:hover {
color: var(--text-color);
background: var(--primary);
}
.linksperpage input[type="text"] {
margin: 0;
padding: .348em;
height: auto;
font-size: 1em;
width: 4em;
color: var(--secondary-text-contrast);
}
.linklist-item.private::before {
background: var(--warning);
}
.linklist-item-title {
background: var(--header-background-color);
}
.linklist-item-description {
color: var(--text-color-inverse);
}
.linklist-item-description a:hover,
.daily-entry-title a:hover,
.page-form a:hover {
color: var(--primary-darken);
}
.linklist-item-title .linklist-link:hover {
color: var(--primary-darken);
}
.edit-link {
color: var(--secondary-darken);
}
.edit-link:hover {
color: var(--secondary);
}
.linklist-item-infos {
padding: 8px 8px 5px 8px;
grid-area: footer;
background: var(--background-secondary-color);
}
.linklist-item-title .label-private {
border: solid 1px var(--warning);
color: var(--warning-darken);
}
.linklist-item-infos .label a {
border-radius: .3rem;
background-color: var(--header-background-color-darken);
border: 1px solid var(--header-background-color-darken);
padding: .3em .6em;
}
.linklist-item-infos .label a:hover {
color: var(--primary);
background-color: var(--header-background-color-lighten);
border: 1px solid var(--header-background-color-darken);
}
.linklist-item-infos .linklist-item-tags {
margin-bottom: .6em;
}
.footer-container::before {
display: none;
margin: 0;
background: inherit;
}
.footer-container {
margin: 0;
color: var(--text-color);
margin: calc(var(--default-space) *4) 0 0 0;
}
.footer-container a {
color: var(--primary);
}
.footer-container a:hover {
color: var(--primary-darken);
}
.linklist-item-title {
grid-area: header;
}
.linklist-item-thumbnail {
grid-area: thumb;
}
.linklist-item-description {
grid-area: main;
}
.grid-container,
.linklist-item {
display: grid;
grid-template-columns: auto 1fr;
grid-template-areas:
'thumb header header'
'thumb main main'
'footer footer footer';
gap: 10px;
width: 80vw;
padding: 10px;
}
.page-form select,
input[type="text"],
input[type="checkbox"] {
color: var(--text-color);
background-color: var(--primary-lighten) !important;
}
.page-form code,
.pure-alert code,
.markdown :not(pre) code {
color: var(--text-color);
background-color: var(--background-color-lighten);
}
.cloudtag-container a {
color: var(--primary);
}
.cloudtag-container a:hover {
color: var(--primary-darken);
}
button {
color: var(--text-color);
background-color: var(--primary);
border: 0;
border-radius: 2px;
background-color: var(--main-color);
padding: 5.5px 7.2px;
}
button:hover {
color: var(--text-color-inverse);
}
.page-form textarea,
.page-form input[type="password"],
.page-form input[type="text"] {
border: medium none currentColor;
border-radius: 2px;
box-shadow: 0 1px 0 rgba(255, 255, 255, .078), 0 1px 1px rgba(0, 0, 0, .298) inset;
padding: 0 5px;
height: 30px;
}
.searchform-block input[type="text"] {
border: medium none currentColor;
border-radius: 2px;
box-shadow: 0 1px 0 rgba(255, 255, 255, .078), 0 1px 1px rgba(0, 0, 0, .298) inset;
padding: 0 5px;
height: 30px;
}
.picwall-container {
display: flex;
flex-wrap: wrap;
gap: .1rem;
justify-content: center;
}
.picwall-pictureframe:hover span.info {
background-color: rgba(0, 0, 0, .6);
color: var(--text-color);
.awesomplete {
width: 100%;
display: inline-block;
position: relative;
}
.awesomplete input {
height: 100%;
padding: .1em;
display: block;
}
.awesomplete>ul {
color: var(--text-color-inverse);
background: var(--primary-lighten);
}
color: var(--text-color-dark);
background: var(--neutral);
.awesomplete mark {
background-color: var(--success);
font-weight: bold;
position: absolute;
left: 0;
z-index: 1;
min-width: 100%;
box-sizing: border-box;
list-style: none;
padding: var(--default-space);
border-radius: .3em;
margin: .2em 0 0;
border: 1px solid rgba(0, 0, 0, .3);
box-shadow: .05em .2em .6em rgba(0, 0, 0, .2);
text-shadow: none;
}
.awesomplete>ul>li[aria-selected="true"],
.awesomplete>ul>li:hover {
background: var(--primary-darken);
background: var(--primary);
color: var(--primary-text-contrast);
}
.tag-sort {
margin-top: 1em;
.awesomplete [hidden] {
display: none;
}
.page-form {
margin: 0;
.awesomplete .visually-hidden {
position: absolute;
clip: rect(0, 0, 0, 0);
}
.container {
margin-top: 0;
.awesomplete>ul:empty {
display: none;
}
.header-search,
.search-linklist {
padding: 0 0 10px 0;
}
.pinned-link {
color: var(--error) !important;
}
.head-logo {
vertical-align: middle;
display: inline;
}
.pure-menu-link {
display: inline-block;
}
header {
background-color: transparent;
}
header h1 img {
display: inline;
}
header h1 {
color: var(--primary);
}
header svg {
fill: var(--primary-lighten);
vertical-align: middle;
}
header a {
transition: 0.4s;
}
header h1 a {
text-decoration: none;
color: var(--primary);
text-decoration: underline transparent;
}
header a:hover {
color: var(--primary-lighten);
text-decoration: underline var(--primary);
text-decoration-thickness: var(--default-space);
}
nav {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
font-family: initial;
}
nav h1,
nav ul {
margin: 0;
}
nav h1 img {
vertical-align: middle;
}
nav ul {
display: flex;
gap: calc(var(--default-space) * 2);
flex-wrap: wrap;
padding: 0;
}
margin: 0 auto var(--default-space);
border: 0;
nav li {
margin: var(--default-space);
list-style: none;
font-size: calc(var(--font-size) * 1.2);
}
nav li a {
color: var(--primary-lighten);
text-decoration: underline transparent;
}
nav li a:hover,
nav .active {
text-decoration: underline var(--primary-darken);
text-decoration-thickness: var(--default-space);
}
nav .fa {
padding-right: var(--default-space);
}
.searchform-block input[type="text"]::placeholder,
.page-form input[type="text"]::placeholder {
color: var(--text-color);
}
.searchform-block input[type="text"],
.page-form input[type="text"] {
color: var(--secondary-text-contrast);
}
.paging,
.linklist-item,
.page-visitor,
#pageError,
.login-form-container,
#addlink-form,
.page-form {
background-color: var(--light-background-color);
border: 1px solid var(--background-color-darken);
border-radius: calc(var(--default-space) * 1.2);
box-shadow: var(--box-shadow-light);
.search-button {
margin: 0;
}
}
.paging {
color: var(--primary-lighten);
margin: 0 0 calc(var(--default-space) *4) 0;
div:first-child {
text-align: left;
a:hover {
text-decoration: underline transparent;
}
svg {
fill: var(--primary-lighten);
}
svg:hover {
fill: var(--primary);
}
.filter-on svg{
background-color: var(--neutral-medium);
}
}
div:nth-child(2) {
text-align: center;
}
div:nth-child(3) {
justify-content: end;
form {
width: auto;
margin: 0;
padding: 0;
border: none;
input {
width: 2rem;
}
}
}
}
section .pure-g,
.pluginform-container {
margin: 0 0 calc(var(--default-space) *4) 0;
.label-sticky {
color: var(--info);
border-color: var(--info);
}
.linklist-item-infos-dateblock a {
color: var(--primary);
}
.linklist-item-infos-dateblock a:hover {
text-decoration: underline var(--primary-darken);
color: var(--primary-darken);
.label-private {
color: var(--error);
border-color: var(--error);
}
.pinned-link,
.pinned-link svg,
.linklist-item-title .label-sticky {
color: var(--info-darken) !important;
color: var(--info-darken);
fill: var(--info-darken);
}
.linklist-item-title .label-sticky {
border: solid 1px var(--info-darken);
}
article.linklist-item {
gap: 0;
display: grid;
grid-template-columns: auto 1fr 3fr;
grid-template-rows: auto auto auto;
grid-auto-flow: row;
grid-template-areas:
"Thumbnail Header Header"
"Thumbnail Content Content"
"Footer Footer Footer";
figure {
grid-area: Thumbnail;
margin: 0;
padding: 0;
}
header {
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: 1fr;
gap: 0px;
grid-template-areas: ". .";
grid-area: Header;
margin: 0;
img {
display: inline-block;
}
h3::before {
content: '';
}
h3 {
text-wrap: auto;
margin-left: .2rem;
}
div {
margin: calc(var(--default-space)*2) var(--default-space);
span:nth-child(1) {
vertical-align: sub;
}
}
a.icon:hover {
text-decoration: underline transparent;
}
.icon svg {
fill: var(--primary-lighten);
}
.icon svg:hover {
fill: var(--primary);
}
}
.content {
grid-area: Content;
}
footer {
font-size: .7rem;
grid-area: Footer;
width: 100%;
text-align: left;
background-color: var(--neutral-light);
padding: calc(var(--default-space) *2) var(--default-space) 0 var(--default-space);
border-radius: 0 0 var(--border-radius) var(--border-radius);
span:last-child {
flex-grow: 1;
text-align: right;
}
div:first-child{
margin: 0 0 var(--default-space) 0;
}
}
}
article.private {
box-shadow: .4rem .4rem 0px .1rem var(--error);
}
.addlink-form {
margin-right: auto;
margin-left: auto;
color: var(--text-color-light);
text-align: center;
}
.vertical-menu {
margin: 0 auto;
text-align: center;
width: 30%;
a {
background-color: var(--neutral-light);
border: 1px solid var(--neutral);
padding: var(--default-space);
width: 100%;
display: inline-block;
}
}
.flex-center {
justify-content: center;
}
.cloudtag-container {
text-align: center;
text-decoration: inherit;
color: inherit;
line-height: 1.5rem;
a {
font-weight: 700;
padding: 0 .1rem;
}
.count {
color: var(--text-color-light);
cursor: copy;
}
}
.gallery {
figcaption {
display: none;
}
figure:hover figcaption {
display: block;
position: absolute;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, .7);
width: 100%;
height: 100%;
text-align: left;
color: var(--text-color-dark);
font-size: .7rem;
font-weight: bold;
text-overflow: unset;
white-space: unset;
padding: .2em;
}
}
.icon {
fill: var(--button-background-color-hover);
background-color: transparent;
}
a[role="button"] svg{
fill: var(--button-color);
}
.linkcount {
color: var(--text-color-auto);
}
.search-button svg {
stroke: var(--primary-text-contrast);
fill: var(--primary-text-contrast)
}
#permalinkQrcode {
height: 280px;
font-size: 1rem;
margin: 0 auto;
img {
margin: 0;
}
}
#js-translations {
visibility: hidden;
display: none;
}
/*
Need refactoring
*/
#actions,
#bulk-tag-action-delete,
#bulk-tag-action-add {
color: var(--secondary-text-contrast);
background-color: var(--background-color-light);
border-radius: var(--border-radius);
border: var(--default-space) solid var(--secondary);
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 0;
width: 70vw;
transition: .4s;
}
.subheader-form {
padding: calc(var(--default-space)*6);
width: auto;
height: auto;
visibility: hidden;
}
#actions.subheader-form.open,
#bulk-tag-action-delete.open,
#bulk-tag-action-add.open {
z-index: 10;
visibility: visible;
transition: .4s;
}
.tag-sort a {
background: unset;
display: inline-block;
padding: var(--default-space);
color: var(--primary);
font-weight: 700;
}

1
tpl/myShaarli/css/myShaarli.min.css vendored Normal file
View file

@ -0,0 +1 @@
body{background-color:var(--background-color-auto);}main{font-size:.8rem;}h1::before,h2::before{content:none;}.pure-u-0{display:none!important;}.markdown p+p{margin:var(--default-space) 0 0!important;}.markdown p{margin:var(--default-space) 0 0!important;}.awesomplete{width:100%;display:inline-block;position:relative;}.awesomplete input{height:100%;display:block;}.awesomplete>ul{color:var(--text-color-dark);background:var(--neutral);position:absolute;left:0;z-index:1;min-width:100%;box-sizing:border-box;list-style:none;padding:var(--default-space);border-radius:.3em;margin:.2em 0 0;border:1px solid rgba(0,0,0,.3);box-shadow:.05em .2em .6em rgba(0,0,0,.2);text-shadow:none;}.awesomplete>ul>li[aria-selected="true"],.awesomplete>ul>li:hover{background:var(--primary);color:var(--primary-text-contrast);}.awesomplete [hidden]{display:none;}.awesomplete .visually-hidden{position:absolute;clip:rect(0,0,0,0);}.awesomplete>ul:empty{display:none;}.search-linklist{padding:0;margin:0 auto var(--default-space);border:0;.search-button{margin:0}}.paging{margin:0 0 calc(var(--default-space) *4) 0;div:first-child{text-align:left;a:hover{text-decoration:underline transparent}svg{fill:var(--primary-lighten)}svg:hover{fill:var(--primary)}.filter-on svg{background-color:var(--neutral-medium)}}div:nth-child(2){text-align:center}div:nth-child(3){justify-content:end;form{width:auto;margin:0;padding:0;border:none;input{width:2rem}}}}.label-sticky{color:var(--info);border-color:var(--info);}.label-private{color:var(--error);border-color:var(--error);}.pinned-link,.pinned-link svg,.linklist-item-title .label-sticky{color:var(--info-darken);fill:var(--info-darken);}.linklist-item-title .label-sticky{border:solid 1px var(--info-darken);}article.linklist-item{gap:0;display:grid;grid-template-columns:auto 1fr 3fr;grid-template-rows:auto auto auto;grid-auto-flow:row;grid-template-areas:"Thumbnail Header Header" "Thumbnail Content Content" "Footer Footer Footer";figure{grid-area:Thumbnail;margin:0;padding:0}header{display:grid;grid-template-columns:1fr auto;grid-template-rows:1fr;gap:0;grid-template-areas:". .";grid-area:Header;margin:0;img{display:inline-block}h3::before{content:''}h3{text-wrap:auto;margin-left:.2rem}div{margin:calc(var(--default-space)*2) var(--default-space);span:nth-child(1){vertical-align:sub}}a.icon:hover{text-decoration:underline transparent}.icon svg{fill:var(--primary-lighten)}.icon svg:hover{fill:var(--primary)}}.content{grid-area:Content}footer{font-size:.7rem;grid-area:Footer;width:100%;text-align:left;background-color:var(--neutral-light);padding:calc(var(--default-space) *2) var(--default-space) 0 var(--default-space);border-radius:0 0 var(--border-radius) var(--border-radius);span:last-child{flex-grow:1;text-align:right}div:first-child{margin:0 0 var(--default-space) 0}}}article.private{box-shadow:.4rem .4rem 0 .1rem var(--error);}.addlink-form{margin-right:auto;margin-left:auto;color:var(--text-color-light);text-align:center;}.vertical-menu{margin:0 auto;text-align:center;width:30%;a{background-color:var(--neutral-light);border:1px solid var(--neutral);padding:var(--default-space);width:100%;display:inline-block}}.flex-center{justify-content:center;}.cloudtag-container{text-align:center;text-decoration:inherit;color:inherit;line-height:1.5rem;a{font-weight:700;padding:0 .1rem}.count{color:var(--text-color-light);cursor:copy}}.gallery{figcaption{display:none}figure:hover figcaption{display:block;position:absolute;top:0;left:0;background-color:rgba(0,0,0,.7);width:100%;height:100%;text-align:left;color:var(--text-color-dark);font-size:.7rem;font-weight:bold;text-overflow:unset;white-space:unset;padding:.2em}}.icon{fill:var(--button-background-color-hover);background-color:transparent;}a[role="button"] svg{fill:var(--button-color);}.linkcount{color:var(--text-color-auto);}.search-button svg{stroke:var(--primary-text-contrast);fill:var(--primary-text-contrast)}#permalinkQrcode{height:280px;font-size:1rem;margin:0 auto;img{margin:0}}#js-translations{visibility:hidden;display:none;}#actions,#bulk-tag-action-delete,#bulk-tag-action-add{color:var(--secondary-text-contrast);background-color:var(--background-color-light);border-radius:var(--border-radius);border:var(--default-space) solid var(--secondary);position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);z-index:0;width:70vw;transition:.4s;}.subheader-form{padding:calc(var(--default-space)*6);width:auto;height:auto;visibility:hidden;}#actions.subheader-form.open,#bulk-tag-action-delete.open,#bulk-tag-action-add.open{z-index:10;visibility:visible;transition:.4s;}.tag-sort a{background:unset;display:inline-block;padding:var(--default-space);color:var(--primary);font-weight:700;}

File diff suppressed because one or more lines are too long

View file

@ -1,33 +1,35 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
<div class="dark-layer">
<div class="screen-center">
<div><span class="progressbar-current"></span> / <span class="progressbar-max"></span></div>
<div class="progressbar">
<div></div>
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
<div class="dark-layer">
<div class="screen-center">
<div><span class="progressbar-current"></span> / <span class="progressbar-max"></span></div>
<div class="progressbar">
<div></div>
</div>
</div>
</div>
</div>
</div>
{include="page.header"}
{include="page.header"}
<div class="section text-center">
<input type="submit" name="save_edit_batch" value="{'Save all'|t}" class="button">
</div>
<div class="center">
<input type="submit" name="save_edit_batch" class="pure-button-shaarli" value="{'Save all'|t}">
</div>
{loop="$links"}
{$batchId=$key}
{include="editlink"}
{/loop}
{loop="$links"}
{$batchId=$key}
{include="editlink"}
{/loop}
<div class="section text-center">
<input type="submit" name="save_edit_batch" value="{'Save all'|t}">
</div>
<div class="center">
<input type="submit" name="save_edit_batch" class="pure-button-shaarli" value="{'Save all'|t}">
</div>
{include="page.footer"}
{if="$async_metadata"}<script src="{$asset_path}/js/metadata.min.js?v={$version_hash}#"></script>{/if}
<script src="{$asset_path}/js/shaare_batch.min.js?v={$version_hash}#"></script>
{include="page.footer"}
{if="$async_metadata"}
<script src="{$asset_path}/js/metadata.min.js?v={$version_hash}#"></script>{/if}
<script src="{$asset_path}/js/shaare_batch.min.js?v={$version_hash}#"></script>

View file

@ -1,122 +1,116 @@
{$batchId=isset($batchId) ? $batchId : ''}
{if="empty($batch_mode)"}
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
{else}
{ignore}Lil hack: when included in a loop in batch mode, `$value` is assigned by RainTPL with template vars.{/ignore}
{function="extract($value) ? '' : ''"}
{/if}
<div id="editlinkform{$batchId}" class="edit-link-container" class="pure-g">
<div class="pure-u-lg-1-5 pure-u-1-24"></div>
<form method="post"
name="linkform"
action="{$base_path}/admin/shaare"
class="page-form pure-u-lg-3-5 pure-u-22-24 page-form page-form-light"
>
{$asyncLoadClass=$link_is_new && $async_metadata && empty($link.title) ? 'loading-input' : ''}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<h2 class="window-title">
{if="!$link_is_new"}{'Edit Shaare'|t}{else}{'New Shaare'|t}{/if}
</h2>
{if="isset($link.id)"}
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
{else}
{ignore}Lil hack: when included in a loop in batch mode, `$value` is assigned by RainTPL with template vars.{/ignore}
{function="extract($value) ? '' : ''"}
{/if}
<section id="editlinkform{$batchId}" class="edit-link-container">
<form method="post" name="linkform" action="{$base_path}/admin/shaare">
{$asyncLoadClass=$link_is_new && $async_metadata && empty($link.title) ? 'loading-input' : ''}
<h2>
{if="!$link_is_new"}{'Edit Shaare'|t}{else}{'New Shaare'|t}{/if}
</h2>
{if="isset($link.id)"}
<input type="hidden" name="lf_id" value="{$link.id}">
{/if}
{if="!$link_is_new"}<div class="created-date">{'Created:'|t} {$link.created|format_date}</div>{/if}
<div>
{/if}
{if="!$link_is_new"}<div class="created-date">{'Created:'|t} {$link.created|format_date}</div>{/if}
<label for="lf_url{$batchId}">{'URL'|t}</label>
</div>
<div>
<input type="text" name="lf_url" id="lf_url{$batchId}" value="{$link.url}" class="lf_input">
</div>
<div>
<label for="lf_title{$batchId}">{'Title'|t}</label>
</div>
<div class="{$asyncLoadClass}">
<input type="text" name="lf_title" id="lf_title{$batchId}" value="{$link.title}"
class="lf_input {if="!$async_metadata"}autofocus{/if}"
>
<div class="icon-container">
<i class="loader"></i>
<label for="lf_title{$batchId}">{'Title'|t}</label>
<div class="{$asyncLoadClass}">
<input type="text" name="lf_title" id="lf_title{$batchId}" value="{$link.title}" class="lf_input {if="!$async_metadata"}autofocus{/if}">
<div class="icon-container">
<i class="loader"></i>
</div>
</div>
</div>
<div>
<label for="lf_description{$batchId}">{'Description'|t}</label>
</div>
<div class="{if="$retrieve_description"}{$asyncLoadClass}{/if}">
<textarea name="lf_description" id="lf_description{$batchId}" class="autofocus">{$link.description}</textarea>
<div class="icon-container">
<i class="loader"></i>
<div class="{if=" $retrieve_description"}{$asyncLoadClass}{/if}">
<textarea name="lf_description" id="lf_description{$batchId}" class="autofocus">{$link.description}</textarea>
<div class="icon-container">
<i class="loader"></i>
</div>
</div>
</div>
<div>
<label for="lf_tags{$batchId}">{'Tags'|t}</label>
</div>
<div class="{if="$retrieve_description"}{$asyncLoadClass}{/if}">
<input type="text" name="lf_tags" id="lf_tags{$batchId}" value="{$link.tags}" class="lf_input autofocus"
data-list="{loop="$tags"}{$key}, {/loop}" data-multiple data-autofirst autocomplete="off" >
<div class="icon-container">
<i class="loader"></i>
<div class="{if=" $retrieve_description"}{$asyncLoadClass}{/if}">
<input type="text" name="lf_tags" id="lf_tags{$batchId}" value="{$link.tags}" class="lf_input autofocus"
data-list="{loop=" $tags"}{$key}, {/loop}" data-multiple data-autofirst autocomplete="off">
<div class="icon-container">
<i class="loader"></i>
</div>
</div>
</div>
<div>
<input type="checkbox" name="lf_private" id="lf_private{$batchId}"
{if="$link.private === true"}
checked="checked"
{/if}>
&nbsp;<label for="lf_private{$batchId}">{'Private'|t}</label>
</div>
<label for="lf_private{$batchId}">
<input type="checkbox" name="lf_private" id="lf_private{$batchId}" {if="$link.private === true"}checked="checked"{/if}>
{'Private'|t}
</label>
{if="$formatter==='markdown'"}
{if="$formatter==='markdown'"}
<div class="md_help">
{'Description will be rendered with'|t}
<a href="http://daringfireball.net/projects/markdown/syntax" title="{'Markdown syntax documentation'|t}">
<a href="http://daringfireball.net/projects/markdown/syntax" title="{'Markdown syntax documentation'|t}" target="_blank">
{'Markdown syntax'|t}
</a>.
</div>
{/if}
{/if}
<div id="editlink-plugins">
{loop="$edit_link_plugin"}
{if="$formatter==='markdownExtra'"}
<div class="md_help">
{'Description will be rendered with'|t}
<a href="https://michelf.ca/projects/php-markdown/extra" title="{'Markdown syntax documentation'|t}" target="_blank">
{'markdownExtra syntax'|t}
</a>.
</div>
{/if}
<div id="editlink-plugins">
{loop="$edit_link_plugin"}
{$value}
{/loop}
</div>
{/loop}
</div>
<div class="submit-buttons center">
{if="!empty($batch_mode)"}
<a href="#" class="button button-grey" name="cancel-batch-link"
title="{'Remove this bookmark from batch creation/modification.'}"
>
<p class="flex">
{if="!empty($batch_mode)"}
<a href="#" role="button" name="cancel-batch-link"
title="{'Remove this bookmark from batch creation/modification.'}">
{'Cancel'|t}
</a>
{/if}
<input type="submit" name="save_edit" class="" id="button-save-edit"
value="{if="$link_is_new"}{'Save'|t}{else}{'Apply Changes'|t}{/if}">
{if="!$link_is_new"}
<a href="{$base_path}/admin/shaare/delete?id={$link.id}&amp;token={$token}"
title="" name="delete_link" class="button button-red confirm-delete">
{'Delete'|t}
</a>
{/if}
</div>
{/if}
<input type="submit" name="save_edit" class="success" id="button-save-edit" value="{if=" $link_is_new"}{'Save'|t}{else}{'Apply Changes'|t}{/if}">
{if="!$link_is_new"}
<a href="{$base_path}/admin/shaare/delete?id={$link.id}&amp;token={$token}" title="" name="delete_link"
class="button confirm-delete error" role="button">
{'Delete'|t}
</a>
{/if}
</p>
<input type="hidden" name="token" value="{$token}">
<input type="hidden" name="source" value="{$source}">
{if="$http_referer"}
<input type="hidden" name="token" value="{$token}">
<input type="hidden" name="source" value="{$source}">
{if="$http_referer"}
<input type="hidden" name="returnurl" value="{$http_referer}">
{/if}
</form>
</div>
{/if}
</form>
</section>
{if="empty($batch_mode)"}
{include="page.footer"}
{if="$link_is_new && $async_metadata"}<script src="{$asset_path}/js/metadata.min.js?v={$version_hash}#"></script>{/if}
</body>
</html>
{/if}
{if="empty($batch_mode)"}
{include="page.footer"}
{if="$link_is_new && $async_metadata"}
<script src="{$asset_path}/js/metadata.min.js?v={$version_hash}#"></script>{/if}
</body>
</html>
{/if}

View file

@ -1,67 +1,39 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<form method="POST" action="{$base_path}/admin/export" name="exportform" id="exportform">
<div class="pure-g">
<div class="pure-u-lg-1-4 pure-u-1-24"></div>
<div class="pure-u-lg-1-2 pure-u-22-24 page-form page-form-complete">
<div>
<h2 class="window-title">{"Export Database"|t}</h2>
</div>
<input type="hidden" name="token" value="{$token}">
<head>
{include="includes"}
</head>
<div class="pure-g">
<div class="pure-u-lg-1-2 pure-u-1">
<div class="form-label">
<label><span class="label-name">{'Selection'|t}</span></label>
</div>
</div>
<div class="pure-u-lg-1-2 pure-u-1">
<div class="radio-buttons">
<div>
<input type="radio" name="selection" value="all" checked="checked">
{'All'|t}
</div>
<div>
<input type="radio" name="selection" value="private">
{'Private'|t}
</div>
<div>
<input type="radio" name="selection" value="public">
{'Public'|t}
</div>
</div>
</div>
</div>
<div class="pure-g">
<div class="pure-u-lg-1-2 pure-u-7-8">
<div class="form-label">
<label for="prepend_note_url">
<span class="label-name">{'Prepend note permalinks with this Shaarli instance\'s URL'|t}</span><br>
<span class="label-desc">{'Useful to import bookmarks in a web browser'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-1-2 pure-u-1-8">
<div class="form-input">
<input type="checkbox" name="prepend_note_url" id="prepend_note_url">
</div>
</div>
</div>
<div class="center">
<body>
{include="page.header"}
<section>
<h2 class="window-title">{"Export Database"|t}</h2>
<form method="POST" action="{$base_path}/admin/export" name="exportform" id="exportform">
<fieldset>
<legend>{'Selection'|t}</legend>
<label>
<input type="radio" name="selection" value="all" checked="checked">
{'All'|t}
</label>
<label>
<input type="radio" name="selection" value="private">
{'Private'|t}
</label>
<label>
<input type="radio" name="selection" value="public">
{'Public'|t}
</label>
</fieldset>
<label for="prepend_note_url">
<input type="checkbox" name="prepend_note_url" id="prepend_note_url">
{'Prepend note permalinks with this Shaarli instance\'s URL'|t} <small>({'Useful to import bookmarks in a web browser'|t})</small>
</label>
<input type="hidden" name="token" value="{$token}">
<input type="submit" value="{'Export'|t}">
</div>
</div>
</div>
</form>
</form>
</section>
{include="page.footer"}
</body>
{include="page.footer"}
</body>
</html>
</html>

Binary file not shown.

Binary file not shown.

Before

(image error) Size: 18 KiB

After

(image error) Size: 19 KiB

Before After
Before After

Binary file not shown.

Before

Width: 256px  |  Height: 256px  |  Size: 75 KiB

After

Width: 128px  |  Height: 128px  |  Size: 198 KiB

Before After
Before After

Binary file not shown.

Before

(image error) Size: 41 KiB

File diff suppressed because it is too large Load diff

Before

(image error) Size: 470 KiB

Binary file not shown.

Before

(image error) Size: 530 B

Binary file not shown.

Before

(image error) Size: 8.1 KiB

View file

@ -1,86 +1,55 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<section>
<form method="POST" action="{$base_path}/admin/import" enctype="multipart/form-data" name="uploadform"
id="uploadform">
<form method="POST" action="{$base_path}/admin/import" enctype="multipart/form-data" name="uploadform" id="uploadform">
<div class="pure-g">
<div class="pure-u-lg-1-4 pure-u-1-24"></div>
<div class="pure-u-lg-1-2 pure-u-22-24 page-form page-form-complete">
<div>
<h2 class="window-title">{"Import Database"|t}</h2>
</div>
<input type="hidden" name="token" value="{$token}">
<div class="center import-field-container" id="import-field">
<input type="hidden" name="token" value="{$token}">
<input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}">
<input type="file" name="filetoupload">
<p><br>{'Maximum size allowed:'|t} <strong>{$maxfilesizeHuman}</strong></p>
</div>
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1">
<div class="form-label">
<label><span class="label-name">{'Visibility'|t}</span></label>
</div>
</div>
<div class="pure-u-lg-2-3 pure-u-1">
<div class="radio-buttons">
<div>
<input type="radio" name="privacy" value="default" checked="checked">
{'Use values from the imported file, default to public'|t}
</div>
<div>
<input type="radio" name="privacy" value="private">
{'Import all bookmarks as private'|t}
</div>
<div>
<input type="radio" name="privacy" value="public">
{'Import all bookmarks as public'|t}
</div>
</div>
</div>
</div>
<label for="filetoupload">{"File"|t}</label>
<input type="file" name="filetoupload" id="filetoupload">
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-7-8">
<div class="form-label">
<label for="overwrite">
<span class="label-name">{'Overwrite existing bookmarks'|t}</span><br>
<span class="label-desc">{'Duplicates based on URL'|t}</span>
</label>
</div>
</div>
<div class="pure-u-lg-2-3 pure-u-1-8">
<div class="form-input">
<input type="checkbox" name="overwrite" id="overwrite">
</div>
</div>
</div>
<p>{'Maximum size allowed:'|t} <strong>{$maxfilesizeHuman}</strong></p>
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1">
<div class="form-label">
<label for="default_tags"><span class="label-name">{'Add default tags'|t}</span></label>
</div>
</div>
<div class="pure-u-lg-2-3 pure-u-1">
<div class="form-input">
<input type="text" name="default_tags" id="default_tags" aria-label="{'Tag'|t}" placeholder="{'Tag'|t}">
</div>
</div>
</div>
<fieldset>
<legend>{'Visibility'|t}</legend>
<label for="privacy-01">
<input type="radio" name="privacy" value="default" checked="checked" id="privacy-01">
{'Use values from the imported file, default to public'|t}
</label>
<label for="privacy-02">
<input type="radio" name="privacy" value="private" id="privacy-02">
{'Import all bookmarks as private'|t}
</label>
<label for="privacy-03">
<input type="radio" name="privacy" value="public" id="privacy-03">
{'Import all bookmarks as public'|t}
</label>
</fieldset>
<label for="overwrite">
<input type="checkbox" name="overwrite" id="overwrite">
{'Overwrite existing bookmarks'|t} <small>({'Duplicates based on URL'|t})</small>
</label>
<label for="default_tags"><span class="label-name">{'Add default tags'|t}</span></label>
<input type="text" name="default_tags" id="default_tags" aria-label="{'Tag'|t}" placeholder="{'Tag'|t}">
<div class="center">
<input type="submit" name="import_file" value="{'Import'|t}">
</div>
</div>
</div>
</form>
</form>
</section>
{include="page.footer"}
</body>
{include="page.footer"}
</body>
</html>
</html>

View file

@ -1,42 +1,41 @@
<title>{$pagetitle}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="referrer" content="same-origin">
<link rel="alternate" type="application/atom+xml" href="{$feedurl}feed/atom?{$searchcrits}#" title="ATOM Feed" />
<link rel="alternate" type="application/rss+xml" href="{$feedurl}feed/rss?{$searchcrits}#" title="RSS Feed" />
<link href="{$asset_path}/img/favicon_64.png#" rel="shortcut icon" type="image/png" />
<link href="{$asset_path}/img/apple-touch-icon.png#" rel="apple-touch-icon" sizes="180x180" />
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/shaarli.min.css?v={$version_hash}#" />
{if="strpos($formatter, 'markdown') !== false"}
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/markdown.min.css?v={$version_hash}#" />
{/if}
<link rel="alternate" type="application/atom+xml" href="{$feedurl}feed/atom?{$searchcrits}#" title="ATOM Feed">
<link rel="alternate" type="application/rss+xml" href="{$feedurl}feed/rss?{$searchcrits}#" title="RSS Feed">
<link href="{$asset_path}/img/favicon_128.png#" rel="shortcut icon" type="image/png">
<link href="{$asset_path}/img/apple-touch-icon.png#" rel="apple-touch-icon" sizes="180x180">
{loop="$plugins_includes.css_files"}
<link type="text/css" rel="stylesheet" href="{$root_path}/{$value}?v={$version_hash}#"/>
<link type="text/css" rel="stylesheet" href="{$root_path}/{$value}?v={$version_hash}#">
{/loop}
{if="is_file('data/user.css')"}
<link type="text/css" rel="stylesheet" href="{$root_path}/data/user.css#" />
<link type="text/css" rel="stylesheet" href="{$root_path}/data/user.css#">
{/if}
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/myShaarli.css?v={$version_hash}#" />
<link rel="search" type="application/opensearchdescription+xml" href="{$base_path}/open-search#"
title="Shaarli search - {$shaarlititle}" />
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/kt-scheme.min.css?v={$version_hash}#">
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/kt-rules.min.css?v={$version_hash}#">
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/myShaarli.css?v={$version_hash}#">
<link rel="search" type="application/opensearchdescription+xml" href="{$base_path}/open-search#" title="Shaarli search - {$shaarlititle}">
{if="$template === 'linklist' && ! empty($links) && count($links) === 1"}
{$link=reset($links)}
<meta property="og:title" content="{$link.title}" />
<meta property="og:type" content="article" />
<meta property="og:url" content="{$index_url}shaare/{$link.shorturl}" />
<meta property="og:title" content="{$link.title}">
<meta property="og:type" content="article">
<meta property="og:url" content="{$index_url}shaare/{$link.shorturl}">
{$ogDescription=isset($link.description_src) ? $link.description_src : $link.description}
<meta property="og:description" content="{function="substr(strip_tags($ogDescription), 0, 300)"}" />
<meta property="og:description" content="{function="substr(strip_tags($ogDescription), 0, 300)"}">
{if="!empty($link.thumbnail)"}
<meta property="og:image" content="{$index_url}{$link.thumbnail}" />
<meta property="og:image" content="{$index_url}{$link.thumbnail}">
{/if}
{if="!$hide_timestamps || $is_logged_in"}
<meta property="article:published_time" content="{$link.created->format(DateTime::ATOM)}" />
<meta property="article:published_time" content="{$link.created->format(DateTime::ATOM)}">
{if="!empty($link.updated)"}
<meta property="article:modified_time" content="{$link.updated->format(DateTime::ATOM)}" />
<meta property="article:modified_time" content="{$link.updated->format(DateTime::ATOM)}">
{/if}
{/if}
{loop="link.taglist"}
<meta property="article:tag" content="{$value}" />
<meta property="article:tag" content="{$value}">
{/loop}
{/if}

View file

@ -1 +0,0 @@
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=16)}({16:function(e,t,r){}});

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
!function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=9)}({9:function(t,e){function r(t){return function(t){if(Array.isArray(t))return n(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return n(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);"Object"===r&&t.constructor&&(r=t.constructor.name);if("Map"===r||"Set"===r)return Array.from(t);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return n(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function n(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r<e;r++)n[r]=t[r];return n}function o(t,e){var r=t.getAttribute("data-line");t.setAttribute("data-order",e),document.querySelector('[name="order_'.concat(r,'"]')).setAttribute("value",e)}function a(t,e){var r=parseInt(t,10)+e,n=document.querySelectorAll('[data-order="'.concat(t,'"]')),a=document.querySelectorAll('[data-order="'.concat(r,'"]'));e>0&&(n=[].slice.call(n).reverse());for(var u=0;u<n.length;u+=1){var i=a[0].parentNode;o(n[u],r),o(a[u],parseInt(t,10));var c=e<0?a[0]:a[a.length-1].nextSibling;i.insertBefore(n[u],c)}}r(document.querySelectorAll(".order")).forEach((function(t){t.addEventListener("click",(function(t){var e;t.preventDefault(),t.target.classList.contains("order-up")?0!==(e=parseInt(t.target.parentNode.parentNode.getAttribute("data-order"),10))&&a(e,-1):t.target.classList.contains("order-down")&&function(t){t!==parseInt(document.querySelector("[data-order]:last-child").getAttribute("data-order"),10)&&a(t,1)}(parseInt(t.target.parentNode.parentNode.getAttribute("data-order"),10))}))}))}});
(()=>{function t(t){return function(t){if(Array.isArray(t))return r(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return r(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=Array(r);e<r;e++)n[e]=t[e];return n}function e(t,r){var e=t.getAttribute("data-line");t.setAttribute("data-order",r),document.querySelector('[name="order_'.concat(e,'"]')).setAttribute("value",r)}function n(t,r){var n=parseInt(t,10)+r,a=document.querySelectorAll('[data-order="'.concat(t,'"]')),o=document.querySelectorAll('[data-order="'.concat(n,'"]'));r>0&&(a=[].slice.call(a).reverse());for(var i=0;i<a.length;i+=1){var c=o[0].parentNode;e(a[i],n),e(o[i],parseInt(t,10));var u=r<0?o[0]:o[o.length-1].nextSibling;c.insertBefore(a[i],u)}}t(document.querySelectorAll(".order")).forEach((function(t){t.addEventListener("click",(function(t){var r;t.preventDefault(),t.target.classList.contains("order-up")?0!==(r=parseInt(t.target.parentNode.parentNode.getAttribute("data-order"),10))&&n(r,-1):t.target.classList.contains("order-down")&&function(t){t!==parseInt(document.querySelector("[data-order]:last-child").getAttribute("data-order"),10)&&n(t,1)}(parseInt(t.target.parentNode.parentNode.getAttribute("data-order"),10))}))}))})();

View file

@ -1 +1 @@
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=5)}({5:function(e,t){function n(e){return function(e){if(Array.isArray(e))return r(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return r(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var o=function(e,t){var r=t.querySelectorAll('input[type="text"], textarea, input[type="checkbox"], input[type="hidden"]'),o=new FormData;return n(r).forEach((function(e){"checkbox"===e.getAttribute("type")?o.append(e.getAttribute("name"),e.checked):o.append(e.getAttribute("name"),e.value)})),new Promise((function(n,r){var c=new XMLHttpRequest;c.open("POST","".concat(e,"/admin/shaare")),c.onload=function(){200!==c.status?(alert("An error occurred. Return code: ".concat(c.status)),r()):(t.closest(".edit-link-container").remove(),n())},c.send(o)}))},c=function(e,t,n){null!=t&&0!==t.length||(window.location.href="".concat(e).concat(n))};!function(){var e=document.querySelector('input[name="js_base_path"]').value,t=function(){return document.querySelectorAll('form[name="linkform"]')},r=document.querySelectorAll('[name="cancel-batch-link"]');null!=r&&n(r).forEach((function(n){n.addEventListener("click",(function(n){n.preventDefault(),n.target.closest('form[name="linkform"]').remove(),c(e,t(),"/admin/add-shaare")}))}));var u=document.querySelectorAll('[name="save_edit"]');null!=u&&n(u).forEach((function(n){n.addEventListener("click",(function(n){n.preventDefault();var r=n.target.closest('form[name="linkform"]');o(e,r).then((function(){return c(e,t(),"/")}))}))}));var a=document.querySelectorAll('[name="save_edit_batch"]');null!=a&&n(a).forEach((function(r){r.addEventListener("click",(function(r){r.preventDefault();var c=n(t()),u=c.length,a=0,i=document.querySelector(".progressbar > div"),l=document.querySelector(".progressbar-current");document.querySelector(".dark-layer").style.display="block",document.querySelector(".progressbar-max").innerHTML=u,l.innerHTML=a;var f=[];c.forEach((function(t){f.push(o(e,t).then((function(){a+=1,i.style.width="".concat(100*a/u,"%"),l.innerHTML=a})))})),Promise.all(f).then((function(){window.location.href="".concat(e,"/")}))}))}));var i=document.querySelectorAll('[name="delete_link"]');null!=i&&n(i).forEach((function(n){n.addEventListener("click",(function(n){n.preventDefault();var r=n.target.closest('form[name="linkform"]');(function(e,t){return new Promise((function(n,r){var o=new XMLHttpRequest;o.open("GET","".concat(e.href,"&source=batch")),o.onload=function(){204!==o.status?(alert("An error occurred. Return code: ".concat(o.status)),r()):(t.closest(".edit-link-container").remove(),n())},o.send()}))})(n.target,r).then((function(){return c(e,t(),"/")}))}))}))}()}});
(()=>{function e(e){return function(e){if(Array.isArray(e))return t(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,n){if(e){if("string"==typeof e)return t(e,n);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?t(e,n):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function t(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var n=function(t,n){var r=n.querySelectorAll('input[type="text"], textarea, input[type="checkbox"], input[type="hidden"]'),o=new FormData;return e(r).forEach((function(e){"checkbox"===e.getAttribute("type")?o.append(e.getAttribute("name"),e.checked):o.append(e.getAttribute("name"),e.value)})),new Promise((function(e,r){var c=new XMLHttpRequest;c.open("POST","".concat(t,"/admin/shaare")),c.onload=function(){200!==c.status?(alert("An error occurred. Return code: ".concat(c.status)),r()):(n.closest(".edit-link-container").remove(),e())},c.send(o)}))},r=function(e,t,n){null!=t&&0!==t.length||(window.location.href="".concat(e).concat(n))};!function(){var t=document.querySelector('input[name="js_base_path"]').value,o=function(){return document.querySelectorAll('form[name="linkform"]')},c=document.querySelectorAll('[name="cancel-batch-link"]');null!=c&&e(c).forEach((function(e){e.addEventListener("click",(function(e){e.preventDefault(),e.target.closest('form[name="linkform"]').remove(),r(t,o(),"/admin/add-shaare")}))}));var a=document.querySelectorAll('[name="save_edit"]');null!=a&&e(a).forEach((function(e){e.addEventListener("click",(function(e){e.preventDefault();var c=e.target.closest('form[name="linkform"]');n(t,c).then((function(){return r(t,o(),"/")}))}))}));var u=document.querySelectorAll('[name="save_edit_batch"]');null!=u&&e(u).forEach((function(r){r.addEventListener("click",(function(r){r.preventDefault();var c=e(o()),a=c.length,u=0,i=document.querySelector(".progressbar > div"),l=document.querySelector(".progressbar-current");document.querySelector(".dark-layer").style.display="block",document.querySelector(".progressbar-max").innerHTML=a,l.innerHTML=u;var f=[];c.forEach((function(e){f.push(n(t,e).then((function(){u+=1,i.style.width="".concat(100*u/a,"%"),l.innerHTML=u})))})),Promise.all(f).then((function(){window.location.href="".concat(t,"/")}))}))}));var i=document.querySelectorAll('[name="delete_link"]');null!=i&&e(i).forEach((function(e){e.addEventListener("click",(function(e){e.preventDefault();var n=e.target.closest('form[name="linkform"]');(function(e,t){return new Promise((function(n,r){var o=new XMLHttpRequest;o.open("GET","".concat(e.href,"&source=batch")),o.onload=function(){204!==o.status?(alert("An error occurred. Return code: ".concat(o.status)),r()):(t.closest(".edit-link-container").remove(),n())},o.send()}))})(e.target,n).then((function(){return r(t,o(),"/")}))}))}))}()})();

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}({7:function(e,t){function n(e,t,r,o){var u=new XMLHttpRequest;u.open("PATCH","".concat(e,"/admin/shaare/").concat(t[r],"/update-thumbnail")),u.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),u.responseType="json",u.onload=function(){if(200!==u.status)alert("An error occurred. Return code: ".concat(u.status));else{var c=u.response;r+=1,o.progressBar.style.width="".concat(100*r/t.length,"%"),o.current.innerHTML=r,o.title.innerHTML=c.title,!1!==c.thumbnail&&(o.thumbnail.innerHTML='<img src="'.concat(e,"/").concat(c.thumbnail,'">')),r<t.length&&n(e,t,r,o)}},u.send()}n(document.querySelector('input[name="js_base_path"]').value,document.getElementsByName("ids")[0].value.split(","),0,{progressBar:document.querySelector(".progressbar > div"),current:document.querySelector(".progress-current"),thumbnail:document.querySelector(".thumbnail-placeholder"),title:document.querySelector(".thumbnail-link-title")})}});
(()=>{function e(t,n,r,o){var a=new XMLHttpRequest;a.open("PATCH","".concat(t,"/admin/shaare/").concat(n[r],"/update-thumbnail")),a.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),a.responseType="json",a.onload=function(){if(200!==a.status)alert("An error occurred. Return code: ".concat(a.status));else{var c=a.response;r+=1,o.progressBar.style.width="".concat(100*r/n.length,"%"),o.current.innerHTML=r,o.title.innerHTML=c.title,!1!==c.thumbnail&&(o.thumbnail.innerHTML='<img src="'.concat(t,"/").concat(c.thumbnail,'">')),r<n.length&&e(t,n,r,o)}},a.send()}e(document.querySelector('input[name="js_base_path"]').value,document.getElementsByName("ids")[0].value.split(","),0,{progressBar:document.querySelector(".progressbar > div"),current:document.querySelector(".progress-current"),thumbnail:document.querySelector(".thumbnail-placeholder"),title:document.querySelector(".thumbnail-link-title")})})();

View file

@ -1,308 +1,299 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
{include="page.header"}
<div id="actions" class="subheader-form section flex flex-center">
<a href="" id="actions-delete" class="error" role="button">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon">
<use href="{$asset_path}/sprites/default.svg#ui-trash"></use>
</svg>
{'Delete'|t}
</a>
<a href="" class="actions-change-visibility secondary" data-visibility="public" role="button">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon">
<use href="{$asset_path}/sprites/default.svg#ui-earth"></use>
</svg>
{'Set public'|t}
</a>
<a href="" class="actions-change-visibility secondary" data-visibility="private" role="button">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon">
<use href="{$asset_path}/sprites/default.svg#ui-secret"></use>
</svg>
{'Set private'|t}
</a>
<a href="" class="subheader-opener secondary" data-open-id="bulk-tag-action-add" role="button">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon">
<use href="{$asset_path}/sprites/default.svg#ui-tag"></use>
</svg>
{'Add tags'|t}
</a>
<a href="" class="subheader-opener warning" data-open-id="bulk-tag-action-delete" role="button">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon">
<use href="{$asset_path}/sprites/default.svg#ui-cancel"></use>
</svg>
{'Delete tags'|t}
</a>
</div>
<div class="linkcount pure-u-0 pure-u-lg-visible">
{if="!empty($linkcount)"}
<span class="strong">{$linkcount}</span> {function="t('shaare', 'shaares', $linkcount)"}
{if="$privateLinkcount>0"}
<br><span class="strong">{$privateLinkcount}</span> {function="t('private link', 'private links', $privateLinkcount)"}
{/if}
{/if}
</div>
{$addDelete=['add', 'delete']}
{loop="$addDelete"}
<div id="bulk-tag-action-{$value}" class="subheader-form section flex flex-center">
<form action="{$base_path}/admin/shaare/update-tags" method="post">
<input type="text" name="tag" class="autofocus"
aria-label="{$value === 'add' ? t('Tag to add') : t('Tag to delete')}"
placeholder="{$value === 'add' ? t('Tag to add') : t('Tag to delete')}" autocomplete="off" data-multiple
data-autofirst data-minChars="1" data-list="{loop="$tags"}{$key}, {/loop}">
<input type="hidden" name="action" value="{$value}">
<input type="hidden" name="id" value="">
<input type="hidden" name="token" value="{$token}">
<a href="" class="button action error" role="button">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon">
<use href="{$asset_path}/sprites/default.svg#ui-tag"></use>
</svg>
{$value === 'add' ? t('Add tag') : t('Delete tag')}
</a>&nbsp;
<button class="subheader-opener warning" data-open-id="actions">{'Cancel'|t}</button>
</form>
</div>
{/loop}
<input type="hidden" name="token" value="{$token}">
<div id="search-linklist" class="searchform-block search-linklist">
<div class="linkcount text-end">
{if="!empty($linkcount)"}
{$linkcount} {function="t('shaare', 'shaares', $linkcount)"}
{if="$privateLinkcount>0"}{$privateLinkcount} {function="t('private link', 'private links', $privateLinkcount)"}
{/if}
{/if}
</div>
<form method="GET" class="pure-form searchform" name="searchform">
<input type="text" name="searchterm" class="searchterm" aria-label="{'Search text'|t}" placeholder="{'Search text'|t}"
{if="!empty($search_term)"}
value="{$search_term}"
{/if}
>
<input type="text" name="searchtags" class="searchtags" aria-label="{'Filter by tag'|t}" placeholder="{'Filter by tag'|t}"
{if="!empty($search_tags)"}
value="{$search_tags}"
{/if}
autocomplete="off" data-multiple data-autofirst data-minChars="1"
data-list="{loop="$tags"}{$key}, {/loop}"
>
<button type="submit" class="search-button" aria-label="{'Search'|t}"><i class="fa fa-search" aria-hidden="true"></i></button>
<input type="hidden" name="token" value="{$token}">
<form method="GET" name="searchform" class="grid search-linklist">
<input type="search" name="searchterm" aria-label="{'Search text'|t}" placeholder="{'Search text'|t}"
{if="!empty($search_term)"} value="{$search_term}"{/if}>
<input type="search" name="searchtags" aria-label="{'Filter by tag'|t}" placeholder="{'Filter by tag'|t}"
{if="!empty($search_tags)"} value="{$search_tags}"{/if} autocomplete="off" data-multiple data-autofirst
data-minChars="1" data-list="{loop="$tags "}{$key}, {/loop}">
<button type="submit" class="search-button" aria-label="{'Search'|t}"><svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-search"></use>
</svg></button>
</form>
</div>
{loop="$plugins_header.fields_toolbar"}
<form
{loop="$value.attr"}
{$key}="{$value}"
{/loop}>
{loop="$plugins_header.fields_toolbar"}
<form {loop="$value.attr"} {$key}="{$value}" {/loop}>
<div class="toolbar-plugin pure-u-lg-1">
{loop="$value.inputs"}
<input
{loop="$value"}
{$key}="{$value}"
{/loop}>
<input {loop="$value"} {$key}="{$value}" {/loop}>
{/loop}
</div>
</form>
{/loop}
{/loop}
{include="linklist.paging"}
{include="linklist.paging"}
<div id="linklist">
<div id="link-count-block" class="pure-g link-count-block">
<div id="link-count-content" >
<div class="linkcount pure-u-lg-0 center">
{if="!empty($linkcount)"}
<span class="strong">{$linkcount}</span> {function="t('shaare', 'shaares', $linkcount)"}
{if="$privateLinkcount>0"}
&middot; <span class="strong">{$privateLinkcount}</span> {function="t('private link', 'private links', $privateLinkcount)"}
{/if}
{/if}
</div>
<div id="plugin_zone_start_linklist" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
</div>
</div>
{if="count($links)==0"}
<div id="search-result-block" class="pure-g pure-alert pure-alert-error search-result">
<div class="pure-u-2-24"></div>
<div id="search-result-content" class="pure-u-20-24">
<div id="searchcriteria">{'Nothing found.'|t}</div>
</div>
</div>
{elseif="!empty($search_term) or $search_tags !== '' or !empty($visibility) or $untaggedonly"}
<div id="search-result-block" class="pure-g pure-alert pure-alert-success search-result">
<div class="pure-u-2-24"></div>
<div id="search-result-content" class="pure-u-20-24 search-result-main">
{function="sprintf(t('%s result', '%s results', $result_count), $result_count)"}
{if="!empty($search_term)"}
{'for'|t} <em><strong>{$search_term}</strong></em>
{/if}
{if="!empty($search_tags)"}
{$exploded_tags=tags_str2array($search_tags, $tags_separator)}
{'tagged'|t}
{loop="$exploded_tags"}
<span class="label label-tag" title="{'Remove tag'|t}">
<a href="{$base_path}/remove-tag/{function="$search_tags_url.$key1"}" aria-label="{'Remove tag'|t}">
{$value}<span class="remove"><i class="fa fa-times" aria-hidden="true"></i></span>
</a>
</span>
{/loop}
{/if}
{if="!empty($visibility)"}
{'with status'|t}
<span class="label label-private">
{$visibility|t}
</span>
{/if}
{if="$untaggedonly"}
<span class="label label-private">
{'without any tag'|t}
</span>
{/if}
</div>
</div>
{/if}
<div id="linklist-loop-block" class="pure-g">
<div id="linklist-loop-content">
{ignore}Set translation here, for performances{/ignore}
{$strPrivate=t('Private')}
{$strEdit=t('Edit')}
{$strDelete=t('Delete')}
{$strFold=t('Fold')}
{$strEdited=t('Edited: ')}
{$strPermalink=t('Permalink')}
{$strPermalinkLc=t('permalink')}
{$strAddTag=t('Add tag')}
{$strToggleSticky=t('Toggle sticky')}
{$strSticky=t('Sticky')}
{$strShaarePrivate=t('Share a private link')}
{ignore}End of translations{/ignore}
{loop="links"}
<div class="anchor" id="{$value.shorturl}"></div>
<div class="linklist-item linklist-item{if="$value.class"} {$value.class}{/if}" data-id="{$value.id}">
<div class="linklist-item-title">
<div class="linklist-item-editbuttons">
{if="$is_logged_in"}
<span class="linklist-item-infos-controls-item ctrl-edit">
<a href="{$base_path}/admin/shaare/{$value.id}" aria-label="{$strEdit}" title="{$strEdit}"><i class="fa fa-pencil-square-o edit-link" aria-hidden="true"></i></a>
</span>
{/if}
{if="$value.sticky"}
<span class="label label-sticky">{$strSticky}</span>
{/if}
{if="$value.private"}
<span class="label label-private">{$strPrivate}</span>
{/if}
</div>
<h2>
<a href="{$value.real_url}" class="linklist-real-url">
{if="strpos($value.url, $value.shorturl) === false"}
<i class="fa fa-external-link" aria-hidden="true"></i>
{else}
<i class="fa fa-sticky-note" aria-hidden="true"></i>
{/if}
<img alt="favicon"
src="{$value.favicon}"
loading="lazy"
height="16" width="16" loading>
<span class="linklist-link">
{$value.title_html}</span>
</a>
</h2>
</div>
{if="$thumbnails_enabled && $value.thumbnail !== false"}
<div
class="linklist-item-thumbnail {if="$value.thumbnail === null"}hidden{/if}"
style="width:{$thumbnails_width}px;height:{$thumbnails_height}px;"
{if="$value.thumbnail === null"}data-async-thumbnail="1"{/if}>
<div class="thumbnail">
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore}
<a href="{$value.real_url}" aria-hidden="true" tabindex="-1">
<img
src="{$value.thumbnail}#"
loading="lazy"
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
</a>
</div>
</div>
{/if}
{if="$value.description"}
<div class="linklist-item-description">
{$value.description}
</div>
{/if}
<div class="linklist-item-infos clear">
{if="$value.tags"}
<div class="linklist-item-tags">
<i class="fa fa-tags" aria-hidden="true"></i>
{$tag_counter=count($value.taglist)}
{loop="value.taglist"}
<span class="label label-tag" title="{$strAddTag}">
<a href="{$base_path}/add-tag/{$value1.taglist_urlencoded.$key2}">{$value1.taglist_html.$key2}</a>
</span>
{if="$tag_counter - 1 != $counter"}&middot;{/if}
{/loop}
</div>
{/if}
<div class="linklist-item-infos-date-url-block pure-g">
<div class="linklist-item-infos-dateblock pure-u-lg-7-12 pure-u-1">
{if="$is_logged_in"}
<div class="linklist-item-infos-controls-group pure-u-0 pure-u-lg-visible">
<span class="linklist-item-infos-controls-item ctrl-checkbox">
<input type="checkbox" class="link-checkbox" value="{$value.id}">
</span>
<span class="linklist-item-infos-controls-item ctrl-pin">
<a href="{$base_path}/admin/shaare/{$value.id}/pin?token={$token}"
title="{$strToggleSticky}" aria-label="{$strToggleSticky}" class="pin-link {if="$value.sticky"}pinned-link{/if} pure-u-0 pure-u-lg-visible">
<i class="fa fa-thumb-tack" aria-hidden="true"></i>
</a>
</span>
</div>
{else}
{if="$value.sticky"}
<div class="linklist-item-infos-controls-group pure-u-0 pure-u-lg-visible">
<span class="linklist-item-infos-controls-item ctrl-pin">
<span title="{$strSticky}" class="pin-link pinned-link pure-u-0 pure-u-lg-visible">
<i class="fa fa-thumb-tack" aria-hidden="true"></i>
</span>
</span>
</div>
{/if}
{/if}
{if="!$hide_timestamps || $is_logged_in"}
{$updated=$value.updated_timestamp ? $strEdited. format_date($value.updated) : $strPermalink}
<span class="linkdate" title="{$updated}">
<i class="fa fa-clock-o" aria-hidden="true"></i>
{$value.created|format_date}
{if="$value.updated_timestamp"}*{/if}
&middot;
</span>
{/if}
<a href="{$base_path}/shaare/{$value.shorturl}" title="{$strPermalink}">
{$strPermalinkLc}
</a>
{if="$is_logged_in && $value.private"}
&middot;
<a href="{$base_path}/admin/shaare/private/{$value.shorturl}?token={$token}" title="{$strShaarePrivate}">
<i class="fa fa-share-alt"></i>
</a>
{/if}
<div class="pure-u-0 pure-u-lg-visible">
{if="isset($value.link_plugin)"}
&middot;
{$link_plugin_counter=count($value.link_plugin)}
{loop="$value.link_plugin"}
{$value}
{if="$link_plugin_counter - 1 != $counter"}&middot;{/if}
{/loop}
{/if}
</div>
</div><div
{ignore}do not add space or line break between these div - Firefox issue{/ignore}
class="linklist-item-infos-url pure-u-lg-5-12 pure-u-1">
<a href="{$value.real_url}" aria-label="{$value.title}" title="{$value.title}">
<i class="fa fa-link" aria-hidden="true"></i> {$value.url_html}
</a>
<div class="linklist-item-buttons pure-u-0 pure-u-lg-visible">
<a href="#" aria-label="{$strFold}" title="{$strFold}" class="fold-button"><i class="fa fa-chevron-up" aria-hidden="true"></i></a>
</div>
</div>
<div class="mobile-buttons pure-u-1 pure-u-lg-0">
{if="isset($value.link_plugin)"}
{$link_plugin_counter=count($value.link_plugin)}
{loop="$value.link_plugin"}
{$value}
{if="$link_plugin_counter - 1 != $counter"}&middot;{/if}
{/loop}
{/if}
{if="$is_logged_in"}
&middot;
<a href="{$base_path}/admin/shaare/delete?id={$value.id}&amp;token={$token}" aria-label="{$strDelete}"
title="{$strDelete}" class="delete-link confirm-delete">
<i class="fa fa-trash" aria-hidden="true"></i>
</a>
&middot;
<a href="{$base_path}/admin/shaare/{$value.id}" aria-label="{$strEdit}" title="{$strEdit}">
<i class="fa fa-pencil-square-o edit-link" aria-hidden="true"></i>
</a>
&middot;
<a href="{$base_path}/admin/shaare/{$value.id}/pin?token={$token}"
aria-label="{$strToggleSticky}"
title="{$strToggleSticky}"
class="pin-link {if="$value.sticky"}pinned-link{/if}"
>
<i class="fa fa-thumb-tack" aria-hidden="true"></i>
</a>
{/if}
</div>
</div>
</div>
</div>
<div id="linklist">
<div id="plugin_zone_start_linklist" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
{if="count($links)==0"}
<div class="error section">
{'Nothing found.'|t}
</div>
{elseif="!empty($search_term) or $search_tags !== '' or !empty($visibility) or $untaggedonly"}
<div class="secondary section">
{function="sprintf(t('%s result', '%s results', $result_count), $result_count)"}
{if="!empty($search_term)"}
{'for'|t} <mark>{$search_term}</mark>
{/if}
{if="!empty($search_tags)"}
{$exploded_tags=tags_str2array($search_tags, $tags_separator)}
{'tagged'|t}
{loop="$exploded_tags"}
<a class="tag" href="{$base_path}/remove-tag/{function="$search_tags_url.$key1"}" aria-label="{'Remove tag'|t}">
{$value} | X
</a>
{/loop}
{/if}
{if="!empty($visibility)"}
{'with status'|t}
<span class="tag">
{$visibility|t}
</span>
{/if}
{if="$untaggedonly"}
<span class="tag">
{'without any tag'|t}
</span>
{/if}
</div>
{/if}
{ignore}Set translation here, for performances{/ignore}
{$strPrivate=t('Private')}
{$strEdit=t('Edit')}
{$strDelete=t('Delete')}
{$strFold=t('Fold')}
{$strEdited=t('Edited: ')}
{$strPermalink=t('Permalink')}
{$strPermalinkLc=t('permalink')}
{$strAddTag=t('Add tag')}
{$strToggleSticky=t('Toggle sticky')}
{$strSticky=t('Sticky')}
{$strShaarePrivate=t('Share a private link')}
{ignore}End of translations{/ignore}
{loop="links"}
<article class="{if="$value.class"}{$value.class}{/if} linklist-item" data-id="{$value.id}" id="{$value.shorturl}">
{if="$thumbnails_enabled && $value.thumbnail !== false"}
<figure {if="$value.thumbnail === null"}data-async-thumbnail="1"{/if}>
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore}
<a href="{$value.real_url}" aria-hidden="true" tabindex="-1">
<img loading="lazy" alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}"
src="{$value.thumbnail}#">
</a>
</figure>
{/if}
<header>
<h3>
<a href="{$value.real_url}">
{if="strpos($value.url, $value.shorturl) === false"}
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-external-link"></use>
</svg>
{else}
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-note"></use>
</svg>
{/if}
{if="$thumbnails_enabled && $value.thumbnail !== false"}
<img loading="lazy" height="32" width="32" alt="favicon" src="{$value.favicon}#">
{/if}
<span class="linklist-link">{$value.title_html}</span>
</a>
</h3>
{if="$is_logged_in || $value.sticky || $value.private"}
<div>
{if="$is_logged_in"}
<span>
<a href="{$base_path}/admin/shaare/{$value.id}" aria-label="{$strEdit}" title="{$strEdit}" class="icon">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-edit"></use>
</svg>
</a>
</span>
{/if}
{if="$value.sticky"}
<span class="label label-sticky">{$strSticky}</span>
{/if}
{if="$value.private"}
<span class="label label-private">{$strPrivate}</span>
{/if}
</div>
{/if}
</header>
{if="$value.description"}
<div class="content">
{$value.description}
</div>
{/if}
<footer>
{if="$value.tags"}
<div>
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-tags"></use>
</svg>
{$tag_counter=count($value.taglist)}
{loop="value.taglist"}
<span class="tag" title="{$strAddTag}">
<a href="{$base_path}/add-tag/{$value1.taglist_urlencoded.$key2}">{$value1.taglist_html.$key2}</a>
</span>
{if="$tag_counter - 1 != $counter"}&nbsp;{/if}
{/loop}
</div>
{/if}
<div class="flex">
{if="$is_logged_in"}
<span>
<input type="checkbox" class="link-checkbox" value="{$value.id}">
</span>
<span>
<a href="{$base_path}/admin/shaare/{$value.id}/pin?token={$token}" title="{$strToggleSticky}"
aria-label="{$strToggleSticky}" class="pin-link {if="$value.sticky"}pinned-link{/if}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-pin"></use>
</svg>
</a>
</span>
{else}
{if="$value.sticky"}
<span>
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<title>{$strSticky}</title>
<use href="{$asset_path}/sprites/default.svg#ui-pin"></use>
</svg>
</span>
{/if}
{/if}
{if="!$hide_timestamps || $is_logged_in"}
{$updated=$value.updated_timestamp ? $strEdited. format_date($value.updated) : $strPermalink}
<span>
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<title>{$updated}</title>
<use href="{$asset_path}/sprites/default.svg#ui-clock"></use>
</svg>
{$value.created|format_date}
{if="$value.updated_timestamp"}*{/if}
</span>
{/if}
<span>
<a href="{$base_path}/shaare/{$value.shorturl}" title="{$strPermalink}">
{$strPermalinkLc}
</a>
</span>
{if="$is_logged_in && $value.private"}
<span><a href="{$base_path}/admin/shaare/private/{$value.shorturl}?token={$token}"
title="{$strShaarePrivate}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-share"></use>
</svg>
</a></span>
{/if}
{if="isset($value.link_plugin)"}
<div class="flex plugin">
{$link_plugin_counter=count($value.link_plugin)}
{loop="$value.link_plugin"}
{$value}
{if="$link_plugin_counter - 1 != $counter"}{/if}
{/loop}
</div>
{/if}
<span><a href="{$value.real_url}" aria-label="{$value.title}" title="{$value.title}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-link"></use>
</svg> {$value.url_html}
</a>
<!--<a href="#" aria-label="{$strFold}" title="{$strFold}" class="fold-button"><svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-chevron-up"></use>
</svg></a>-->
</span>
</div>
</footer>
</article>
{/loop}
</div>
</div>
<div id="plugin_zone_end_linklist" class="plugin_zone">
{loop="$plugin_end_zone"}
@ -310,10 +301,12 @@
{/loop}
</div>
{include="linklist.paging"}
{include="linklist.paging"}
{include="page.footer"}
<script src="{$asset_path}/js/thumbnails.min.js?v={$version_hash}#"></script>
{if="$is_logged_in && $async_metadata"}<script src="{$asset_path}/js/metadata.min.js?v={$version_hash}#"></script>{/if}
{include="page.footer"}
<script src="{$asset_path}/js/thumbnails.min.js?v={$version_hash}#"></script>
{if="$is_logged_in && $async_metadata"}
<script src="{$asset_path}/js/metadata.min.js?v={$version_hash}#"></script>
{/if}
</body>
</html>
</html>

View file

@ -1,70 +1,74 @@
<div class="paging pure-g">
<div class="linklist-filters pure-u-1-3">
<span class="linklist-filters-text pure-u-0 pure-u-lg-visible">
{'Filters'|t}
</span>
<div class="grid section paging">
<div>
{'Filters'|t}
{if="$is_logged_in"}
<a href="{$base_path}/admin/visibility/private" aria-label="{'Only display private links'|t}" title="{'Only display private links'|t}"
class="{if="$visibility==='private'"}filter-on{else}filter-off{/if}"
><i class="fa fa-user-secret" aria-hidden="true"></i></a>
<a href="{$base_path}/admin/visibility/public" aria-label="{'Only display public links'|t}" title="{'Only display public links'|t}"
class="{if="$visibility==='public'"}filter-on{else}filter-off{/if}"
><i class="fa fa-globe" aria-hidden="true"></i></a>
<a href="{$base_path}/admin/visibility/private" aria-label="{'Only display private links'|t}"
title="{'Only display private links'|t}" class="{if="$visibility==='private'"} filter-on {else} filter-off{/if}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-secret"></use></svg>
</a>
<a href="{$base_path}/admin/visibility/public" aria-label="{'Only display public links'|t}"
title="{'Only display public links'|t}" class="{if="$visibility==='public'"} filter-on {else} filter-off {/if}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-earth"></use></svg>
</a>
{/if}
<a href="{$base_path}/untagged-only" aria-label="{'Filter untagged links'|t}" title="{'Filter untagged links'|t}"
class={if="$untaggedonly"}"filter-on"{else}"filter-off"{/if}
><i class="fa fa-tag" aria-hidden="true"></i></a>
class="{if="$untaggedonly"}filter-on{else}filter-off{/if}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-tag"></use></svg>
</a>
{if="$is_logged_in"}
<a href="#" aria-label="{'Select all'|t}" title="{'Select all'|t}"
class="filter-off select-all-button pure-u-0 pure-u-lg-visible"
><i class="fa fa-check-square-o" aria-hidden="true"></i></a>
{/if}
<a href="#" class="filter-off fold-all pure-u-lg-0" aria-label="{'Fold all'|t}" title="{'Fold all'|t}">
<i class="fa fa-chevron-up" aria-hidden="true"></i>
<a href="#" aria-label="{'Select all'|t}" title="{'Select all'|t}" class="filter-off select-all-button">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-check-with-border"></use></svg>
</a>
{/if}
{if="!empty($action_plugin)"}
{loop="$action_plugin"}
{$value.attr.class=isset($value.attr.class) ? $value.attr.class : ''}
{$value.attr.class=!empty($value.on) ? $value.attr.class .' filter-on' : $value.attr.class .' filter-off'}
<a
{loop="$value.attr"}
{$key}="{$value}"
{/loop}>
{$value.html}
</a>
{/loop}
{/if}
</div>
<div class="linklist-pages pure-u-1-3">
{if="$next_page_url"}
<a href="{$next_page_url}" class="paging_newer">
<i class="fa fa-arrow-circle-left"></i>
</a>
{/if}
{if="$page_max>1"}<span class="strong">{$page_current} / {$page_max}</span>{/if}
{if="$previous_page_url"}
<a href="{$previous_page_url}" class="paging_older">
<i class="fa fa-arrow-circle-right"></i>
</a>
{/if}
</div>
<div class="linksperpage pure-u-1-3">
<div class="pure-u-0 pure-u-lg-visible">{'Links per page'|t}</div>
<a href="{$base_path}/links-per-page?nb=20"
{if="$links_per_page == 20"}class="selected"{/if}>20</a>
<a href="{$base_path}/links-per-page?nb=50"
{if="$links_per_page == 50"}class="selected"{/if}>50</a>
<a href="{$base_path}/links-per-page?nb=100"
{if="$links_per_page == 100"}class="selected"{/if}>100</a>
<form method="GET" class="pure-u-0 pure-u-lg-visible" action="{$base_path}/links-per-page">
<input type="text" name="nb" placeholder="133"
{if="$links_per_page != 20 && $links_per_page != 50 && $links_per_page != 100"}
value="{$links_per_page}"{/if}>
</form>
<a href="#" class="filter-off fold-all pure-u-0 pure-u-lg-visible" aria-label="{'Fold all'|t}" title="{'Fold all'|t}">
<i class="fa fa-chevron-up" aria-hidden="true"></i>
{loop="$action_plugin"}
{$value.attr.class=isset($value.attr.class) ? $value.attr.class : ''}
{$value.attr.class=!empty($value.on) ? $value.attr.class .' filter-on' : $value.attr.class .' filter-off'}
<a {loop="$value.attr"} {$key}="{$value}" {/loop}>
{$value.html}
</a>
{/loop}
{/if}
</div>
<div>
{if="$next_page_url"}
<a href="{$next_page_url}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-arrow-left-circle"></use></svg>
</a>
{/if}
{if="$page_max>1"}{$page_current} / {$page_max}{/if}
{if="$previous_page_url"}
<a href="{$previous_page_url}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-arrow-right-circle"></use></svg>
</a>
{/if}
</div>
<div class="flex">
{'Links per page'|t}
<a href="{$base_path}/links-per-page?nb=25" {if="$links_per_page == 25"}class="selected"{/if}>25</a>
<a href="{$base_path}/links-per-page?nb=50" {if="$links_per_page == 50"}class="selected"{/if}>50</a>
<a href="{$base_path}/links-per-page?nb=75" {if="$links_per_page == 75"}class="selected"{/if}>75</a>
<form method="GET" action="{$base_path}/links-per-page">
<input type="text" name="nb" placeholder="100"
{if="$links_per_page != 25 && $links_per_page != 50 && $links_per_page != 75"} value="{$links_per_page}"{/if}>
</form>
<!--<a href="#" class="filter-off fold-all" aria-label="{'Fold all'|t}" title="{'Fold all'|t}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<use href="{$asset_path}/sprites/default.svg#ui-chevron-up"></use>
</svg></a>-->
</div>
</div>

View file

@ -1,10 +1,7 @@
</main>
<div class="pure-g">
<div class="pure-u-2-24"></div>
<footer id="footer" class="pure-u-20-24 footer-container" role="contentinfo">
<i class="fa fa-shaarli" aria-hidden="true"></i>
<strong><a href="https://github.com/shaarli/Shaarli">Shaarli</a></strong>
<footer id="footer" role="contentinfo">
<a href="https://github.com/shaarli/Shaarli">Shaarli</a>
{if="$is_logged_in===true"}
{$version}
{/if}
@ -15,8 +12,6 @@
{$value}
{/loop}
</footer>
<div class="pure-u-2-24"></div>
</div>
{loop="$plugins_footer.endofpage"}
{$value}
@ -26,7 +21,7 @@
<script src="{$root_path}/{$value}#"></script>
{/loop}
<div id="js-translations" class="hidden" aria-hidden="true">
<div id="js-translations" aria-hidden="true">
<span id="translation-fold">{'Fold'|t}</span>
<span id="translation-fold-all">{'Fold all'|t}</span>
<span id="translation-expand">{'Expand'|t}</span>
@ -38,8 +33,8 @@
</span>
</div>
<input type="hidden" name="js_base_path" value="{$base_path}" />
<input type="hidden" name="token" value="{$token}" id="token" />
<input type="hidden" name="tags_separator" value="{$tags_separator}" id="tags_separator" />
<input type="hidden" name="js_base_path" value="{$base_path}">
<input type="hidden" name="token" value="{$token}" id="token">
<input type="hidden" name="tags_separator" value="{$tags_separator}" id="tags_separator">
<script src="{$asset_path}/js/shaarli.min.js?v={$version_hash}#"></script>
<script src="{$asset_path}/js/shaarli.min.js?v={$version_hash}#"></script>

View file

@ -1,238 +1,129 @@
<header>
<nav>
<h1>
<img src="{$asset_path}/img/favicon_128.png#" loading="lazy" height="120px" alt="logo" />
<a href="{$titleLink}">
{$shaarlititle}
</a>
</h1>
<ul>
{loop="$plugins_header.buttons_toolbar"}
<li>
<a
{loop="$value.attr"}
{$key}="{$value}"
{/loop}>
{$value.html}
</a>
</li>
{/loop}
{if="$is_logged_in || $openshaarli"}
<li>
<a href="{$base_path}/admin/add-shaare">
{'Shaare'|t}
</a>
</li>
<li>
<a href="{$base_path}/admin/tools">
{'Tools'|t}
</a>
</li>
{/if}
<li>
<a href="{$base_path}/tags/cloud">
{'Tag cloud'|t}
</a>
</li>
{if="$thumbnails_enabled"}
<li>
<a href="{$base_path}/picture-wall?{function="ltrim($searchcrits, '&')"}">
{'Picture wall'|t}
</a>
</li>
{/if}
</ul>
<header class="banner">
<hgroup>
<h1>
<img src="{$asset_path}/img/favicon_128.png#"
height="120"
loading="lazy"
alt="logo"><a href="{$titleLink}">{$shaarlititle}</a>
</h1>
</hgroup>
<nav role="navigation">
<ul>
<li>
<a href="#" title="Toggle Dark/Light theme" aria-label="Toggle Dark/Light theme" onclick="switchTheme();">
<i class="fa fa-moon-o" aria-hidden="true"></i>
</a>
</li>
<li>
<a href="{$base_path}/feed/{$feed_type}?{$searchcrits}" title="{'RSS Feed'|t}" aria-label="{'RSS Feed'|t}">
<i class="fa fa-rss" aria-hidden="true"></i>
</a>
</li>
{if="!$is_logged_in"}
{loop="$plugins_header.buttons_toolbar"}
<li>
<a href="{$base_path}/login"
data-open-id="header-login-form"
id="login-button" aria-label="{'Login'|t}" title="{'Login'|t}">
<i class="fa fa-user" aria-hidden="true"></i>
<a
{loop="$value.attr"}
{$key}="{$value}"
{/loop}>
{$value.html}
</a>
</li>
{else}
{/loop}
{if="$is_logged_in || $openshaarli"}
<li>
<a href="{$base_path}/admin/add-shaare">{'Shaare'|t}</a>
</li>
<li>
<a href="{$base_path}/admin/tools">{'Tools'|t}</a>
</li>
{/if}
<li>
<a href="{$base_path}/admin/logout" aria-label="{'Logout'|t}" title="{'Logout'|t}">
<i class="fa fa-sign-out" aria-hidden="true"></i>
<a href="{$base_path}/tags/cloud">{'Tag cloud'|t}</a>
</li>
{if="$thumbnails_enabled"}
<li>
<a href="{$base_path}/picture-wall?{function="ltrim($searchcrits, '&')"}">{'Picture wall'|t}</a>
</li>
{/if}
<li>
<a href="#" title="Toggle Dark/Light theme" aria-label="Toggle Dark/Light theme" onclick="switchTheme();">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<title>Toggle Dark/Light theme</title>
<use href="{$asset_path}/sprites/default.svg#ui-light-dark"></use>
</svg>
</a>
</li>
{/if}
</ul>
</nav>
<li>
<a href="{$base_path}/feed/{$feed_type}?{$searchcrits}" title="{'RSS Feed'|t}" aria-label="{'RSS Feed'|t}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<title>{'RSS Feed'|t}</title>
<use href="{$asset_path}/sprites/default.svg#ui-feed"></use>
</svg>
</a>
</li>
{if="!$is_logged_in"}
<li>
<a href="{$base_path}/login"
data-open-id="header-login-form"
id="login-button" aria-label="{'Login'|t}" title="{'Login'|t}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<title>{'Login'|t}</title>
<use href="{$asset_path}/sprites/default.svg#ui-user"></use>
</svg>
</a>
</li>
{else}
<li>
<a href="{$base_path}/admin/logout" aria-label="{'Logout'|t}" title="{'Logout'|t}">
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation">
<title>{'Login'|t}</title>
<use href="{$asset_path}/sprites/default.svg#ui-logout"></use>
</svg>
</a>
</li>
{/if}
</ul>
</nav>
</header>
<main id="content" class="container" role="main" data-theme="dark">
<div id="search" class="subheader-form searchform-block header-search">
<form method="GET" class="pure-form searchform" name="searchform" action="{$base_path}/">
<input type="text" id="searchform_value" name="searchterm" aria-label="{'Search text'|t}" placeholder="{'Search text'|t}"
{if="!empty($search_term)"}
value="{$search_term}"
{/if}
>
<input type="text" name="searchtags" id="tagfilter_value" aria-label="{'Filter by tag'|t}" placeholder="{'Filter by tag'|t}"
{if="!empty($search_tags)"}
value="{$search_tags}"
{/if}
autocomplete="off" data-multiple data-autofirst data-minChars="1"
data-list="{loop="$tags"}{$key}, {/loop}"
>
<button type="submit" class="search-button" aria-label="{'Search'|t}"><i class="fa fa-search" aria-hidden="true"></i></button>
</form>
</div>
<div id="actions" class="subheader-form">
<div class="pure-g">
<div class="pure-u-1">
<a href="" id="actions-delete" class="button">
<i class="fa fa-trash" aria-hidden="true"></i>
{'Delete'|t}
</a>&nbsp;
<a href="" class="actions-change-visibility button" data-visibility="public">
<i class="fa fa-globe" aria-hidden="true"></i>
{'Set public'|t}
</a>&nbsp;
<a href="" class="actions-change-visibility button" data-visibility="private">
<i class="fa fa-user-secret" aria-hidden="true"></i>
{'Set private'|t}
</a>&nbsp;
<a href="" class="subheader-opener button" data-open-id="bulk-tag-action-add">
<i class="fa fa-tag" aria-hidden="true"></i>
{'Add tags'|t}
</a>&nbsp;
<a href="" class="subheader-opener button" data-open-id="bulk-tag-action-delete">
<i class="fa fa-window-close" aria-hidden="true"></i>
{'Delete tags'|t}
</a>
</div>
</div>
</div>
{$addDelete=['add', 'delete']}
{loop="$addDelete"}
<div id="bulk-tag-action-{$value}" class="subheader-form">
<form class="pure-g" action="{$base_path}/admin/shaare/update-tags" method="post">
<div class="pure-u-1">
<span>
<input
type="text" name="tag" class="autofocus"
aria-label="{$value === 'add' ? t('Tag to add') : t('Tag to delete')}"
placeholder="{$value === 'add' ? t('Tag to add') : t('Tag to delete')}"
autocomplete="off" data-multiple data-autofirst data-minChars="1"
data-list="{loop="$tags"}{$key}, {/loop}"
>
<input type="hidden" name="action" value="{$value}" />
<input type="hidden" name="id" value="" />
<input type="hidden" name="token" value="{$token}" />
</span>&nbsp;
<a href="" class="button action">
<i class="fa fa-tag" aria-hidden="true"></i>
{$value === 'add' ? t('Add tag') : t('Delete tag')}
</a>&nbsp;
<a href="" class="subheader-opener button cancel" data-open-id="actions">{'Cancel'|t}</a>
</div>
</form>
</div>
{/loop}
{if="!$is_logged_in"}
<form method="post" name="loginform">
<div class="subheader-form header-login-form" id="header-login-form">
<input type="text" name="login" aria-label="{'Username'|t}" placeholder="{'Username'|t}" autocapitalize="off" >
<input type="password" name="password" aria-label="{'Password'|t}" placeholder="{'Password'|t}" >
<div class="remember-me">
<input type="checkbox" name="longlastingsession" id="longlastingsession" checked>
<label for="longlastingsession">{'Remember me'|t}</label>
</div>
<input type="hidden" name="token" value="{$token}">
<input type="hidden" name="returnurl">
<input type="submit" value="Login">
</div>
</form>
{/if}
<main id="content" class="container" role="main">
{if="!empty($newVersion) || !empty($versionError)"}
<div class="pure-g new-version-message pure-alert pure-alert-warning pure-alert-closable">
<div class="pure-u-2-24"></div>
<div class="warning">
{if="$newVersion"}
<div class="pure-u-20-24">
<div>
Shaarli {$newVersion}
<a href="https://github.com/shaarli/Shaarli/releases">{'is available'|t}</a>.
</div>
{/if}
{if="$versionError"}
<div class="pure-u-20-24">
<div>
{'Error'|t}: {$versionError}
</div>
{/if}
<div class="pure-u-2-24">
<i id="new-version-dismiss" class="fa fa-times pure-alert-close"></i>
</div>
</div>
{/if}
{if="!empty($plugin_errors) && $is_logged_in"}
<div class="pure-g new-version-message pure-alert pure-alert-error pure-alert-closable" id="shaarli-errors-alert">
<div class="pure-u-2-24"></div>
<div class="pure-u-20-24">
<div class="error">
{loop="plugin_errors"}
<p>{$value}</p>
{/loop}
</div>
<div class="pure-u-2-24">
<i class="fa fa-times pure-alert-close"></i>
</div>
</div>
{/if}
{if="!empty($global_errors)"}
<div class="pure-g header-alert-message pure-alert pure-alert-error pure-alert-closable" id="shaarli-errors-alert">
<div class="pure-u-2-24"></div>
<div class="pure-u-20-24">
<div class="error">
{loop="$global_errors"}
<p>{$value}</p>
{/loop}
</div>
<div class="pure-u-2-24">
<i class="fa fa-times pure-alert-close"></i>
</div>
</div>
{/if}
{if="!empty($global_warnings)"}
<div class="pure-g header-alert-message pure-alert pure-alert-warning pure-alert-closable" id="shaarli-warnings-alert">
<div class="pure-u-2-24"></div>
<div class="pure-u-20-24">
<div class="warning">
{loop="global_warnings"}
<p>{$value}</p>
{/loop}
</div>
<div class="pure-u-2-24">
<i class="fa fa-times pure-alert-close"></i>
</div>
</div>
{/if}
{if="!empty($global_successes)"}
<div class="pure-g header-alert-message new-version-message pure-alert pure-alert-success pure-alert-closable" id="shaarli-success-alert">
<div class="pure-u-2-24"></div>
<div class="pure-u-20-24">
<div class="success">
{loop="$global_successes"}
<p>{$value}</p>
{/loop}
</div>
<div class="pure-u-2-24">
<i class="fa fa-times pure-alert-close"></i>
</div>
</div>
{/if}
<div class="clear"></div>
{/if}

View file

@ -1,56 +1,52 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
{if="count($linksToDisplay)===0 && $is_logged_in"}
<div class="pure-g pure-alert pure-alert-warning page-single-alert">
<div class="pure-u-1 center">
{'There is no cached thumbnail.'|t}
<a href="{$base_path}/admin/thumbnails">{'Try to synchronize them.'|t}</a>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
{if="count($linksToDisplay)===0 && $is_logged_in"}
<div class="pure-g pure-alert pure-alert-warning page-single-alert">
<div class="pure-u-1 center">
{'There is no cached thumbnail.'|t}
<a href="{$base_path}/admin/thumbnails">{'Try to synchronize them.'|t}</a>
</div>
</div>
</div>
{/if}
{/if}
<div class="pure-g">
<div class="page-form page-visitor">
{$countPics=count($linksToDisplay)}
<h2 class="window-title">{'Picture Wall'|t} - {$countPics} {'pics'|t}</h2>
<div id="plugin_zone_start_picwall" class="plugin_zone">
{loop="$plugin_start_zone"}
<section>
{$countPics=count($linksToDisplay)}
<h2>{'Picture Wall'|t} - {$countPics} {'pics'|t}</h2>
<div id="plugin_zone_start_picwall" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
{/loop}
</div>
<div id="picwall-container" class="picwall-container" role="list">
{loop="$linksToDisplay"}
<div class="picwall-pictureframe" role="listitem" style="width:{$thumbnails_width}px; height:{$thumbnails_height}px ;">
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore}
<img
src="{$value.thumbnail}#"
loading="lazy"
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
<a href="{$value.real_url}"><span class="info">{$value.title}</span></a>
<div class="gallery flex flex-center">
{loop="$linksToDisplay"}
<figure>
<a href="{$value.real_url}">
<img src="{$value.thumbnail}#" loading="lazy" width="{$thumbnails_width}" height="{$thumbnails_height}" alt="thumbnail">
</a>
<figcaption title="{$value.title}">{$value.title}</figcaption>
{loop="$value.picwall_plugin"}
{$value}
{/loop}
</div>
{/loop}
<div class="clear"></div>
</div>
</figure>
{/loop}
</div>
<div id="plugin_zone_end_picwall" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
</div>
</div>
<div id="plugin_zone_end_picwall" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
</section>
{include="page.footer"}
</body>
</html>
{include="page.footer"}
</body>
</html>

View file

@ -1,183 +1,150 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<noscript>
<div class="pure-g new-version-message pure-alert pure-alert-warning">
<div class="pure-u-2-24"></div>
<div class="pure-u-20-24">
{'You have to enable JavaScript to change plugin loading order.'|t}
</div>
</div>
<div class="clear"></div>
</noscript>
<head>
{include="includes"}
</head>
<form method="POST" action="{$base_path}/admin/plugins" name="pluginform" id="pluginform" class="pluginform-container">
<div class="pure-g">
<div class="pure-u-lg-1-8 pure-u-1-24"></div>
<div class="pure-u-lg-3-4 pure-u-22-24 page-form page-form-complete">
<body>
{include="page.header"}
<noscript>
<div class="pure-g new-version-message pure-alert pure-alert-warning">
<div class="pure-u-2-24"></div>
<div class="pure-u-20-24">
{'You have to enable JavaScript to change plugin loading order.'|t}
</div>
</div>
<div class="clear"></div>
</noscript>
<section>
<h2 class="window-title">{'Plugin administration'|t}</h2>
<section id="enabled_plugins">
<h3 class="window-subtitle">{'Enabled Plugins'|t}</h3>
<div>
<form method="POST" action="{$base_path}/admin/plugins" name="pluginform" id="pluginform">
<fieldset id="enabled_plugins">
<legend class="window-subtitle">{'Enabled Plugins'|t}</legend>
{if="count($enabledPlugins)==0"}
<p class="center">{'No plugin enabled.'|t}</p>
<p>{'No plugin enabled.'|t}</p>
{else}
<table id="plugin_table">
<thead>
<tr>
<th class="center">{'Enabled'|t}</th>
<th>{'Enabled'|t}</th>
<th>{'Name'|t}</th>
<th><div class="pure-u-0 pure-u-lg-visible">{'Description'|t}</div></th>
<th class="center">{'Order'|t}</th>
<th>{'Description'|t}</th>
<th>{'Order'|t}</th>
</tr>
</thead>
<tbody>
{loop="$enabledPlugins"}
<tr data-line="{$key}" data-order="{$counter}" class="main-row">
<td class="center"><input type="checkbox" name="{$key}" id="{$key}" checked="checked"></td>
<td class="center">
<label for="{$key}"><strong>{function="str_replace('_', ' ', $key)"}</strong></label>
</td>
<td><div class="pure-u-0 pure-u-lg-visible"><label for="{$key}">{$value.description}</label></div></td>
<td class="center">
{if="count($enabledPlugins)>1"}
<a href="#" class="order order-up"></a>
<a href="#" class="order order-down"></a>
{/if}
<input type="hidden" name="order_{$key}" value="{$counter}">
</td>
</tr>
<tr data-line="{$key}" data-order="{$counter}" class="pure-u-lg-0 mobile-row">
<td colspan="4"><label for="{$key}">{$value.description}</label></td>
</tr>
<tr data-line="{$key}" data-order="{$counter}">
<td class="text-center"><input type="checkbox" name="{$key}" id="{$key}" checked="checked"></td>
<td>
<label for="{$key}">{function="str_replace('_', ' ', $key)"}</label>
</td>
<td>{$value.description}</td>
<td class="text-center">
{if="count($enabledPlugins)>1"}
<a href="#" class="order order-up"></a>
<a href="#" class="order order-down"></a>
{/if}
<input type="hidden" name="order_{$key}" value="{$counter}">
</td>
</tr>
{/loop}
</tbody>
<tfoot>
<tr>
<th class="center">{'Enabled'|t}</th>
<th>{'Enabled'|t}</th>
<th>{'Name'|t}</th>
<th><div class="pure-u-0 pure-u-lg-visible">{'Description'|t}</div></th>
<th class="center">{'Order'|t}</th>
<th>{'Description'|t}</th>
<th>{'Order'|t}</th>
</tr>
</tfoot>
</table>
{/if}
</div>
</section>
</fieldset>
<section id="disabled_plugins">
<h3 class="window-subtitle">{'Disabled Plugins'|t}</h3>
<div>
<fieldset id="disabled_plugins">
<legend class="window-subtitle">{'Disabled Plugins'|t}</legend>
{if="count($disabledPlugins)==0"}
<p class="center">{'No plugin disabled.'|t}</p>
<p>{'No plugin disabled.'|t}</p>
{else}
<table>
<thead>
<tr>
<th class="center">{'Enabled'|t}</th>
<th>{'Enabled'|t}</th>
<th>{'Name'|t}</th>
<th><div class="pure-u-0 pure-u-lg-visible">{'Description'|t}</div></th>
<th>{'Description'|t}</th>
</tr>
</thead>
<tbody>
{loop="$disabledPlugins"}
<tr class="main-row">
<td class="center"><input type="checkbox" name="{$key}" id="{$key}"></td>
<td class="center">
<label for="{$key}"><strong>{function="str_replace('_', ' ', $key)"}</strong></label>
</td>
<td><div class="pure-u-0 pure-u-lg-visible">
<label for="{$key}">{$value.description}</label>
</div></td>
</tr>
<tr class="pure-u-lg-0 mobile-row">
<td colspan="3"><label for="{$key}">{$value.description}</label></td>
</tr>
<tr>
<td class="text-center"><input type="checkbox" name="{$key}" id="{$key}"></td>
<td>
<label for="{$key}">{function="str_replace('_', ' ', $key)"}</label>
</td>
<td>
{$value.description}
</td>
</tr>
{/loop}
</tbody>
<tfoot>
<tr>
<th class="center">{'Enabled'|t}</th>
<th>{'Enabled'|t}</th>
<th>{'Name'|t}</th>
<th><div class="pure-u-0 pure-u-lg-visible">{'Description'|t}</div></th>
<th>{'Description'|t}</th>
</tr>
</tfoot>
</table>
{/if}
</div>
</section>
<div class="center more">
{"More plugins available"|t}
<a href="{$root_path}/doc/html/Community-&-Related-software/#third-party-plugins">{"in the documentation"|t}</a>.
</div>
<div class="center">
</fieldset>
<p>
{"More plugins available"|t}
<a href="{$root_path}/doc/html/Community-&-Related-software/#third-party-plugins">{"in the documentation"|t}</a>.
</p>
<input type="submit" value="{'Save'|t}" name="save">
</div>
</div>
</div>
<input type="hidden" name="token" value="{$token}">
</form>
<input type="hidden" name="token" value="{$token}">
</form>
</section>
<form action="{$base_path}/admin/plugins" method="POST" class="pluginform-container">
<div class="pure-g">
<div class="pure-u-lg-1-8 pure-u-1-24"></div>
<div class="pure-u-lg-3-4 pure-u-22-24 page-form page-form-light">
<section>
<h2 class="window-title">{'Plugin configuration'|t}</h2>
<section id="plugin_parameters">
<div>
{if="count($enabledPlugins)==0"}
<p class="center">{'No plugin enabled.'|t}</p>
{else}
{$nbParameters=0}
{loop="$enabledPlugins"}
{$nbParameters=$nbParameters+count($value.parameters)}
{if="count($value.parameters) > 0"}
<div class="plugin_parameters">
<h3 class="window-subtitle">{function="str_replace('_', ' ', $key)"}</h3>
{loop="$value.parameters"}
<div class="plugin_parameter">
<p class="float_label">
<label for="{$key}">
<code>{$key}</code>
{if="isset($value.desc)"}
&middot; {$value.desc}
{/if}
</label>
</p>
<div class="float_input">
<input name="{$key}" value="{$value.value}" id="{$key}" type="text" />
</div>
</div>
{/loop}
</div>
{/if}
{/loop}
{if="$nbParameters===0"}
<p class="center">{'No parameter available.'|t}</p>
{else}
<div class="center">
<input type="submit" name="parameters_form" value="{'Save'|t}"/>
</div>
<form action="{$base_path}/admin/plugins" method="POST">
{if="count($enabledPlugins)==0"}
<p>{'No plugin enabled.'|t}</p>
{else}
{$nbParameters=0}
{loop="$enabledPlugins"}
{$nbParameters=$nbParameters+count($value.parameters)}
{if="count($value.parameters) > 0"}
<fieldset class="plugin_parameters">
<legend class="window-subtitle">{function="str_replace('_', ' ', $key)"}</legend>
{loop="$value.parameters"}
<label for="{$key}">{$key}
{if="isset($value.desc)"}
&middot; {$value.desc}
{/if}
{/if}
</div>
</section>
</div>
</div>
<input type="hidden" name="token" value="{$token}">
</form>
</label>
<input name="{$key}" value="{$value.value}" id="{$key}" type="text" />
{/loop}
</fieldset>
{/if}
{/loop}
{if="$nbParameters===0"}
<p>{'No parameter available.'|t}</p>
{else}
<input type="submit" name="parameters_form" value="{'Save'|t}" />
{/if}
{/if}
<input type="hidden" name="token" value="{$token}">
</form>
</section>
{include="page.footer"}
<script src="{$asset_path}/js/pluginsadmin.min.js?v={$version_hash}#"></script>
</body>
{include="page.footer"}
<script src="{$asset_path}/js/pluginsadmin.min.js?v={$version_hash}#"></script>
</body>
</html>
</html>

View file

@ -1,129 +1,79 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<div class="pure-g">
<div class="pure-u-lg-1-4 pure-u-1-24"></div>
<div class="pure-u-lg-1-2 pure-u-22-24 page-form server-tables-page">
<h2 class="window-title">{'Server administration'|t}</h2>
<head>
{include="includes"}
</head>
<h3 class="window-subtitle">{'General'|t}</h3>
<body>
{include="page.header"}
<section>
<h2>{'Server administration'|t}</h2>
<div class="pure-g server-row">
<div class="pure-u-lg-1-2 pure-u-1 server-label">
<p>{'Index URL'|t}</p>
</div>
<div class="pure-u-lg-1-2 pure-u-1">
<p><a href="{$index_url}" title="{$pagetitle}">{$index_url}</a></p>
</div>
</div>
<div class="pure-g server-row">
<div class="pure-u-lg-1-2 pure-u-1 server-label">
<p>{'Base path'|t}</p>
</div>
<div class="pure-u-lg-1-2 pure-u-1">
<p>{$base_path}</p>
</div>
</div>
<div class="pure-g server-row">
<div class="pure-u-lg-1-2 pure-u-1 server-label">
<p>{'Client IP'|t}</p>
</div>
<div class="pure-u-lg-1-2 pure-u-1">
<p>{$client_ip}</p>
</div>
</div>
<div class="pure-g server-row">
<div class="pure-u-lg-1-2 pure-u-1 server-label">
<p>{'Trusted reverse proxies'|t}</p>
</div>
<div class="pure-u-lg-1-2 pure-u-1">
{if="count($trusted_proxies) > 0"}
<p>
<article>
<h3>{'General'|t}</h3>
<p>{'Index URL'|t} : <a href="{$index_url}" title="{$pagetitle}">{$index_url}</a></p>
<p>{'Base path'|t} : {$base_path}</p>
<p>{'Client IP'|t} : {$client_ip}</p>
<p>{'Trusted reverse proxies'|t} :
{if="count($trusted_proxies) > 0"}
<ul>
{loop="$trusted_proxies"}
{$value}<br>
<li>{$value}</li>
{/loop}
</p>
</ul>
{else}
<p>{'N/A'|t}</p>
{'N/A'|t}
{/if}
</div>
</div>
{include="server.requirements"}
<h3 class="window-subtitle">{'Version'|t}</h3>
<div class="pure-g server-row">
<div class="pure-u-lg-1-2 pure-u-1 server-label">
<p>{'Current version'|t}</p>
</div>
<div class="pure-u-lg-1-2 pure-u-1">
<p>{$current_version}</p>
</div>
</div>
<div class="pure-g server-row">
<div class="pure-u-lg-1-2 pure-u-1 server-label">
<p>{'Latest release'|t}</p>
</div>
<div class="pure-u-lg-1-2 pure-u-1">
<p>
<a href="{$release_url}" title="{'Visit releases page on Github'|t}">
{$latest_version}
</a>
</p>
</div>
</div>
</article>
<h3 class="window-subtitle">{'Thumbnails'|t}</h3>
{include="server.requirements"}
<article>
<h3>{'Version'|t}</h3>
<p>{'Current version'|t} : {$current_version}</p>
<p>{'Latest release'|t} : <a href="{$release_url}"
title="{'Visit releases page on Github'|t}">{$latest_version}</a>
</p>
</article>
<div class="pure-g server-row">
<div class="pure-u-lg-1-2 pure-u-1 server-label">
<p>{'Thumbnails status'|t}</p>
</div>
<div class="pure-u-lg-1-2 pure-u-1">
<p>
<article>
<h3>{'Thumbnails'|t}</h3>
<p>{'Thumbnails status'|t} :
{if="$thumbnails_mode==='all'"}
{'All'|t}
{'All'|t}
{elseif="$thumbnails_mode==='common'"}
{'Only common media hosts'|t}
{'Only common media hosts'|t}
{else}
{'None'|t}
{'None'|t}
{/if}
</p>
</div>
</div>
{if="$thumbnails_mode!=='none'"}
<p class="flex-center flex">
<a role="button" href="{$base_path}/admin/thumbnails" title="{'Synchronize all link thumbnails'|t}">
{'Synchronize thumbnails'|t}
</a>
</p>
{/if}
</article>
{if="$thumbnails_mode!=='none'"}
<div class="center tools-item">
<a href="{$base_path}/admin/thumbnails" title="{'Synchronize all link thumbnails'|t}">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Synchronize thumbnails'|t}</span>
</a>
</div>
{/if}
<article>
<h3>{'Cache'|t}</h3>
<p class="flex-center flex">
<a role="button" href="{$base_path}/admin/clear-cache?type=main">
{'Clear main cache'|t}
</a>
<a role="button" href="{$base_path}/admin/clear-cache?type=thumbnails">
{'Clear thumbnails cache'|t}
</a>
</p>
</article>
</section>
<h3 class="window-subtitle">{'Cache'|t}</h3>
{include="page.footer"}
<div class="center tools-item">
<a href="{$base_path}/admin/clear-cache?type=main">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Clear main cache'|t}</span>
</a>
</div>
</body>
<div class="center tools-item">
<a href="{$base_path}/admin/clear-cache?type=thumbnails">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Clear thumbnails cache'|t}</span>
</a>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
</html>

View file

@ -1,37 +1,44 @@
<div class="server-tables">
<h3 class="window-subtitle">{'Permissions'|t}</h3>
<article>
<h3>{'Permissions'|t}</h3>
{if="count($permissions) > 0"}
<p class="center">
<i class="fa fa-close fa-color-red" aria-hidden="true"></i>
<p>
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon error">
<use href="{$asset_path}/sprites/default.svg#ui-cancel"></use>
</svg>
{'There are permissions that need to be fixed.'|t}
</p>
<p>
<ul>
{loop="$permissions"}
<div class="center">{$value}</div>
<li>{$value}</li>
{/loop}
</p>
</ul>
{else}
<p class="center">
<i class="fa fa-check fa-color-green" aria-hidden="true"></i>
<p>
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon success">
<use href="{$asset_path}/sprites/default.svg#ui-check"></use>
</svg>
{'All read/write permissions are properly set.'|t}
</p>
{/if}
</article>
<h3 class="window-subtitle">PHP</h3>
<p class="center">
<strong>{'Running PHP'|t} {$php_version}</strong>
<article>
<h3>PHP</h3>
<p>
{'Running PHP'|t} <b>{$php_version}</b>
{if="$php_has_reached_eol"}
<i class="fa fa-circle fa-color-orange" aria-label="hidden"></i><br>
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon warning">
<use href="{$asset_path}/sprites/default.svg#ui-cancel"></use>
</svg>
{'End of life: '|t} {$php_eol}
{else}
<i class="fa fa-circle fa-color-green" aria-label="hidden"></i><br>
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon success">
<use href="{$asset_path}/sprites/default.svg#ui-check"></use>
</svg>
{/if}
</p>
<table class="center">
<table>
<thead>
<tr>
<th>{'Extension'|t}</th>
@ -46,23 +53,28 @@
<td>{$value.name}</td>
<td>{$value.desc}</td>
<td>{$value.required ? t('Required') : t('Optional')}</td>
<td>
<td class="text-center">
{if="$value.loaded"}
{$classLoaded="fa-color-green"}
{$classLoaded="success"}
{$strLoaded=t('Loaded')}
{$uiIcon="check"}
{else}
{$strLoaded=t('Not loaded')}
{if="$value.required"}
{$classLoaded="fa-color-red"}
{$classLoaded="error"}
{$uiIcon="cancel"}
{else}
{$classLoaded="fa-color-orange"}
{$classLoaded="warning"}
{$uiIcon="check"}
{/if}
{/if}
<i class="fa fa-circle {$classLoaded}" aria-label="{$strLoaded}" title="{$strLoaded}"></i>
<svg viewBox="0 0 48 48" aria-hidden="true" focusable="false" role="presentation" class="icon {$classLoaded}">
<title>{$strLoaded}</title>
<use href="{$asset_path}/sprites/default.svg#ui-{$uiIcon}"></use>
</svg>
</td>
</tr>
{/loop}
</tbody>
</table>
</div>
</article>

File diff suppressed because one or more lines are too long

Before

(image error) Size: 1.5 KiB

After

(image error) Size: 18 KiB

Before After
Before After

View file

@ -1,70 +1,58 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
{include="tag.sort"}
<head>
{include="includes"}
</head>
<div class="pure-g">
<div class="page-form page-visitor">
{$countTags=count($tags)}
<h2 class="window-title">{'Tag cloud'|t} - {$countTags} {'tags'|t}</h2>
{if="!empty($search_tags)"}
<p class="center">
<a href="{$base_path}/?searchtags={$search_tags_url}" class="pure-button pure-button-shaarli">
{'List all links with those tags'|t}
</a>
</p>
{/if}
<body>
{include="page.header"}
<div id="search-tagcloud" class="pure-g">
<div class="pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-1-2">
<form method="GET">
<input type="hidden" name="do" value="tagcloud">
<input type="text" name="searchtags" aria-label="{'Filter by tag'|t}" placeholder="{'Filter by tag'|t}"
{if="!empty($search_tags)"}
value="{$search_tags}"
{/if}
autocomplete="off" data-multiple data-autofirst data-minChars="1"
data-list="{loop="$tags"}{$key}, {/loop}"
class="autofocus"
>
<button type="submit" class="search-button" aria-label="{'Search'|t}"><i class="fa fa-search" aria-hidden="true"></i></button>
</form>
</div>
<div class="pure-u-lg-1-4"></div>
</div>
{include="tag.sort"}
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
{loop="$plugin_start_zone"}
<section>
{$countTags=count($tags)}
<h2>{'Tag cloud'|t} - {$countTags} {'tags'|t}</h2>
<form method="GET">
<input type="hidden" name="do" value="tagcloud">
<input type="text" name="searchtags" aria-label="{'Filter by tag'|t}" placeholder="{'Filter by tag'|t}"
{if="!empty($search_tags)"} value="{$search_tags}" {/if} autocomplete="off" data-multiple data-autofirst
data-minChars="1" data-list="{loop="$tags "}{$key}, {/loop}" class="autofocus">
<input type="submit" value="{'Search'|t}">
{if="!empty($search_tags)"}
<a role="button" class="success" href="{$base_path}/?searchtags={$search_tags_url}">
{'List all links with those tags'|t}
</a>
{/if}
</form>
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
{/loop}
</div>
<div id="cloudtag" class="cloudtag-container">
{loop="tags"}
<a href="{$base_path}/?searchtags={$tags_url.$key1}{$tags_separator|urlencode}{$search_tags_url}" style="font-size:{$value.size}em;">{$key}</a
><a href="{$base_path}/add-tag/{$tags_url.$key1}" title="{'Filter by tag'|t}" class="count">{$value.count}</a>
{loop="$value.tag_plugin"}
<div class="cloudtag-container">
{loop="tags"}
<a href="{$base_path}/?searchtags={$tags_url.$key1}{$tags_separator|urlencode}{$search_tags_url}"
style="font-size:{$value.size}rem;">{$key}</a><a href="{$base_path}/add-tag/{$tags_url.$key1}"
title="{'Filter by tag'|t}" class="count">{$value.count}</a>
{loop="$value.tag_plugin"}
{$value}
{/loop}
{/loop}
</div>
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
{/loop}
</div>
</div>
</section>
{include="tag.sort"}
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
</div>
</div>
{include="tag.sort"}
{include="page.footer"}
</body>
</html>
{include="page.footer"}
</body>
</html>

View file

@ -8,84 +8,48 @@
{include="tag.sort"}
<div class="pure-g">
<div class="pure-u-lg-1-6 pure-u-1-24"></div>
<div class="pure-u-lg-2-3 pure-u-22-24 page-form page-visitor">
{$countTags=count($tags)}
<h2 class="window-title">{'Tag list'|t} - {$countTags} {'tags'|t}</h2>
<section>
{$countTags=count($tags)}
<h2>{'Tag cloud'|t} - {$countTags} {'tags'|t}</h2>
<form method="GET">
<input type="hidden" name="do" value="taglist">
<input type="text" name="searchtags" aria-label="{'Filter by tag'|t}" placeholder="{'Filter by tag'|t}"
{if="!empty($search_tags)"} value="{$search_tags}" {/if} autocomplete="off" data-multiple data-autofirst
data-minChars="1" data-list="{loop="$tags "}{$key}, {/loop}" class="autofocus">
<input type="submit" value="{'Search'|t}">
{if="!empty($search_tags)"}
<p class="center">
<a href="{$base_path}/?searchtags={$search_tags_url}" class="pure-button pure-button-shaarli">
{'List all links with those tags'|t}
</a>
</p>
<a role="button" class="success" href="{$base_path}/?searchtags={$search_tags_url}">
{'List all links with those tags'|t}
</a>
{/if}
</form>
<div id="search-tagcloud" class="pure-g searchform-block search-tagcloud">
<div class="pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-1-2">
<form method="GET">
<input type="hidden" name="do" value="taglist">
<input type="text" name="searchtags" aria-label="{'Filter by tag'|t}" placeholder="{'Filter by tag'|t}"
{if="!empty($search_tags)"}
value="{$search_tags}"
{/if}
autocomplete="off" data-multiple data-autofirst data-minChars="1"
data-list="{loop="$tags"}{$key}, {/loop}"
>
<button type="submit" class="search-button" aria-label="{'Search'|t}"><i class="fa fa-search" aria-hidden="true"></i></button>
</form>
</div>
<div class="pure-u-lg-1-4"></div>
</div>
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
<div id="taglist" class="taglist-container">
{loop="tags"}
<div class="tag-list-item pure-g" data-tag="{$key}" data-tag-url="{$tags_url.$key1}">
<div class="pure-u-1">
{if="$is_logged_in===true"}
<a href="#" class="delete-tag" aria-label="{'Delete'|t}"><i class="fa fa-trash" aria-hidden="true"></i></a>&nbsp;&nbsp;
<a href="{$base_path}/admin/tags?fromtag={$tags_url.$key1}" class="rename-tag" aria-label="{'Rename tag'|t}">
<i class="fa fa-pencil-square-o {$key}" aria-hidden="true"></i>
</a>
{/if}
<a href="{$base_path}/add-tag/{$tags_url.$key1}" title="{'Filter by tag'|t}" class="count">{$value}</a>
<a href="{$base_path}/?searchtags={$tags_url.$key1} {$search_tags_url}" class="tag-link">{$key}</a>
{loop="$value.tag_plugin"}
{$value}
{/loop}
</div>
{if="$is_logged_in===true"}
<div class="rename-tag-form pure-u-1">
<input type="text" name="{$key}" value="{$key}" class="rename-tag-input" />
<a href="#" class="validate-rename-tag"><i class="fa fa-check" aria-hidden="true"></i></a>
</div>
{/if}
</div>
{/loop}
</div>
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
</div>
{if="$is_logged_in===true"}
<input type="hidden" name="taglist" value="{loop="$tags"}{$key} {/loop}"
{/if}
<div class="cloudtag-container">
{loop="tags"}
<a href="{$base_path}/add-tag/{$tags_url.$key1}" title="{'Filter by tag'|t}" class="count">{$value}</a><a href="{$base_path}/?searchtags={$tags_url.$key1} {$search_tags_url}" class="tag-link">{$key}</a>
{loop="$value.tag_plugin"}
{$value}
{/loop}
{/loop}
</div>
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
</section>
{include="tag.sort"}
{include="page.footer"}
</body>
</html>
</html>

View file

@ -1,8 +1,6 @@
<div class="pure-g">
<div class="pure-u-1 pure-alert pure-alert-success tag-sort">
<div class="section tag-sort">
{'Sort by:'|t}
<a class="button" href="{$base_path}/tags/cloud">{'Cloud'|t}</a>
<a class="button" href="{$base_path}/tags/list?sort=usage">{'Most used'|t}</a>
<a class="button" href="{$base_path}/tags/list?sort=alpha">{'Alphabetical'|t}</a>
</div>
</div>
<a href="{$base_path}/tags/cloud">{'Cloud'|t}</a>
<a href="{$base_path}/tags/list?sort=usage">{'Most used'|t}</a>
<a href="{$base_path}/tags/list?sort=alpha">{'Alphabetical'|t}</a>
</div>

View file

@ -1,140 +1,88 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{include="includes"}
</head>
<body>
{include="page.header"}
<html{if="$language !=='auto'"} lang=" {$language}"{/if}>
<head>
{include="includes"}
</head>
<section>
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div class="pure-u-lg-1-3 pure-u-22-24 page-form page-form-light">
<h2 class="window-title">{'Settings'|t}</h2>
<div class="tools-item">
<a href="{$base_path}/admin/configure" title="{'Change Shaarli settings: title, timezone, etc.'|t}">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Configure your Shaarli'|t}</span>
</a>
</div>
<div class="tools-item">
<a href="{$base_path}/admin/plugins" title="{'Enable, disable and configure plugins'|t}">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Plugin administration'|t}</span>
</a>
</div>
<div class="tools-item">
<a href="{$base_path}/admin/server"
title="{'Check instance\'s server configuration'|t}">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Server administration'|t}</span>
</a>
</div>
{if="!$openshaarli"}
<div class="tools-item">
<a href="{$base_path}/admin/password" title="{'Change your password'|t}">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Change password'|t}</span>
</a>
</div>
{/if}
<div class="tools-item">
<a href="{$base_path}/admin/tags" title="{'Rename or delete a tag in all links'|t}">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Manage tags'|t}</span>
</a>
</div>
<div class="tools-item">
<a href="{$base_path}/admin/import"
title="{'Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, delicious...)'|t}">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Import links'|t}</span>
</a>
</div>
<div class="tools-item">
<a href="{$base_path}/admin/export"
title="{'Export Netscape HTML bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)'|t}">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Export database'|t}</span>
</a>
</div>
<body>
{include="page.header"}
{loop="$tools_plugin"}
<div class="tools-item">
{$value}
</div>
{/loop}
</div>
<section>
<h2>{'Settings'|t}</h2>
<nav class="vertical-menu">
<ul>
<li><a href="{$base_path}/admin/configure"
title="{'Change Shaarli settings: title, timezone, etc.'|t}">{'Configure your Shaarli'|t}</a></li>
<li><a href="{$base_path}/admin/plugins" title="{'Enable, disable and configure plugins'|t}">{'Plugin administration'|t}</a></li>
<li><a href="{$base_path}/admin/server" title="{'Check instance\'s server configuration'|t}">{'Server administration'|t}</a></li>
{if="!$openshaarli"}
<li><a href="{$base_path}/admin/password" title="{'Change your password'|t}">{'Change password'|t}</a></li>
{/if}
<li><a href="{$base_path}/admin/tags" title="{'Rename or delete a tag in all links'|t}">{'Manage tags'|t}</a>
</li>
<li><a href="{$base_path}/admin/import"
title="{'Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, delicious...)'|t}">{'Import links'|t}</a></li>
<li><a href="{$base_path}/admin/export"
title="{'Export Netscape HTML bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)'|t}">{'Export database'|t}</a></li>
{loop="$tools_plugin"}
<li>{$value}</li>
{/loop}
</ul>
</nav>
</section>
<div class="clear"></div>
</div>
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div class="pure-u-lg-1-3 pure-u-22-24 page-form page-form-light">
<h2 class="window-title">{'Bookmarklets'|t}</h2>
<section>
<h2>{'Bookmarklets'|t}</h2>
<p>
{'Drag one of these button to your bookmarks toolbar or right-click it and "Bookmark This Link"'|t},
{'then click on the bookmarklet in any page you want to share.'|t}
</p>
<div class="tools-item">
<p class="flex-center flex">
<a title="{'Drag this link to your bookmarks toolbar or right-click it and Bookmark This Link'|t},
{'then click ✚Shaare link button in any page you want to share'|t}"
class="bookmarklet-link"
href="javascript:(
function(){
var%20url%20=%20location.href;
var%20title%20=%20document.title%20||%20url;
var%20desc=document.getSelection().toString();
if(desc.length>4000){
desc=desc.substr(0,4000)+'...';
alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}');
}
window.open(
'{$pageabsaddr}admin/shaare?post='%20+%20encodeURIComponent(url)+
'&amp;title='%20+%20encodeURIComponent(title)+
'&amp;description='%20+%20encodeURIComponent(desc)+
'&amp;source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1'
);
}
)();">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">✚ {'Shaare link'|t}</span>
{'then click ✚Shaare link button in any page you want to share'|t}" role="button" href="javascript:(
function(){
var%20url%20=%20location.href;
var%20title%20=%20document.title%20||%20url;
var%20desc=document.getSelection().toString();
if(desc.length>4000){
desc=desc.substr(0,4000)+'...';
alert('{function=" str_replace(' ', ' %20', t('The selected text is too long, it will be truncated.'))"}'); }
window.open( '{$pageabsaddr}admin/shaare?post='
%20+%20encodeURIComponent(url)+ '&amp;title=' %20+%20encodeURIComponent(title)+ '&amp;description='
%20+%20encodeURIComponent(desc)+ '&amp;source=bookmarklet'
,'_blank','menubar=no,height=900,width=700,toolbar=no,scrollbars=yes,status=no,dialog=1' ); } )();">✚ {'Shaare link'|t}
</a>
</div>
<div class="tools-item">
<a title="{'Drag this link to your bookmarks toolbar or right-click it and Bookmark This Link'|t},
{'Then click ✚Add Note button anytime to start composing a private Note (text post) to your Shaarli'|t}"
class="bookmarklet-link"
href="javascript:(
function(){
var%20desc=document.getSelection().toString();
if(desc.length>4000){
desc=desc.substr(0,4000)+'...';
alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}');
}
window.open(
'{$pageabsaddr}admin/shaare?private=1&amp;post='+
'&amp;description='%20+%20encodeURIComponent(desc)+
'&amp;source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1'
);
}
)();">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">✚ {'Add Note'|t}</span>
{'Then click ✚Add Note button anytime to start composing a private Note (text post) to your Shaarli'|t}"
role="button" href="javascript:(
function(){
var%20desc=document.getSelection().toString();
if(desc.length>4000){
desc=desc.substr(0,4000)+'...';
alert('{function=" str_replace(' ', ' %20', t('The selected text is too long, it will be truncated.'))"}'); }
window.open( '{$pageabsaddr}admin/shaare?private=1&amp;post=' + '&amp;description='
%20+%20encodeURIComponent(desc)+ '&amp;source=bookmarklet'
,'_blank','menubar=no,height=900,width=700,toolbar=no,scrollbars=yes,status=no,dialog=1' ); } )();">
✚ {'Add Note'|t}
</a>
</div>
</div>
</div>
</p>
</section>
<div class="pure-g">
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
<div class="pure-u-lg-1-3 pure-u-22-24 page-form page-form-light">
<h2 class="window-title">{'Third-party resources'|t}</h2>
<div class="tools-item">
<a href="https://shaarli.readthedocs.io/en/master/Community-and-related-software/">
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Community and related software'|t}</span>
</a>
</div>
</div>
</div>
<section>
<h2>{'Third-party resources'|t}</h2>
<nav class="vertical-menu">
<ul>
<li>
<a href="https://shaarli.readthedocs.io/en/master/Community-and-related-software/" target="_blank">{'Community and related software'|t}</a>
</li>
</ul>
</nav>
</section>
</section>
{include="page.footer"}
<input type="hidden" id="bookmarklet-alert"
value="{'Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link'|t}">
</body>
{include="page.footer"}
<input type="hidden" id="bookmarklet-alert"
value="{'Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link'|t}">
</body>
</html>
</html>