Update for Shaarli 0.12.2
This commit is contained in:
parent
23a5fc1eef
commit
2c1f0981d9
76 changed files with 9219 additions and 4126 deletions
BIN
assets/myShaarli/fonts/Roboto-Bold.woff
Normal file
BIN
assets/myShaarli/fonts/Roboto-Bold.woff
Normal file
Binary file not shown.
BIN
assets/myShaarli/fonts/Roboto-Bold.woff2
Normal file
BIN
assets/myShaarli/fonts/Roboto-Bold.woff2
Normal file
Binary file not shown.
BIN
assets/myShaarli/fonts/Roboto-Regular.woff
Normal file
BIN
assets/myShaarli/fonts/Roboto-Regular.woff
Normal file
Binary file not shown.
BIN
assets/myShaarli/fonts/Roboto-Regular.woff2
Normal file
BIN
assets/myShaarli/fonts/Roboto-Regular.woff2
Normal file
Binary file not shown.
BIN
assets/myShaarli/img/apple-touch-icon.png
Normal file
BIN
assets/myShaarli/img/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
assets/myShaarli/img/favicon.png
Normal file
BIN
assets/myShaarli/img/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
assets/myShaarli/img/sad_star.png
Normal file
BIN
assets/myShaarli/img/sad_star.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
718
assets/myShaarli/js/base.js
Normal file
718
assets/myShaarli/js/base.js
Normal file
|
@ -0,0 +1,718 @@
|
|||
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;
|
||||
}
|
||||
})();
|
81
assets/myShaarli/js/plugins-admin.js
Normal file
81
assets/myShaarli/js/plugins-admin.js
Normal file
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* 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));
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
1849
assets/myShaarli/scss/shaarli.scss
Normal file
1849
assets/myShaarli/scss/shaarli.scss
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,102 +0,0 @@
|
|||
## Markdown Shaarli plugin
|
||||
|
||||
Convert all your shaares description to HTML formatted Markdown.
|
||||
|
||||
[Read more about Markdown syntax](http://daringfireball.net/projects/markdown/syntax).
|
||||
|
||||
Markdown processing is done with [Parsedown library](https://github.com/erusev/parsedown).
|
||||
|
||||
### Installation
|
||||
|
||||
As a default plugin, it should already be in `tpl/plugins/` directory.
|
||||
If not, download and unpack it there.
|
||||
|
||||
The directory structure should look like:
|
||||
|
||||
```
|
||||
--- plugins
|
||||
|--- markdown
|
||||
|--- help.html
|
||||
|--- markdown.css
|
||||
|--- markdown.meta
|
||||
|--- markdown.php
|
||||
|--- README.md
|
||||
```
|
||||
|
||||
To enable the plugin, just check it in the plugin administration page.
|
||||
|
||||
You can also add `markdown` to your list of enabled plugins in `data/config.json.php`
|
||||
(`general.enabled_plugins` list).
|
||||
|
||||
This should look like:
|
||||
|
||||
```
|
||||
"general": {
|
||||
"enabled_plugins": [
|
||||
"markdown",
|
||||
[...]
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
Parsedown parsing library is imported using Composer. If you installed Shaarli using `git`,
|
||||
or the `master` branch, run
|
||||
|
||||
composer update --no-dev --prefer-dist
|
||||
|
||||
### No Markdown tag
|
||||
|
||||
If the tag `nomarkdown` is set for a shaare, it won't be converted to Markdown syntax.
|
||||
|
||||
> Note: this is a special tag, so it won't be displayed in link list.
|
||||
|
||||
### HTML escape
|
||||
|
||||
By default, HTML tags are escaped. You can enable HTML tags rendering
|
||||
by setting `security.markdwon_escape` to `false` in `data/config.json.php`:
|
||||
|
||||
```json
|
||||
{
|
||||
"security": {
|
||||
"markdown_escape": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
With this setting, Markdown support HTML tags. For example:
|
||||
|
||||
> <strong>strong</strong><strike>strike</strike>
|
||||
|
||||
Will render as:
|
||||
|
||||
> <strong>strong</strong><strike>strike</strike>
|
||||
|
||||
|
||||
**Warning:**
|
||||
|
||||
* This setting might present **security risks** (XSS) on shared instances, even though tags
|
||||
such as script, iframe, etc should be disabled.
|
||||
* If you want to shaare HTML code, it is necessary to use inline code or code blocks.
|
||||
* If your shaared descriptions contained HTML tags before enabling the markdown plugin,
|
||||
enabling it might break your page.
|
||||
|
||||
### Known issue
|
||||
|
||||
#### Redirector
|
||||
|
||||
If you're using a redirector, you *need* to add a space after a link,
|
||||
otherwise the rest of the line will be `urlencode`.
|
||||
|
||||
```
|
||||
[link](http://domain.tld)-->test
|
||||
```
|
||||
|
||||
Will consider `http://domain.tld)-->test` as URL.
|
||||
|
||||
Instead, add an additional space.
|
||||
|
||||
```
|
||||
[link](http://domain.tld) -->test
|
||||
```
|
||||
|
||||
> Won't fix because a `)` is a valid part of an URL.
|
|
@ -1,5 +0,0 @@
|
|||
<div class="md_help">
|
||||
%s
|
||||
<a href="http://daringfireball.net/projects/markdown/syntax" title="%s">
|
||||
%s</a>.
|
||||
</div>
|
|
@ -1,173 +0,0 @@
|
|||
/**
|
||||
* Credit to Simon Laroche <https://github.com/simonlc/Markdown-CSS>
|
||||
* whom created the CSS which this file is based on.
|
||||
* License: Unlicense <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
.markdown p{
|
||||
margin:0.75em 0;
|
||||
}
|
||||
|
||||
.markdown img{
|
||||
max-width:100%;
|
||||
}
|
||||
|
||||
.markdown h1, .markdown h2, .markdown h3, .markdown h4, .markdown h5, .markdown h6{
|
||||
font-weight:normal;
|
||||
font-style:normal;
|
||||
line-height:1em;
|
||||
margin:0.75em 0;
|
||||
}
|
||||
.markdown h4, .markdown h5, .markdown h6{ font-weight: bold; }
|
||||
.markdown h1{ font-size:2.5em; }
|
||||
.markdown h2{ font-size:2em; }
|
||||
.markdown h3{ font-size:1.5em; }
|
||||
.markdown h4{ font-size:1.2em; }
|
||||
.markdown h5{ font-size:1em; }
|
||||
.markdown h6{ font-size:0.9em; }
|
||||
|
||||
.markdown blockquote{
|
||||
color:#666666;
|
||||
padding-left: 3em;
|
||||
border-left: 0.5em #EEE solid;
|
||||
margin:0.75em 0;
|
||||
}
|
||||
.markdown hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa;border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; }
|
||||
.markdown pre, .markdown code, .markdown kbd, .markdown samp {
|
||||
font-family: monospace, 'courier new';
|
||||
font-size: 0.98em;
|
||||
}
|
||||
.markdown pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
|
||||
|
||||
.markdown b, .markdown strong { font-weight: bold; }
|
||||
|
||||
.markdown dfn, .markdown em { font-style: italic; }
|
||||
|
||||
.markdown ins { background: #ff9; color: #000; text-decoration: none; }
|
||||
|
||||
.markdown mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
|
||||
|
||||
.markdown sub, .markdown sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
||||
.markdown sup { top: -0.5em; }
|
||||
.markdown sub { bottom: -0.25em; }
|
||||
|
||||
.markdown ul, .markdown ol { margin: 1em 0; padding: 0 0 0 2em; }
|
||||
.markdown li p:last-child { margin:0 }
|
||||
.markdown dd { margin: 0 0 0 2em; }
|
||||
|
||||
.markdown img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
|
||||
|
||||
.markdown table { border-collapse: collapse; border-spacing: 0; }
|
||||
.markdown td { vertical-align: top; }
|
||||
|
||||
@media only screen and (min-width: 480px) {
|
||||
.markdown {font-size:0.9em;}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
.markdown {font-size:1em;}
|
||||
}
|
||||
|
||||
#linklist .markdown li {
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#linklist .markdown ul li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
#linklist .markdown ol li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown table {
|
||||
padding: 0;
|
||||
}
|
||||
.markdown table tr {
|
||||
border-top: 1px solid #cccccc;
|
||||
background-color: white;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.markdown table tr:nth-child(2n) {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.markdown table tr th {
|
||||
font-weight: bold;
|
||||
border: 1px solid #cccccc;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
.markdown table tr td {
|
||||
border: 1px solid #cccccc;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
.markdown table tr th :first-child, .markdown table tr td :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.markdown table tr th :last-child, table tr td :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown pre {
|
||||
background-color: #eee;
|
||||
padding: 4px 9px;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
overflow: auto;
|
||||
box-shadow: 0 -1px 0 #e5e5e5,0 0 1px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);
|
||||
}
|
||||
|
||||
.markdown pre code {
|
||||
color: black;
|
||||
font-family: 'Consolas', 'Monaco', 'Andale Mono', monospace;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
white-space: pre;
|
||||
word-spacing: normal;
|
||||
word-break: normal;
|
||||
line-height: 1.7;
|
||||
font-size: 11.5px;
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
.markdown :not(pre) code {
|
||||
background-color: #eee;
|
||||
padding: 1px 3px;
|
||||
border-radius: 1px;
|
||||
box-shadow: 0 -1px 0 #e5e5e5,0 0 1px rgba(0,0,0,0.12),0 1px 1px rgba(0,0,0,0.24);
|
||||
}
|
||||
|
||||
#pageheader .md_help {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/*
|
||||
Remove header links style
|
||||
*/
|
||||
#pageheader .md_help a {
|
||||
color: lightgray;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#pageheader .md_help a:hover {
|
||||
color: white;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
description="Render shaare description with Markdown syntax.<br><strong>Warning</strong>:
|
||||
If your shaared descriptions contained HTML tags before enabling the markdown plugin,
|
||||
enabling it might break your page.
|
||||
See the <a href=\"https://github.com/shaarli/Shaarli/tree/master/plugins/markdown#html-rendering\">README</a>."
|
|
@ -1,365 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Plugin Markdown.
|
||||
*
|
||||
* Shaare's descriptions are parsed with Markdown.
|
||||
*/
|
||||
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
use Shaarli\Router;
|
||||
|
||||
/*
|
||||
* If this tag is used on a shaare, the description won't be processed by Parsedown.
|
||||
*/
|
||||
define('NO_MD_TAG', 'nomarkdown');
|
||||
|
||||
/**
|
||||
* Parse linklist descriptions.
|
||||
*
|
||||
* @param array $data linklist data.
|
||||
* @param ConfigManager $conf instance.
|
||||
*
|
||||
* @return mixed linklist data parsed in markdown (and converted to HTML).
|
||||
*/
|
||||
function hook_markdown_render_linklist($data, $conf)
|
||||
{
|
||||
foreach ($data['links'] as &$value) {
|
||||
if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
|
||||
$value = stripNoMarkdownTag($value);
|
||||
continue;
|
||||
}
|
||||
$value['description_src'] = $value['description'];
|
||||
$value['description'] = process_markdown(
|
||||
$value['description'],
|
||||
$conf->get('security.markdown_escape', true),
|
||||
$conf->get('security.allowed_protocols')
|
||||
);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse feed linklist descriptions.
|
||||
*
|
||||
* @param array $data linklist data.
|
||||
* @param ConfigManager $conf instance.
|
||||
*
|
||||
* @return mixed linklist data parsed in markdown (and converted to HTML).
|
||||
*/
|
||||
function hook_markdown_render_feed($data, $conf)
|
||||
{
|
||||
foreach ($data['links'] as &$value) {
|
||||
if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
|
||||
$value = stripNoMarkdownTag($value);
|
||||
continue;
|
||||
}
|
||||
$value['description'] = reverse_feed_permalink($value['description']);
|
||||
$value['description'] = process_markdown(
|
||||
$value['description'],
|
||||
$conf->get('security.markdown_escape', true),
|
||||
$conf->get('security.allowed_protocols')
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse daily descriptions.
|
||||
*
|
||||
* @param array $data daily data.
|
||||
* @param ConfigManager $conf instance.
|
||||
*
|
||||
* @return mixed daily data parsed in markdown (and converted to HTML).
|
||||
*/
|
||||
function hook_markdown_render_daily($data, $conf)
|
||||
{
|
||||
//var_dump($data);die;
|
||||
// Manipulate columns data
|
||||
foreach ($data['linksToDisplay'] as &$value) {
|
||||
if (!empty($value['tags']) && noMarkdownTag($value['tags'])) {
|
||||
$value = stripNoMarkdownTag($value);
|
||||
continue;
|
||||
}
|
||||
$value['formatedDescription'] = process_markdown(
|
||||
$value['formatedDescription'],
|
||||
$conf->get('security.markdown_escape', true),
|
||||
$conf->get('security.allowed_protocols')
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if noMarkdown is set in tags.
|
||||
*
|
||||
* @param string $tags tag list
|
||||
*
|
||||
* @return bool true if markdown should be disabled on this link.
|
||||
*/
|
||||
function noMarkdownTag($tags)
|
||||
{
|
||||
return preg_match('/(^|\s)'. NO_MD_TAG .'(\s|$)/', $tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the no-markdown meta tag so it won't be displayed.
|
||||
*
|
||||
* @param array $link Link data.
|
||||
*
|
||||
* @return array Updated link without no markdown tag.
|
||||
*/
|
||||
function stripNoMarkdownTag($link)
|
||||
{
|
||||
if (! empty($link['taglist'])) {
|
||||
$offset = array_search(NO_MD_TAG, $link['taglist']);
|
||||
if ($offset !== false) {
|
||||
unset($link['taglist'][$offset]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($link['tags'])) {
|
||||
str_replace(NO_MD_TAG, '', $link['tags']);
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* When link list is displayed, include markdown CSS.
|
||||
*
|
||||
* @param array $data includes data.
|
||||
*
|
||||
* @return mixed - includes data with markdown CSS file added.
|
||||
*/
|
||||
function hook_markdown_render_includes($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == Router::$PAGE_LINKLIST
|
||||
|| $data['_PAGE_'] == Router::$PAGE_DAILY
|
||||
|| $data['_PAGE_'] == Router::$PAGE_EDITLINK
|
||||
) {
|
||||
$data['css_files'][] = PluginManager::$PLUGINS_PATH . '/markdown/markdown.css';
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook render_editlink.
|
||||
* Adds an help link to markdown syntax.
|
||||
*
|
||||
* @param array $data data passed to plugin
|
||||
*
|
||||
* @return array altered $data.
|
||||
*/
|
||||
function hook_markdown_render_editlink($data)
|
||||
{
|
||||
// Load help HTML into a string
|
||||
$txt = file_get_contents(PluginManager::$PLUGINS_PATH .'/markdown/help.html');
|
||||
$translations = [
|
||||
t('Description will be rendered with'),
|
||||
t('Markdown syntax documentation'),
|
||||
t('Markdown syntax'),
|
||||
];
|
||||
$data['edit_link_plugin'][] = vsprintf($txt, $translations);
|
||||
// Add no markdown 'meta-tag' in tag list if it was never used, for autocompletion.
|
||||
if (! in_array(NO_MD_TAG, $data['tags'])) {
|
||||
$data['tags'][NO_MD_TAG] = 0;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove HTML links auto generated by Shaarli core system.
|
||||
* Keeps HREF attributes.
|
||||
*
|
||||
* @param string $description input description text.
|
||||
*
|
||||
* @return string $description without HTML links.
|
||||
*/
|
||||
function reverse_text2clickable($description)
|
||||
{
|
||||
$descriptionLines = explode(PHP_EOL, $description);
|
||||
$descriptionOut = '';
|
||||
$codeBlockOn = false;
|
||||
$lineCount = 0;
|
||||
|
||||
foreach ($descriptionLines as $descriptionLine) {
|
||||
// Detect line of code: starting with 4 spaces,
|
||||
// except lists which can start with +/*/- or `2.` after spaces.
|
||||
$codeLineOn = preg_match('/^ +(?=[^\+\*\-])(?=(?!\d\.).)/', $descriptionLine) > 0;
|
||||
// Detect and toggle block of code
|
||||
if (!$codeBlockOn) {
|
||||
$codeBlockOn = preg_match('/^```/', $descriptionLine) > 0;
|
||||
} elseif (preg_match('/^```/', $descriptionLine) > 0) {
|
||||
$codeBlockOn = false;
|
||||
}
|
||||
|
||||
$hashtagTitle = ' title="Hashtag [^"]+"';
|
||||
// Reverse `inline code` hashtags.
|
||||
$descriptionLine = preg_replace(
|
||||
'!(`[^`\n]*)<a href="[^ ]*"'. $hashtagTitle .'>([^<]+)</a>([^`\n]*`)!m',
|
||||
'$1$2$3',
|
||||
$descriptionLine
|
||||
);
|
||||
|
||||
// Reverse all links in code blocks, only non hashtag elsewhere.
|
||||
$hashtagFilter = (!$codeBlockOn && !$codeLineOn) ? '(?!'. $hashtagTitle .')': '(?:'. $hashtagTitle .')?';
|
||||
$descriptionLine = preg_replace(
|
||||
'#<a href="[^ ]*"'. $hashtagFilter .'>([^<]+)</a>#m',
|
||||
'$1',
|
||||
$descriptionLine
|
||||
);
|
||||
|
||||
// Make hashtag links markdown ready, otherwise the links will be ignored with escape set to true
|
||||
if (!$codeBlockOn && !$codeLineOn) {
|
||||
$descriptionLine = preg_replace(
|
||||
'#<a href="([^ ]*)"'. $hashtagTitle .'>([^<]+)</a>#m',
|
||||
'[$2]($1)',
|
||||
$descriptionLine
|
||||
);
|
||||
}
|
||||
|
||||
$descriptionOut .= $descriptionLine;
|
||||
if ($lineCount++ < count($descriptionLines) - 1) {
|
||||
$descriptionOut .= PHP_EOL;
|
||||
}
|
||||
}
|
||||
return $descriptionOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove <br> tag to let markdown handle it.
|
||||
*
|
||||
* @param string $description input description text.
|
||||
*
|
||||
* @return string $description without <br> tags.
|
||||
*/
|
||||
function reverse_nl2br($description)
|
||||
{
|
||||
return preg_replace('!<br */?>!im', '', $description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove HTML spaces ' ' auto generated by Shaarli core system.
|
||||
*
|
||||
* @param string $description input description text.
|
||||
*
|
||||
* @return string $description without HTML links.
|
||||
*/
|
||||
function reverse_space2nbsp($description)
|
||||
{
|
||||
return preg_replace('/(^| ) /m', '$1 ', $description);
|
||||
}
|
||||
|
||||
function reverse_feed_permalink($description)
|
||||
{
|
||||
return preg_replace('@— <a href="([^"]+)" title="[^"]+">(\w+)</a>$@im', '— [$2]($1)', $description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace not whitelisted protocols with http:// in given description.
|
||||
*
|
||||
* @param string $description input description text.
|
||||
* @param array $allowedProtocols list of allowed protocols.
|
||||
*
|
||||
* @return string $description without malicious link.
|
||||
*/
|
||||
function filter_protocols($description, $allowedProtocols)
|
||||
{
|
||||
return preg_replace_callback(
|
||||
'#]\((.*?)\)#is',
|
||||
function ($match) use ($allowedProtocols) {
|
||||
return ']('. whitelist_protocols($match[1], $allowedProtocols) .')';
|
||||
},
|
||||
$description
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove dangerous HTML tags (tags, iframe, etc.).
|
||||
* Doesn't affect <code> content (already escaped by Parsedown).
|
||||
*
|
||||
* @param string $description input description text.
|
||||
*
|
||||
* @return string given string escaped.
|
||||
*/
|
||||
function sanitize_html($description)
|
||||
{
|
||||
$escapeTags = array(
|
||||
'script',
|
||||
'style',
|
||||
'link',
|
||||
'iframe',
|
||||
'frameset',
|
||||
'frame',
|
||||
);
|
||||
foreach ($escapeTags as $tag) {
|
||||
$description = preg_replace_callback(
|
||||
'#<\s*'. $tag .'[^>]*>(.*</\s*'. $tag .'[^>]*>)?#is',
|
||||
function ($match) {
|
||||
return escape($match[0]);
|
||||
},
|
||||
$description
|
||||
);
|
||||
}
|
||||
$description = preg_replace(
|
||||
'#(<[^>]+\s)on[a-z]*="?[^ "]*"?#is',
|
||||
'$1',
|
||||
$description
|
||||
);
|
||||
return $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render shaare contents through Markdown parser.
|
||||
* 1. Remove HTML generated by Shaarli core.
|
||||
* 2. Reverse the escape function.
|
||||
* 3. Generate markdown descriptions.
|
||||
* 4. Sanitize sensible HTML tags for security.
|
||||
* 5. Wrap description in 'markdown' CSS class.
|
||||
*
|
||||
* @param string $description input description text.
|
||||
* @param bool $escape escape HTML entities
|
||||
*
|
||||
* @return string HTML processed $description.
|
||||
*/
|
||||
function process_markdown($description, $escape = true, $allowedProtocols = [])
|
||||
{
|
||||
$parsedown = new Parsedown();
|
||||
|
||||
$processedDescription = $description;
|
||||
$processedDescription = reverse_nl2br($processedDescription);
|
||||
$processedDescription = reverse_space2nbsp($processedDescription);
|
||||
$processedDescription = reverse_text2clickable($processedDescription);
|
||||
$processedDescription = filter_protocols($processedDescription, $allowedProtocols);
|
||||
$processedDescription = unescape($processedDescription);
|
||||
$processedDescription = $parsedown
|
||||
->setMarkupEscaped($escape)
|
||||
->setBreaksEnabled(true)
|
||||
->text($processedDescription);
|
||||
$processedDescription = sanitize_html($processedDescription);
|
||||
|
||||
if (!empty($processedDescription)) {
|
||||
$processedDescription = '<div class="markdown">'. $processedDescription . '</div>';
|
||||
}
|
||||
|
||||
return $processedDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is never called, but contains translation calls for GNU gettext extraction.
|
||||
*/
|
||||
function markdown_dummy_translation()
|
||||
{
|
||||
// meta
|
||||
t('Render shaare description with Markdown syntax.<br><strong>Warning</strong>:
|
||||
If your shaared descriptions contained HTML tags before enabling the markdown plugin,
|
||||
enabling it might break your page.
|
||||
See the <a href="https://github.com/shaarli/Shaarli/tree/master/plugins/markdown#html-rendering">README</a>.');
|
||||
}
|
|
@ -1,5 +1,9 @@
|
|||
<?php
|
||||
|
||||
use Shaarli\Bookmark\Bookmark;
|
||||
use Shaarli\Config\ConfigManager;
|
||||
use Shaarli\Plugin\PluginManager;
|
||||
|
||||
/**
|
||||
* Plugin externalThumbshot
|
||||
*/
|
||||
|
@ -11,19 +15,20 @@
|
|||
*
|
||||
* @return array Eventual error.
|
||||
*/
|
||||
function myShaarli_init($conf)
|
||||
{
|
||||
function myShaarli_init($conf) {
|
||||
if (empty($conf->get('plugins.ExternalThumbshot_URL'))) {
|
||||
$error = 'myShaarli plugin error: ' .
|
||||
'Please define the "ExternalThumbshot_URL" setting in the plugin administration page.';
|
||||
$conf->set('thumbnails.mode', 'none');
|
||||
return array($error);
|
||||
}
|
||||
if ($conf->get('resource.theme') !== 'myShaarli' and $conf->get('resource.theme') !== 'myShaarli_Columns') {
|
||||
$error = 'myShaarli plugin: ' .
|
||||
'This plugin need modification of template. Use myShaarli theme for test.';
|
||||
$conf->set('thumbnails.mode', 'none');
|
||||
return array($error);
|
||||
}
|
||||
$conf->set('thumbnails.mode', 'none');
|
||||
$conf->set('thumbnails.mode', 'full');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,8 +39,7 @@ function myShaarli_init($conf)
|
|||
* @return mixed - linklist data with readityourself plugin.
|
||||
*/
|
||||
|
||||
function hook_myShaarli_render_linklist($data, $conf)
|
||||
{
|
||||
function hook_myShaarli_render_linklist($data, $conf) {
|
||||
$action = array(
|
||||
'attr' => array(
|
||||
'href' => '?searchtags=note',
|
||||
|
@ -94,8 +98,7 @@ function hook_myShaarli_render_linklist($data, $conf)
|
|||
* @return mixed - linklist data with readityourself plugin.
|
||||
*/
|
||||
|
||||
function hook_myShaarli_render_daily($data, $conf)
|
||||
{
|
||||
function hook_myShaarli_render_daily($data, $conf) {
|
||||
$thumUrl = $conf->get('plugins.ExternalThumbshot_URL');
|
||||
if (!empty($conf->get('plugins.ExternalThumbshot_KEY'))) {
|
||||
$key = $conf->get('plugins.ExternalThumbshot_KEY');
|
||||
|
@ -124,10 +127,9 @@ function hook_myShaarli_render_daily($data, $conf)
|
|||
/**
|
||||
* Hook render_footer.
|
||||
*/
|
||||
function hook_myShaarli_render_footer($data)
|
||||
{
|
||||
function hook_myShaarli_render_footer($data) {
|
||||
if (file_exists('contact.php')) {
|
||||
$data['text'][] = '<br><a href="https://forge.leslibres.org/Knah-Tsaeb/MyShaarli">MyShaarli</a> is a fork of Shaarli.<a href="contact.php">Contact</a>';
|
||||
$data['text'][] = '<br><a href="contact.php">Contact</a>';
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
@ -142,8 +144,7 @@ function hook_myShaarli_render_footer($data)
|
|||
*
|
||||
* @return array altered $data.
|
||||
*/
|
||||
function hook_myShaarli_render_editlink($data)
|
||||
{
|
||||
function hook_myShaarli_render_editlink($data) {
|
||||
if ((int) $data['link_is_new'] === 1 && $data['link']['url'][0] === '?' && strlen($data['link']['url']) === 7) {
|
||||
$data['link']['tags'] = 'note ';
|
||||
}
|
||||
|
@ -160,8 +161,7 @@ Améliore la sortie print
|
|||
@return false affiche les clef valeur du tableau $data
|
||||
@example n_print($array, 'Tableau de valeur');
|
||||
*/
|
||||
function n_print($data, $name = '')
|
||||
{
|
||||
function n_print($data, $name = '') {
|
||||
$aBackTrace = debug_backtrace();
|
||||
echo '<h2>', $name, '</h2>';
|
||||
echo '<fieldset style="border: 1px solid orange; padding: 5px;color: <a href="?addtag=333" title="Hashtag 333">#333</a>; background-color: <a href="?addtag=fff" title="Hashtag fff">#fff</a>;">';
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
<label for="lf_stuff"><i>Origin</i></label><br>
|
||||
<input type="text" name="lf_origin" id="lf_origin" value="%s" class="lf_input"><br>
|
||||
<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>
|
||||
|
|
|
@ -25,8 +25,8 @@ use Shaarli\Router;
|
|||
$html = file_get_contents(PluginManager::$PLUGINS_PATH .'/origin/field.html');
|
||||
|
||||
// replace value in HTML if it exists in $data
|
||||
if (!empty($data['link']['via'])) {
|
||||
$html = sprintf($html, $data['link']['via']);
|
||||
if (!empty($data['link']['additional_content']['via'])) {
|
||||
$html = sprintf($html, $data['link']['additional_content']['via']);
|
||||
} else {
|
||||
$html = sprintf($html, '');
|
||||
}
|
||||
|
@ -51,7 +51,8 @@ use Shaarli\Router;
|
|||
{
|
||||
// Save link added in editlink field
|
||||
if (!empty($_POST['lf_origin'])) {
|
||||
$data['via'] = escape($_POST['lf_origin']);
|
||||
$data['additional_content']['via'] = escape($_POST['lf_origin']);
|
||||
n_print($_POST);
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
@ -71,9 +72,9 @@ use Shaarli\Router;
|
|||
$origin_html = file_get_contents(PluginManager::$PLUGINS_PATH . '/origin/render.html');
|
||||
|
||||
foreach ($data['links'] as &$value) {
|
||||
if(!empty($value['via'])){
|
||||
$host = getJustDomain($value['via']);
|
||||
$origin = sprintf($origin_html, $value['via'], $host);
|
||||
if(!empty($value['additional_content']['via'])){
|
||||
$host = getJustDomain($value['additional_content']['via']);
|
||||
$origin = sprintf($origin_html, $value['additional_content']['via'], $host);
|
||||
$value['description'] = $value['description'].$origin;
|
||||
}
|
||||
}
|
||||
|
@ -108,9 +109,9 @@ use Shaarli\Router;
|
|||
$origin_html = file_get_contents(PluginManager::$PLUGINS_PATH . '/origin/render.html');
|
||||
|
||||
foreach ($data['links'] as &$value) {
|
||||
if(!empty($value['via'])){
|
||||
$host = getJustDomain($value['via']);
|
||||
$origin = sprintf($origin_html, $value['via'], $host);
|
||||
if(!empty($value['additional_content']['via'])){
|
||||
$host = getJustDomain($value['additional_content']['via']);
|
||||
$origin = sprintf($origin_html, $value['additional_content']['via'], $host);
|
||||
$value['description'] = $value['description'].$origin;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
<body>
|
||||
<div id="pageheader">
|
||||
{include="page.header"}
|
||||
<div class="center" id="page404" class="page404-container">
|
||||
<div id="pageError" class="page-error-container center">
|
||||
<h2>{'Sorry, nothing to see here.'|t}</h2>
|
||||
<img src="img/sad_star.png" alt="">
|
||||
<img src="{$asset_path}/img/sad_star.png#" alt="">
|
||||
<p>{$error_message}</p>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<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">{"Shaare a new link"|t}</h2>
|
||||
<form method="GET" action="#" name="addform" class="addform">
|
||||
<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">
|
||||
|
@ -20,6 +20,62 @@
|
|||
</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} <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}>
|
||||
<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>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<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="#" name="changepasswordform" id="changepasswordform">
|
||||
<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>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<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">{"Manage tags"|t}</h2>
|
||||
<form method="POST" action="#" name="changetag" id="changetag">
|
||||
<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">
|
||||
|
@ -27,12 +27,36 @@
|
|||
<div><i class="fa fa-info-circle" aria-hidden="true"></i> {'Case sensitive'|t}</div>
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
<div>
|
||||
<input type="submit" value="{'Rename'|t}" name="renametag">
|
||||
<input type="submit" value="{'Delete'|t}" name="deletetag" class="button button-red confirm-delete">
|
||||
<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>
|
||||
</form>
|
||||
|
||||
<p>{'You can also edit tags in the'|t} <a href="?do=taglist&sort=usage">{'tag list'|t}</a>.</p>
|
||||
<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">
|
||||
<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>
|
||||
{'Note that hashtags won\'t fully work with a non-whitespace separator.'|t}
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
{$ratioInput='7-12'}
|
||||
{$ratioInputMobile='1-8'}
|
||||
|
||||
<form method="POST" action="#" name="configform" id="configform">
|
||||
<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">
|
||||
|
@ -35,7 +35,7 @@
|
|||
<div class="form-label">
|
||||
<label for="titleLink">
|
||||
<span class="label-name">{'Home link'|t}</span><br>
|
||||
<span class="label-desc">{'Default value'|t}: ?</span>
|
||||
<span class="label-desc">{'Default value'|t}: {$base_path}/</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
|
||||
<div class="form-label">
|
||||
<label for="titleLink">
|
||||
<span class="label-name">{'Theme'|t}</span>
|
||||
<span class="label-name">{'Themes'|t}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,12 +68,34 @@
|
|||
</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">{'Language'|t}</span>
|
||||
<span class="label-name">{'Languages'|t}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -199,8 +221,8 @@
|
|||
<div class="pure-g">
|
||||
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile}">
|
||||
<div class="form-label">
|
||||
<label for="hidePublicLinks">
|
||||
<span class="label-name">{'Check updates'|t}</span><br>
|
||||
<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>
|
||||
|
@ -215,22 +237,22 @@
|
|||
<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>
|
||||
<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 class="pure-g">
|
||||
<div class="pure-u-lg-{$ratioLabel} pure-u-{$ratioLabelMobile}">
|
||||
<div class="form-label">
|
||||
</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>
|
||||
|
@ -248,7 +270,7 @@
|
|||
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
|
||||
<div class="form-label">
|
||||
<label for="apiSecret">
|
||||
<span class="label-name">{'API secret'|t}</span><br>
|
||||
<span class="label-name">{'REST API secret'|t}</span><br>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -267,7 +289,7 @@
|
|||
{if="! $gd_enabled"}
|
||||
{'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}
|
||||
{elseif="$thumbnails_enabled"}
|
||||
<a href="?do=thumbs_update">{'Synchronize thumbnails'|t}</a>
|
||||
<a href="{$base_path}/admin/thumbnails">{'Synchronize thumbnails'|t}</a>
|
||||
{/if}
|
||||
</span>
|
||||
</label>
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
.awesomplete [hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.awesomplete .visually-hidden {
|
||||
position: absolute;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.awesomplete {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.awesomplete > input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.awesomplete > ul {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
min-width: 100%;
|
||||
box-sizing: border-box;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.awesomplete > ul:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.awesomplete > ul {
|
||||
border-radius: .3em;
|
||||
margin: .2em 0 0;
|
||||
background: hsla(0,0%,100%,.9);
|
||||
background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));
|
||||
border: 1px solid rgba(0,0,0,.3);
|
||||
box-shadow: .05em .2em .6em rgba(0,0,0,.2);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
@supports (transform: scale(0)) {
|
||||
.awesomplete > ul {
|
||||
transition: .3s cubic-bezier(.4,.2,.5,1.4);
|
||||
transform-origin: 1.43em -.43em;
|
||||
}
|
||||
|
||||
.awesomplete > ul[hidden],
|
||||
.awesomplete > ul:empty {
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
display: block;
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pointer */
|
||||
.awesomplete > ul:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -.43em;
|
||||
left: 1em;
|
||||
width: 0; height: 0;
|
||||
padding: .4em;
|
||||
background: white;
|
||||
border: inherit;
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.awesomplete > ul > li {
|
||||
position: relative;
|
||||
padding: .2em .5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.awesomplete > ul > li:hover {
|
||||
background: hsl(200, 40%, 80%);
|
||||
color: black;
|
||||
}
|
||||
|
||||
.awesomplete > ul > li[aria-selected="true"] {
|
||||
background: hsl(205, 40%, 40%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.awesomplete mark {
|
||||
background: hsl(65, 100%, 50%);
|
||||
}
|
||||
|
||||
.awesomplete li:hover mark {
|
||||
background: hsl(68, 100%, 41%);
|
||||
}
|
||||
|
||||
.awesomplete li[aria-selected="true"] mark {
|
||||
background: hsl(86, 100%, 21%);
|
||||
color: inherit;
|
||||
}
|
||||
/*# sourceMappingURL=awesomplete.css.map */
|
12
tpl/myShaarli/css/fork-awesome.min.css
vendored
12
tpl/myShaarli/css/fork-awesome.min.css
vendored
File diff suppressed because one or more lines are too long
7
tpl/myShaarli/css/grids-responsive-min.css
vendored
7
tpl/myShaarli/css/grids-responsive-min.css
vendored
File diff suppressed because one or more lines are too long
7
tpl/myShaarli/css/grids-responsive.min.css
vendored
7
tpl/myShaarli/css/grids-responsive.min.css
vendored
File diff suppressed because one or more lines are too long
1
tpl/myShaarli/css/markdown.min.css
vendored
Normal file
1
tpl/myShaarli/css/markdown.min.css
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
.markdown p{margin:.75em 0}.markdown img{max-width:100%}.markdown h1,.markdown h2,.markdown h3,.markdown h4,.markdown h5,.markdown h6{font-weight:normal;font-style:normal;line-height:1em;margin:.75em 0}.markdown h4,.markdown h5,.markdown h6{font-weight:bold}.markdown h1{font-size:2.5em}.markdown h2{font-size:2em}.markdown h3{font-size:1.5em}.markdown h4{font-size:1.2em}.markdown h5{font-size:1em}.markdown h6{font-size:.9em}.markdown blockquote{color:#666;padding-left:3em;border-left:.5em #eee solid;margin:.75em 0}.markdown hr{display:block;height:2px;border:0;border-top:1px solid #aaa;border-bottom:1px solid #eee;margin:1em 0;padding:0}.markdown pre,.markdown code,.markdown kbd,.markdown samp{font-family:monospace,"courier new";font-size:.98em}.markdown pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}.markdown b,.markdown strong{font-weight:bold}.markdown dfn,.markdown em{font-style:italic}.markdown ins{background:#ff9;color:#000;text-decoration:none}.markdown mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}.markdown sub,.markdown sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}.markdown sup{top:-0.5em}.markdown sub{bottom:-0.25em}.markdown ul,.markdown ol{margin:1em 0;padding:0 0 0 2em}.markdown li p:last-child{margin:0}.markdown dd{margin:0 0 0 2em}.markdown img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle}.markdown table{border-collapse:collapse;border-spacing:0}.markdown td{vertical-align:top}@media only screen and (min-width: 480px){.markdown{font-size:.9em}}@media only screen and (min-width: 768px){.markdown{font-size:1em}}#linklist .markdown li{padding:0;border:none;background:none}#linklist .markdown ul li{list-style:circle}#linklist .markdown ol li{list-style:decimal}.markdown table{padding:0}.markdown table tr{border-top:1px solid #ccc;background-color:#fff;margin:0;padding:0}.markdown table tr:nth-child(2n){background-color:#f8f8f8}.markdown table tr th{font-weight:bold;border:1px solid #ccc;text-align:left;margin:0;padding:6px 13px}.markdown table tr td{border:1px solid #ccc;text-align:left;margin:0;padding:6px 13px}.markdown table tr th :first-child,.markdown table tr td :first-child{margin-top:0}.markdown table tr th :last-child,table tr td :last-child{margin-bottom:0}.markdown pre{background-color:#eee;padding:4px 9px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;overflow:auto;box-shadow:0 -1px 0 #e5e5e5,0 0 1px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}.markdown pre code{color:#000;font-family:"Consolas","Monaco","Andale Mono",monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.7;font-size:11.5px;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.markdown :not(pre) code{background-color:#eee;padding:1px 3px;border-radius:1px;box-shadow:0 -1px 0 #e5e5e5,0 0 1px rgba(0,0,0,.12),0 1px 1px rgba(0,0,0,.24)}#pageheader .md_help{color:#fff}#pageheader .md_help a{color:#d3d3d3;font-weight:bold;text-decoration:underline;background:none;box-shadow:none;padding:0;margin:0}#pageheader .md_help a:hover{color:#fff}
|
|
@ -1377,4 +1377,5 @@ form[name="linkform"].page-form {
|
|||
color: white;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
|
|
@ -1,262 +0,0 @@
|
|||
/* Images */
|
||||
.pure-img-eliptical {
|
||||
border-radius: 80%;
|
||||
}
|
||||
.pure-img-rounded {
|
||||
border-radius: 3px;
|
||||
}
|
||||
.pure-img-bordered {
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
|
||||
/* Thumbnails */
|
||||
.pure-thumbnails li {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
/* IE7 inline-block hack */
|
||||
*zoom: 1;
|
||||
vertical-align: top;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 0.5em;
|
||||
}
|
||||
.pure-thumbnails {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.pure-thumbnails a:focus {
|
||||
outline: 0 none;
|
||||
}
|
||||
|
||||
.pure-thumb {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
.pure-thumb img {
|
||||
max-width: 100%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
vertical-align: middle; /* this will remove a thin line below the image */
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pure-thumb-bordered {
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.pure-thumb .caption {
|
||||
text-align: left;
|
||||
display: block;
|
||||
margin: 0 5px 6px;
|
||||
|
||||
}
|
||||
.pure-thumb .caption p {
|
||||
margin: 0.3em 0 0;
|
||||
font-size: 75%;
|
||||
}
|
||||
.pure-thumb .caption .caption-head {
|
||||
font-weight: bold;
|
||||
margin-top: 0.3em;
|
||||
}
|
||||
|
||||
.pure-thumb-eliptical img {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.pure-thumb-rounded img {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* Badges/Pills */
|
||||
.pure-badge,
|
||||
.pure-badge-error,
|
||||
.pure-badge-warning,
|
||||
.pure-badge-success,
|
||||
.pure-badge-info,
|
||||
.pure-badge-inverse {
|
||||
padding: 0.35em 0.9em 0.35em;
|
||||
background-color: #9D988E;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-size: 11.844px;
|
||||
font-weight: bold;
|
||||
line-height: 1.2em;
|
||||
vertical-align: baseline;
|
||||
white-space: nowrap;
|
||||
border-radius: 20px;
|
||||
margin: 0.2em;
|
||||
}
|
||||
.pure-badge-error {
|
||||
background-color: #D13C38;
|
||||
}
|
||||
.pure-badge-warning {
|
||||
background-color: #E78C05;
|
||||
}
|
||||
.pure-badge-success {
|
||||
background-color: rgb(83, 180, 79);
|
||||
}
|
||||
.pure-badge-info {
|
||||
background-color: rgb(18, 169, 218);
|
||||
}
|
||||
.pure-badge-inverse {
|
||||
background-color: #4D370C;
|
||||
}
|
||||
|
||||
/* Alerts */
|
||||
.pure-alert {
|
||||
position: relative;
|
||||
margin-bottom: 1em;
|
||||
padding: 1em;
|
||||
background: #ccc;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.pure-alert label {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
/* IE7 inline-block hack */
|
||||
*zoom: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.pure-alert {
|
||||
background-color: rgb(209, 235, 238);
|
||||
color: rgb(102, 131, 145);
|
||||
}
|
||||
.pure-alert-error {
|
||||
background-color: #D13C38;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pure-alert-warning {
|
||||
background-color: rgb(250, 191, 103);
|
||||
color: rgb(151, 96, 13);
|
||||
}
|
||||
|
||||
.pure-alert-success {
|
||||
background-color: rgb(83, 180, 79);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
/* Contextual Modals */
|
||||
|
||||
.pure-popover {
|
||||
position: relative;
|
||||
width: 300px;
|
||||
background-color: #f0f1f3;
|
||||
color: #2f3034;
|
||||
padding: 15px;
|
||||
border: 1px solid #bfc0c8;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
box-padding: border-box;
|
||||
-webkit-background-clip: padding-box;
|
||||
-moz-background-clip: padding;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.pure-arrow-border, .pure-arrow {
|
||||
border-style: solid;
|
||||
border-width: 10px;
|
||||
height:0;
|
||||
width:0;
|
||||
position:absolute;
|
||||
}
|
||||
|
||||
|
||||
/* POPOVER ARROW POSITIONING BOTTOM */
|
||||
|
||||
.pure-popover.bottom .pure-arrow-border {
|
||||
border-color: #bfc0c8 transparent transparent transparent;
|
||||
bottom: -20px;
|
||||
left: 50%;
|
||||
}
|
||||
.pure-popover.bottom .pure-arrow {
|
||||
border-color: #f0f1f3 transparent transparent transparent;
|
||||
bottom:-19px;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
/* POPOVER ARROW POSITIONING TOP*/
|
||||
|
||||
.pure-popover.top .pure-arrow-border {
|
||||
border-color: transparent transparent #bfc0c8 transparent;
|
||||
top: -21px;
|
||||
left: 50%;
|
||||
}
|
||||
.pure-popover.top .pure-arrow {
|
||||
border-color: transparent transparent #f0f1f3 transparent;
|
||||
top:-20px;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
/* POPOVER ARROW POSITIONING RIGHT*/
|
||||
|
||||
.pure-popover.right .pure-arrow-border {
|
||||
border-color: transparent transparent transparent #bfc0c8;
|
||||
top: 45%;
|
||||
right: -21px;
|
||||
}
|
||||
.pure-popover.right .pure-arrow {
|
||||
border-color: transparent transparent transparent #f0f1f3;
|
||||
top:45%;
|
||||
right: -20px;
|
||||
}
|
||||
|
||||
|
||||
/* POPOVER ARROW POSITIONING LEFT*/
|
||||
|
||||
.pure-popover.left .pure-arrow-border {
|
||||
border-color: transparent #bfc0c8 transparent transparent;
|
||||
top: 45%;
|
||||
left: -21px;
|
||||
}
|
||||
.pure-popover.left .pure-arrow {
|
||||
border-color: transparent #f0f1f3 transparent transparent;
|
||||
top:45%;
|
||||
left: -20px;
|
||||
}
|
||||
|
||||
|
||||
/* BUTTON IMPROVEMENTS */
|
||||
.pure-button-block {
|
||||
display: block;
|
||||
}
|
||||
.pure-button-small {
|
||||
padding: .6em 2em .65em;
|
||||
font-size:70%;
|
||||
}
|
||||
.pure-button-large {
|
||||
padding: .8em 5em .9em;
|
||||
font-size:110%;
|
||||
}
|
||||
.pure-button-selected {
|
||||
background-color: #345fcb;
|
||||
color: #fff;
|
||||
}
|
||||
.pure-button-secondary {
|
||||
background: rgb(161, 195, 238);
|
||||
color: rgb(26, 88, 122);
|
||||
}
|
||||
.pure-button-error {
|
||||
background: rgb(214, 86, 75);
|
||||
color: white;
|
||||
}
|
||||
.pure-button-success {
|
||||
background: rgb(54, 197, 71);
|
||||
color: white;
|
||||
}
|
||||
.pure-button-warning {
|
||||
background: rgb(255, 163, 0);
|
||||
color: white;
|
||||
}
|
||||
|
11
tpl/myShaarli/css/pure.min.css
vendored
11
tpl/myShaarli/css/pure.min.css
vendored
File diff suppressed because one or more lines are too long
2735
tpl/myShaarli/css/shaarli.min.css
vendored
2735
tpl/myShaarli/css/shaarli.min.css
vendored
File diff suppressed because one or more lines are too long
|
@ -6,12 +6,25 @@
|
|||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-1 pure-alert pure-alert-success tag-sort">
|
||||
<a href="{$base_path}/daily?day">{'Daily'|t}</a>
|
||||
<a href="{$base_path}/daily?week">{'Weekly'|t}</a>
|
||||
<a href="{$base_path}/daily?month">{'Monthly'|t}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<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" id="daily">
|
||||
<h2 class="window-title">
|
||||
{'The Daily Shaarli'|t}
|
||||
<a href="?do=dailyrss" title="{'1 RSS entry per day'|t}"><i class="fa fa-rss"></i></a>
|
||||
{$localizedType} Shaarli
|
||||
<a href="{$base_path}/daily-rss?{$type}"
|
||||
title="{function="t('1 RSS entry per :type', '', 1, 'shaarli', [':type' => t($type)])"}"
|
||||
>
|
||||
<i class="fa fa-rss"></i>
|
||||
</a>
|
||||
</h2>
|
||||
|
||||
<div id="plugin_zone_start_daily" class="plugin_zone">
|
||||
|
@ -25,31 +38,28 @@
|
|||
<div class="pure-g">
|
||||
<div class="pure-u-lg-1-3 pure-u-1 center">
|
||||
{if="$previousday"}
|
||||
<a href="?do=daily&day={$previousday}">
|
||||
<a href="{$base_path}/daily?{$type}={$previousday}">
|
||||
<i class="fa fa-arrow-left"></i>
|
||||
{'Previous day'|t}
|
||||
{function="t('Previous :type', '', 1, 'shaarli', [':type' => t($type)], true)"}
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="daily-desc pure-u-lg-1-3 pure-u-1 center">
|
||||
{'All links of one day in a single page.'|t}
|
||||
{function="t('All links of one :type in a single page.', '', 1, 'shaarli', [':type' => t($type)])"}
|
||||
</div>
|
||||
<div class="pure-u-lg-1-3 pure-u-1 center">
|
||||
{if="$nextday"}
|
||||
<a href="?do=daily&day={$nextday}">
|
||||
{'Next day'|t}
|
||||
<a href="{$base_path}/daily?{$type}={$nextday}">
|
||||
{function="t('Next :type', '', 1, 'shaarli', [':type' => t($type)], true)"}
|
||||
<i class="fa fa-arrow-right"></i>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="window-subtitle">
|
||||
{if="!empty($dayDesc)"}
|
||||
{$dayDesc} -
|
||||
{/if}
|
||||
{function="format_date($dayDate, false)"}
|
||||
</h3>
|
||||
<h3 class="window-subtitle">
|
||||
{$dayDesc}
|
||||
</h3>
|
||||
|
||||
<div id="plugin_zone_about_daily" class="plugin_zone">
|
||||
{loop="$daily_about_plugin"}
|
||||
|
@ -69,21 +79,23 @@
|
|||
{$link=$value}
|
||||
<div class="daily-entry">
|
||||
<div class="daily-entry-title center">
|
||||
<a href="?{$link.shorturl}" title="{'Permalink'|t}">
|
||||
<a href="{$base_path}/shaare/{$link.shorturl}" title="{'Permalink'|t}">
|
||||
<i class="fa fa-link"></i>
|
||||
</a>
|
||||
<a href="{$link.real_url}">{$link.title}</a>
|
||||
</div>
|
||||
{if="$thumbnails_enabled && !empty($link.thumbnail)"}
|
||||
<div class="daily-entry-thumbnail">
|
||||
<img data-src="{$link.thumbnail}#" class="b-lazy"
|
||||
<img data-src="{$root_path}/{$link.thumbnail}#" class="b-lazy"
|
||||
src=""
|
||||
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
|
||||
</div>
|
||||
{/if}
|
||||
<div class="daily-entry-description">{$link.formatedDescription}</div>
|
||||
{if="$link.tags"}
|
||||
<div class="daily-entry-tags center">
|
||||
{loop="link.taglist"}
|
||||
<span class="label label-tag" title="Add tag">
|
||||
<span class="label label-tag">
|
||||
{$value}
|
||||
</span>
|
||||
{/loop}
|
||||
|
@ -114,7 +126,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
<script src="js/thumbnails.min.js?v={$version_hash}"></script>
|
||||
<script src="{$asset_path}/js/thumbnails.min.js?v={$version_hash}#"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -1,16 +1,35 @@
|
|||
<item>
|
||||
<title>{$title} - {function="strftime('%A %e %B %Y', $daydate)"}</title>
|
||||
<guid>{$absurl}</guid>
|
||||
<link>{$absurl}</link>
|
||||
<pubDate>{$rssdate}</pubDate>
|
||||
<description><![CDATA[
|
||||
{loop="links"}
|
||||
<h3><a href="{$value.url}">{$value.title}</a></h3>
|
||||
<small>{if="!$hide_timestamps"}{function="strftime('%c', $value.timestamp)"} - {/if}{if="$value.tags"}{$value.tags}{/if}<br>
|
||||
{$value.url}</small><br>
|
||||
{if="$value.thumbnail"}<img src="{$index_url}{$value.thumbnail}#" alt="thumbnail" />{/if}<br>
|
||||
{if="$value.description"}{$value.formatedDescription}{/if}
|
||||
<br><br><hr>
|
||||
{/loop}
|
||||
]]></description>
|
||||
</item>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>{$localizedType} - {$title}</title>
|
||||
<link>{$index_url}</link>
|
||||
<description>{function="t('All links of one :type in a single page.', '', 1, 'shaarli', [':type' => t($type)])"}</description>
|
||||
<language>{$language}</language>
|
||||
<copyright>{$index_url}</copyright>
|
||||
<generator>Shaarli</generator>
|
||||
|
||||
{loop="$days"}
|
||||
<item>
|
||||
<title>{$value.date_human} - {$title}</title>
|
||||
<guid>{$value.absolute_url}</guid>
|
||||
<link>{$value.absolute_url}</link>
|
||||
<pubDate>{$value.date_rss}</pubDate>
|
||||
<description><![CDATA[
|
||||
{loop="$value.links"}
|
||||
<h3><a href="{$value.url}">{$value.title}</a></h3>
|
||||
<small>
|
||||
{if="!$hide_timestamps"}{$value.created|format_date} — {/if}
|
||||
<a href="{$index_url}shaare/{$value.shorturl}">{'Permalink'|t}</a>
|
||||
{if="$value.tags"} — {$value.tags}{/if}
|
||||
<br>
|
||||
{$value.url}
|
||||
</small><br>
|
||||
{if="$value.thumbnail"}<img src="{$index_url}{$value.thumbnail}#" alt="thumbnail" />{/if}<br>
|
||||
{if="$value.description"}{$value.description}{/if}
|
||||
<br><hr>
|
||||
{/loop}
|
||||
]]></description>
|
||||
</item>
|
||||
{/loop}
|
||||
</channel>
|
||||
</rss><!-- Cached version of {$page_url} -->
|
||||
|
|
33
tpl/myShaarli/editlink.batch.html
Normal file
33
tpl/myShaarli/editlink.batch.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
<!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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="page.header"}
|
||||
|
||||
<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}
|
||||
|
||||
<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>
|
|
@ -1,3 +1,5 @@
|
|||
{$batchId=isset($batchId) ? $batchId : ''}
|
||||
{if="empty($batch_mode)"}
|
||||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
|
@ -5,51 +7,80 @@
|
|||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
<div id="editlinkform" class="edit-link-container" class="pure-g">
|
||||
{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" class="page-form pure-u-lg-3-5 pure-u-22-24 page-form page-form-light">
|
||||
<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' : ''}
|
||||
|
||||
<h2 class="window-title">
|
||||
{if="!$link_is_new"}{'Edit Shaare'|t}{else}{'New Shaare'|t}{/if}
|
||||
</h2>
|
||||
<input type="hidden" name="lf_linkdate" value="{$link.linkdate}">
|
||||
{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>
|
||||
<label for="lf_url">{'URL'|t}</label>
|
||||
<label for="lf_url{$batchId}">{'URL'|t}</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" name="lf_url" id="lf_url" value="{$link.url}" class="lf_input autofocus">
|
||||
<input type="text" name="lf_url" id="lf_url{$batchId}" value="{$link.url}" class="lf_input">
|
||||
</div>
|
||||
<div>
|
||||
<label for="lf_title">{'Title'|t}</label>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" name="lf_title" id="lf_title" value="{$link.title}" class="lf_input autofocus">
|
||||
<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>
|
||||
</div>
|
||||
<div>
|
||||
<label for="lf_description">{'Description'|t}</label>
|
||||
<label for="lf_tags{$batchId}">{'Tags'|t}</label>
|
||||
</div>
|
||||
<div>
|
||||
<textarea name="lf_description" id="lf_description" class="autofocus">{$link.description}</textarea>
|
||||
</div>
|
||||
<div>
|
||||
<label for="lf_tags">{'Tags'|t}</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="text" name="lf_tags" id="lf_tags" value="{$link.tags}" class="lf_input autofocus"
|
||||
<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>
|
||||
<input type="checkbox" name="lf_private" id="lf_private"
|
||||
{if="($link_is_new && $default_private_links || $link.private == true)"}
|
||||
<input type="checkbox" name="lf_private" id="lf_private{$batchId}"
|
||||
{if="$link.private === true"}
|
||||
checked="checked"
|
||||
{/if}>
|
||||
<label for="lf_private">{'Private'|t}</label>
|
||||
<label for="lf_private{$batchId}">{'Private'|t}</label>
|
||||
</div>
|
||||
|
||||
{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}">
|
||||
{'Markdown syntax'|t}
|
||||
</a>.
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div id="editlink-plugins">
|
||||
{loop="$edit_link_plugin"}
|
||||
{$value}
|
||||
|
@ -58,10 +89,17 @@
|
|||
|
||||
|
||||
<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.'}"
|
||||
>
|
||||
{'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="?delete_link&lf_linkdate={$link.id}&token={$token}"
|
||||
<a href="{$base_path}/admin/shaare/delete?id={$link.id}&token={$token}"
|
||||
title="" name="delete_link" class="button button-red confirm-delete">
|
||||
{'Delete'|t}
|
||||
</a>
|
||||
|
@ -69,11 +107,16 @@
|
|||
</div>
|
||||
|
||||
<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="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}
|
||||
|
|
26
tpl/myShaarli/error.html
Normal file
26
tpl/myShaarli/error.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
<div id="pageheader">
|
||||
{include="page.header"}
|
||||
<div id="pageError" class="page-error-container center">
|
||||
<h2>{$message}</h2>
|
||||
|
||||
<img src="{$asset_path}/img/sad_star.png#" alt="">
|
||||
|
||||
{if="!empty($text)"}
|
||||
<p>{$text}</p>
|
||||
{/if}
|
||||
|
||||
{if="!empty($stacktrace)"}
|
||||
<pre>
|
||||
{$stacktrace}
|
||||
</pre>
|
||||
{/if}
|
||||
</div>
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
|
@ -5,6 +5,6 @@
|
|||
Do Not Edit! -->{ignore}The RainTPL loop is formatted to avoid generating extra newlines{/ignore}
|
||||
<TITLE>{$pagetitle}</TITLE>
|
||||
<H1>Shaarli export of {$selection} bookmarks on {$date}</H1>
|
||||
<DL><p>{loop="links"}
|
||||
<DT><A HREF="{$value.url}" ADD_DATE="{$value.timestamp}" PRIVATE="{$value.private}" TAGS="{$value.taglist}">{$value.title}</A>{if="$value.description"}{$eol}<DD>{$value.description}{/if}{/loop}
|
||||
<DL><p>{loop="links"}{$private=intval($value.private)}
|
||||
<DT><A HREF="{$value.url}" ADD_DATE="{$value.timestamp}" {if="$value.updated_timestamp"}LAST_MODIFIED="{$value.updated_timestamp}" {/if}PRIVATE="{$private}" TAGS="{$value.taglist}">{$value.title}</A>{if="$value.description"}{$eol}<DD>{$value.description}{/if}{/loop}
|
||||
</DL><p>
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
<form method="GET" action="#" name="exportform" id="exportform">
|
||||
<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="do" value="export">
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
|
||||
<div class="pure-g">
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
<updated>{$last_update}</updated>
|
||||
{/if}
|
||||
<link rel="self" href="{$self_link}#" />
|
||||
{loop="$plugins_feed_header"}
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="{$index_url}open-search#"
|
||||
title="Shaarli search - {$shaarlititle}" />
|
||||
{loop="$feed_plugins_header"}
|
||||
{$value}
|
||||
{/loop}
|
||||
<author>
|
||||
<name>{$index_url}</name>
|
||||
<name>{$pagetitle}</name>
|
||||
<uri>{$index_url}</uri>
|
||||
</author>
|
||||
<id>{$index_url}</id>
|
||||
|
@ -28,7 +30,7 @@
|
|||
<published>{$value.pub_iso_date}</published>
|
||||
<updated>{$value.up_iso_date}</updated>
|
||||
{/if}
|
||||
<content type="html" xml:lang="{$language}"><![CDATA[{$value.description}]]> <![CDATA[{$value.permalink}]]></content>
|
||||
<content type="html" xml:lang="{$language}"><![CDATA[{$value.description}]]></content>
|
||||
{loop="$value.taglist"}
|
||||
<category scheme="{$index_url}?searchtags=" term="{$value|strtolower}" label="{$value}" />
|
||||
{/loop}
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
<language>{$language}</language>
|
||||
<copyright>{$index_url}</copyright>
|
||||
<generator>Shaarli</generator>
|
||||
<atom:link rel="self" href="{$self_link}" />
|
||||
{loop="$plugins_feed_header"}
|
||||
<atom:link rel="self" href="{$self_link}" />
|
||||
<atom:link rel="search" type="application/opensearchdescription+xml" href="{$index_url}open-search#"
|
||||
title="Shaarli search - {$shaarlititle}" />
|
||||
{loop="$feed_plugins_header"}
|
||||
{$value}
|
||||
{/loop}
|
||||
{loop="$links"}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load diff
Before Width: | Height: | Size: 434 KiB |
2849
tpl/myShaarli/img/forkawesome-webfont.svg
Normal file
2849
tpl/myShaarli/img/forkawesome-webfont.svg
Normal file
File diff suppressed because it is too large
Load diff
After Width: | Height: | Size: 470 KiB |
|
@ -1,12 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
<form method="POST" action="?do=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">
|
||||
|
@ -69,7 +69,7 @@
|
|||
</div>
|
||||
<div class="pure-u-lg-2-3 pure-u-1">
|
||||
<div class="form-input">
|
||||
<input type="text" name="default_tags" id="default_tags" placeholder="{'Tag'|t}">
|
||||
<input type="text" name="default_tags" id="default_tags" aria-label="{'Tag'|t}" placeholder="{'Tag'|t}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,19 +3,40 @@
|
|||
<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}?do=atom{$searchcrits}#" title="ATOM Feed" />
|
||||
<link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" />
|
||||
<link href="img/favicon_64.png" rel="shortcut icon" type="image/png" />
|
||||
<link type="text/css" rel="stylesheet" href="css/pure.min.css?v={$version_hash}" />
|
||||
<link type="text/css" rel="stylesheet" href="css/grids-responsive.min.css?v={$version_hash}">
|
||||
<link type="text/css" rel="stylesheet" href="css/pure-extras.css?v={$version_hash}">
|
||||
<link type="text/css" rel="stylesheet" href="css/fork-awesome.min.css?v={$version_hash}" />
|
||||
<link type="text/css" rel="stylesheet" href="css/awesomplete.css?v={$version_hash}" />
|
||||
<link type="text/css" rel="stylesheet" href="css/myShaarli.css?v={$version_hash}" />
|
||||
<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}#" />
|
||||
<link type="text/css" rel="stylesheet" href="{$asset_path}/css/myShaarli.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}
|
||||
{loop="$plugins_includes.css_files"}
|
||||
<link type="text/css" rel="stylesheet" href="{$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="data/user.css#" />
|
||||
<link type="text/css" rel="stylesheet" href="{$root_path}/data/user.css#" />
|
||||
{/if}
|
||||
<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}" />
|
||||
{$ogDescription=isset($link.description_src) ? $link.description_src : $link.description}
|
||||
<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}" />
|
||||
{/if}
|
||||
{if="!$hide_timestamps || $is_logged_in"}
|
||||
<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)}" />
|
||||
{/if}
|
||||
{/if}
|
||||
{loop="link.taglist"}
|
||||
<meta property="article:tag" content="{$value}" />
|
||||
{/loop}
|
||||
{/if}
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="?do=opensearch#" title="Shaarli search - {$shaarlititle}"/>
|
|
@ -10,14 +10,14 @@
|
|||
{$ratioLabelMobile='7-8'}
|
||||
{$ratioInputMobile='1-8'}
|
||||
|
||||
<form method="POST" action="#" name="installform" id="installform">
|
||||
<form method="POST" action="{$base_path}/install" name="installform" id="installform">
|
||||
<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-form-complete">
|
||||
<h2 class="window-title">{'Install Shaarli'|t}</h2>
|
||||
|
||||
<div class="center">
|
||||
{'It looks like it\'s the first time you run Shaarli. Please configure it.'|t}
|
||||
<p>{'It looks like it\'s the first time you run Shaarli. Please configure it.'|t}</p>
|
||||
</div>
|
||||
|
||||
<div class="pure-g">
|
||||
|
@ -30,7 +30,7 @@
|
|||
</div>
|
||||
<div class="pure-u-lg-{$ratioInput} pure-u-1">
|
||||
<div class="form-input">
|
||||
<input type="text" name="setlogin" id="username">
|
||||
<input type="text" name="setlogin" id="username" autocapitalize="off">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -69,7 +69,7 @@
|
|||
<div class="pure-u-lg-{$ratioLabel} pure-u-1">
|
||||
<div class="form-label">
|
||||
<label for="language">
|
||||
<span class="label-name">{'Language'|t}</span>
|
||||
<span class="label-name">{'Languages'|t}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -127,7 +127,7 @@
|
|||
<div class="pure-u-lg-{$ratioLabel} pure-u-7-8">
|
||||
<div class="form-label">
|
||||
<label for="update">
|
||||
<span class="label-name">{'Check updates'|t}</span><br>
|
||||
<span class="label-name">{'Check for updates'|t}</span><br>
|
||||
<span class="label-desc">
|
||||
{'Notify me when a new release is ready'|t}
|
||||
</span>
|
||||
|
@ -163,6 +163,16 @@
|
|||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<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-form-complete">
|
||||
<h2 class="window-title">{'Server requirements'|t}</h2>
|
||||
|
||||
{include="server.requirements"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
|
|
1
tpl/myShaarli/js/markdown.min.js
vendored
Normal file
1
tpl/myShaarli/js/markdown.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
!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){}});
|
2
tpl/myShaarli/js/metadata.min.js
vendored
Normal file
2
tpl/myShaarli/js/metadata.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
tpl/myShaarli/js/metadata.min.js.LICENSE.txt
Normal file
1
tpl/myShaarli/js/metadata.min.js.LICENSE.txt
Normal file
|
@ -0,0 +1 @@
|
|||
/*! https://mths.be/he v1.2.0 by @mathias | MIT license */
|
2
tpl/myShaarli/js/pluginsadmin.min.js
vendored
2
tpl/myShaarli/js/pluginsadmin.min.js
vendored
|
@ -1 +1 @@
|
|||
(function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={i:d,l:!1,exports:{}};return a[d].call(e.exports,e,e.exports,b),e.l=!0,e.exports}var c={};return b.m=a,b.c=c,b.d=function(a,c,d){b.o(a,c)||Object.defineProperty(a,c,{configurable:!1,enumerable:!0,get:d})},b.n=function(a){var c=a&&a.__esModule?function(){return a['default']}:function(){return a};return b.d(c,'a',c),c},b.o=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)},b.p='',b(b.s=3)})({3:function(){'use strict';function a(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b<a.length;b++)c[b]=a[b];return c}return Array.from(a)}function b(a,b){var c=a.getAttribute('data-line');a.setAttribute('data-order',b);var d=document.querySelector('[name="order_'+c+'"]');d.setAttribute('value',b)}function c(a,c){var d=parseInt(a,10)+c,e=document.querySelectorAll('[data-order="'+a+'"]'),f=document.querySelectorAll('[data-order="'+d+'"]');0<c&&(e=[].slice.call(e).reverse());for(var g,h=0;h<e.length;h+=1){g=f[0].parentNode,b(e[h],d),b(f[h],parseInt(a,10));var i=0>c?f[0]:f[f.length-1].nextSibling;g.insertBefore(e[h],i)}}function d(a){0!==a&&c(a,-1)}function e(a){var b=parseInt(document.querySelector('[data-order]:last-child').getAttribute('data-order'),10);a!==b&&c(a,1)}(function(){var b=document.querySelectorAll('.order');[].concat(a(b)).forEach(function(a){a.addEventListener('click',function(a){a.preventDefault(),a.target.classList.contains('order-up')?d(parseInt(a.target.parentNode.parentNode.getAttribute('data-order'),10)):a.target.classList.contains('order-down')&&e(parseInt(a.target.parentNode.parentNode.getAttribute('data-order'),10))})})})()}});
|
||||
!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))}))}))}});
|
1
tpl/myShaarli/js/shaare_batch.min.js
vendored
Normal file
1
tpl/myShaarli/js/shaare_batch.min.js
vendored
Normal file
|
@ -0,0 +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(),"/")}))}))}))}()}});
|
3
tpl/myShaarli/js/shaarli.min.js
vendored
3
tpl/myShaarli/js/shaarli.min.js
vendored
File diff suppressed because one or more lines are too long
1
tpl/myShaarli/js/shaarli.min.js.LICENSE.txt
Normal file
1
tpl/myShaarli/js/shaarli.min.js.LICENSE.txt
Normal file
|
@ -0,0 +1 @@
|
|||
/*! https://mths.be/he v1.2.0 by @mathias | MIT license */
|
7
tpl/myShaarli/js/thumbnails.min.js
vendored
7
tpl/myShaarli/js/thumbnails.min.js
vendored
File diff suppressed because one or more lines are too long
5
tpl/myShaarli/js/thumbnails.min.js.LICENSE.txt
Normal file
5
tpl/myShaarli/js/thumbnails.min.js.LICENSE.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
/*!
|
||||
hey, [be]Lazy.js - v1.8.2 - 2016.10.25
|
||||
A fast, small and dependency free lazy load script (https://github.com/dinbror/blazy)
|
||||
(c) Bjoern Klinggaard - @bklinggaard - http://dinbror.dk/blazy
|
||||
*/
|
2
tpl/myShaarli/js/thumbnails_update.min.js
vendored
2
tpl/myShaarli/js/thumbnails_update.min.js
vendored
|
@ -1 +1 @@
|
|||
(function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={i:d,l:!1,exports:{}};return a[d].call(e.exports,e,e.exports,b),e.l=!0,e.exports}var c={};return b.m=a,b.c=c,b.d=function(a,c,d){b.o(a,c)||Object.defineProperty(a,c,{configurable:!1,enumerable:!0,get:d})},b.n=function(a){var c=a&&a.__esModule?function(){return a['default']}:function(){return a};return b.d(c,'a',c),c},b.o=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)},b.p='',b(b.s=2)})({2:function(){'use strict';function a(b,c,d){var e=new XMLHttpRequest;e.open('POST','?do=ajax_thumb_update'),e.setRequestHeader('Content-Type','application/x-www-form-urlencoded'),e.responseType='json',e.onload=function(){if(200!==e.status)alert('An error occurred. Return code: '+e.status);else{var f=e.response;c+=1,d.progressBar.style.width=100*c/b.length+'%',d.current.innerHTML=c,d.title.innerHTML=f.title,!1!==f.thumbnail&&(d.thumbnail.innerHTML='<img src="'+f.thumbnail+'">'),c<b.length&&a(b,c,d)}},e.send('id='+b[c])}(function(){var b=document.getElementsByName('ids')[0].value.split(','),c={progressBar:document.querySelector('.progressbar > div'),current:document.querySelector('.progress-current'),thumbnail:document.querySelector('.thumbnail-placeholder'),title:document.querySelector('.thumbnail-link-title')};a(b,0,c)})()}});
|
||||
!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")})}});
|
|
@ -19,19 +19,19 @@
|
|||
<div id="search-linklist" class="searchform-block search-linklist">
|
||||
|
||||
<form method="GET" class="pure-form searchform" name="searchform">
|
||||
<input type="text" tabindex="1" name="searchterm" class="searchterm" placeholder="{'Search text'|t}"
|
||||
<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" tabindex="2" name="searchtags" class="searchtags" placeholder="{'Filter by tag'|t}"
|
||||
<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"><i class="fa fa-search"></i></button>
|
||||
<button type="submit" class="search-button" aria-label="{'Search'|t}"><i class="fa fa-search" aria-hidden="true"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
@ -90,11 +90,13 @@
|
|||
{'for'|t} <em><strong>{$search_term}</strong></em>
|
||||
{/if}
|
||||
{if="!empty($search_tags)"}
|
||||
{$exploded_tags=explode(' ', $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="?removetag={function="urlencode($value)"}">{$value}<span class="remove"><i class="fa fa-times" aria-hidden="true"></i></span></a>
|
||||
<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}
|
||||
|
@ -127,17 +129,22 @@
|
|||
{$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">
|
||||
{if="!empty($value.thumbnail)"}
|
||||
<div class="linklist-item-thumbnail" style="width:{$thumbnails_width}px;height:{$thumbnails_height}px;">
|
||||
{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">
|
||||
<a href="{$value.real_url}">
|
||||
{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 data-src="{$value.thumbnail}#" class="b-lazy"
|
||||
src=""
|
||||
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
|
||||
|
@ -146,32 +153,29 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
{if="$is_logged_in"}
|
||||
<div class="linklist-item-editbuttons">
|
||||
<span class="linklist-item-infos-controls-item ctrl-edit">
|
||||
<a href="?edit_link={$value.id}" title="{$strEdit}"><i class="fa fa-pencil-square-o edit-link"></i></a>
|
||||
</span>
|
||||
{if="$value.private"}
|
||||
<span class="label label-private">{$strPrivate}</span>
|
||||
{/if}
|
||||
{if="$value.sticky"}
|
||||
<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}
|
||||
</div>
|
||||
{/if}
|
||||
{if="$value.private"}
|
||||
<span class="label label-private">{$strPrivate}</span>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<h2>
|
||||
<a href="{$value.real_url}">
|
||||
<a href="{$value.real_url}" class="linklist-real-url">
|
||||
{if="strpos($value.url, $value.shorturl) === false"}
|
||||
<i class="fa fa-external-link"></i>
|
||||
<i class="fa fa-external-link" aria-hidden="true"></i>
|
||||
{else}
|
||||
<i class="fa fa-sticky-note"></i>
|
||||
<i class="fa fa-sticky-note" aria-hidden="true"></i>
|
||||
{/if}
|
||||
|
||||
<span class="linklist-link">
|
||||
<img data-src="{$value.favicon}#" class="b-lazy"
|
||||
src=""
|
||||
alt="fav" width="16px" height="16px" /> {$value.title}</span>
|
||||
<span class="linklist-link">{$value.title_html}</span>
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
|
@ -185,11 +189,11 @@
|
|||
<div class="linklist-item-infos clear">
|
||||
{if="$value.tags"}
|
||||
<div class="linklist-item-tags">
|
||||
<i class="fa fa-tags"></i>
|
||||
<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="?addtag={$value|urlencode}">{$value}</a>
|
||||
<a href="{$base_path}/add-tag/{$value1.taglist_urlencoded.$key2}">{$value1.taglist_html.$key2}</a>
|
||||
</span>
|
||||
{if="$tag_counter - 1 != $counter"}·{/if}
|
||||
{/loop}
|
||||
|
@ -199,20 +203,33 @@
|
|||
<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">
|
||||
<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="?do=pin&id={$value.id}&token={$token}"
|
||||
<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}
|
||||
<a href="?{$value.shorturl}" title="{$strPermalink}">
|
||||
<a href="{$base_path}/shaare/{$value.shorturl}" title="{$strPermalink}">
|
||||
{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"></i>
|
||||
<i class="fa fa-clock-o" aria-hidden="true"></i>
|
||||
{$value.created|format_date}
|
||||
{if="$value.updated_timestamp"}*{/if}
|
||||
·
|
||||
|
@ -221,6 +238,12 @@
|
|||
{$strPermalinkLc}
|
||||
</a>
|
||||
|
||||
{if="$is_logged_in && $value.private"}
|
||||
<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)"}
|
||||
·
|
||||
|
@ -234,10 +257,12 @@
|
|||
</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}" title="{$value.title}">
|
||||
<i class="fa fa-link" aria-hidden="true"></i> {$value.url}
|
||||
<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>
|
||||
<a href="#" aria-label="{$strFold}" title="{$strFold}" class="fold-button"><i class="fa fa-chevron-up" aria-hidden="true"></i></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)"}
|
||||
|
@ -247,6 +272,25 @@
|
|||
{if="$link_plugin_counter - 1 != $counter"}·{/if}
|
||||
{/loop}
|
||||
{/if}
|
||||
{if="$is_logged_in"}
|
||||
·
|
||||
<a href="{$base_path}/admin/shaare/delete?id={$value.id}&token={$token}" aria-label="{$strDelete}"
|
||||
title="{$strDelete}" class="delete-link confirm-delete">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
</a>
|
||||
·
|
||||
<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>
|
||||
·
|
||||
<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>
|
||||
|
@ -270,6 +314,7 @@
|
|||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
<script src="js/thumbnails.min.js?v={$version_hash}"></script>
|
||||
<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>
|
||||
|
|
|
@ -1,24 +1,29 @@
|
|||
<div class="linklist-paging">
|
||||
<div class="paging pure-g">
|
||||
<div class="linklist-filters pure-u-1-3">
|
||||
{if="$is_logged_in or !empty($action_plugin)"}
|
||||
<span class="linklist-filters-text pure-u-0 pure-u-lg-visible">
|
||||
{'Filters'|t}
|
||||
</span>
|
||||
{if="$is_logged_in"}
|
||||
<a href="?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="?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>
|
||||
{/if}
|
||||
<a href="?untaggedonly" 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>
|
||||
<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>
|
||||
<span class="linklist-filters-text pure-u-0 pure-u-lg-visible">
|
||||
{'Filters'|t}
|
||||
</span>
|
||||
{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>
|
||||
{/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>
|
||||
{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>
|
||||
{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'}
|
||||
|
@ -50,14 +55,19 @@
|
|||
|
||||
<div class="linksperpage pure-u-1-3">
|
||||
<div class="pure-u-0 pure-u-lg-visible">{'Links per page'|t}</div>
|
||||
<a href="?linksperpage=20">20</a>
|
||||
<a href="?linksperpage=50">50</a>
|
||||
<a href="?linksperpage=100">100</a>
|
||||
<form method="GET" class="pure-u-0 pure-u-lg-visible">
|
||||
<input type="text" name="linksperpage" placeholder="133">
|
||||
<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>
|
||||
<i class="fa fa-chevron-up" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,46 +5,33 @@
|
|||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
{if="!$user_can_login"}
|
||||
<div class="pure-g pure-alert pure-alert-error pure-alert-closable center">
|
||||
<div class="pure-u-2-24"></div>
|
||||
<div class="pure-u-20-24">
|
||||
<p>{'You have been banned after too many failed login attempts. Try again later.'|t}</p>
|
||||
</div>
|
||||
<div class="pure-u-2-24">
|
||||
<i class="fa fa-times pure-alert-close"></i>
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
|
||||
<div id="login-form" class="page-form page-form-light pure-u-lg-1-3 pure-u-22-24 login-form-container">
|
||||
<form method="post" name="loginform">
|
||||
<h2 class="window-title">{'Login'|t}</h2>
|
||||
<div>
|
||||
<input type="text" name="login" aria-label="{'Username'|t}" placeholder="{'Username'|t}"
|
||||
{if="!empty($username)"}value="{$username}"{/if} class="autofocus" autocapitalize="off">
|
||||
</div>
|
||||
<div>
|
||||
<input type="password" name="password" aria-label="{'Password'|t}" placeholder="{'Password'|t}" class="autofocus">
|
||||
</div>
|
||||
<div class="remember-me">
|
||||
<input type="checkbox" name="longlastingsession" id="longlastingsessionform"
|
||||
{if="$remember_user_default"}checked="checked"{/if}>
|
||||
<label for="longlastingsessionform">{'Remember me'|t}</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="submit" value="{'Login'|t}" class="bigbutton">
|
||||
</div>
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
{if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if}
|
||||
</form>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-3 pure-u-1-8"></div>
|
||||
</div>
|
||||
{else}
|
||||
<div class="pure-g">
|
||||
<div class="pure-u-lg-1-3 pure-u-1-24"></div>
|
||||
<div id="login-form" class="page-form page-form-light pure-u-lg-1-3 pure-u-22-24 login-form-container">
|
||||
<form method="post" name="loginform">
|
||||
<h2 class="window-title">{'Login'|t}</h2>
|
||||
<div>
|
||||
<input type="text" name="login" aria-label="{'Username'|t}" placeholder="{'Username'|t}"
|
||||
{if="!empty($username)"}value="{$username}"{/if} class="autofocus">
|
||||
</div>
|
||||
<div>
|
||||
<input type="password" name="password" aria-label="{'Password'|t}" placeholder="{'Password'|t}" class="autofocus">
|
||||
</div>
|
||||
<div class="remember-me">
|
||||
<input type="checkbox" name="longlastingsession" id="longlastingsessionform"
|
||||
{if="$remember_user_default"}checked="checked"{/if}>
|
||||
<label for="longlastingsessionform">{'Remember me'|t}</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="submit" value="{'Login'|t}" class="bigbutton">
|
||||
</div>
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
{if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if}
|
||||
</form>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-3 pure-u-1-8"></div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<ShortName>Shaarli search - {$pagetitle}</ShortName>
|
||||
<Description>Shaarli search - {$pagetitle}</Description>
|
||||
<Url type="text/html" template="{$serverurl}?searchterm={searchTerms}" />
|
||||
<Url type="application/atom+xml" template="{$serverurl}?do=atom&searchterm={searchTerms}"/>
|
||||
<Url type="application/rss+xml" template="{$serverurl}?do=rss&searchterm={searchTerms}"/>
|
||||
<Url type="application/atom+xml" template="{$serverurl}feed/atom?searchterm={searchTerms}"/>
|
||||
<Url type="application/rss+xml" template="{$serverurl}feed/rss?searchterm={searchTerms}"/>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<Developer>Shaarli Community - https://github.com/shaarli/Shaarli/</Developer>
|
||||
<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAHRklE
|
||||
|
|
|
@ -1,42 +1,46 @@
|
|||
</div>
|
||||
</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>
|
||||
<i class="fa fa-shaarli" aria-hidden="true"></i>
|
||||
<strong><a href="https://github.com/shaarli/Shaarli">Shaarli</a></strong>
|
||||
{if="$is_logged_in===true"}
|
||||
{$version}
|
||||
{/if}
|
||||
·
|
||||
{'The personal, minimalist, super-fast, database free, bookmarking service'|t} {'by the Shaarli community'|t} ·
|
||||
<a href="doc/html/index.html" rel="nofollow">{'Documentation'|t}</a>
|
||||
<a href="{$root_path}/doc/html/index.html" rel="nofollow">{'Documentation'|t}</a>
|
||||
<br>Theme <a href="https://forge.leslibres.org/Knah-Tsaeb/MyShaarli">MyShaarli </a>by Knah Tsaeb
|
||||
{loop="$plugins_footer.text"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</footer>
|
||||
</footer>
|
||||
<div class="pure-u-2-24"></div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="token" value="{$token}" id="token" />
|
||||
|
||||
{loop="$plugins_footer.endofpage"}
|
||||
{$value}
|
||||
{/loop}
|
||||
|
||||
{loop="$plugins_footer.js_files"}
|
||||
<script src="{$value}#"></script>
|
||||
<script src="{$root_path}/{$value}#"></script>
|
||||
{/loop}
|
||||
|
||||
<div id="js-translations" class="hidden">
|
||||
<div id="js-translations" class="hidden" 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>
|
||||
<span id="translation-expand-all">{'Expand all'|t}</span>
|
||||
<span id="translation-delete-link">{'Are you sure you want to delete this link?'|t}</span>
|
||||
<span id="translation-delete-tag">{'Are you sure you want to delete this tag?'|t}</span>
|
||||
<span id="translation-shaarli-desc">
|
||||
{'The personal, minimalist, super-fast, database free, bookmarking service'|t} {'by the Shaarli community'|t}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<script src="js/shaarli.min.js?v={$version_hash}"></script>
|
||||
<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>
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
<div class="shaarli-menu pure-g" id="shaarli-menu">
|
||||
<div class="pure-u-lg-0 pure-u-1">
|
||||
<div class="pure-menu">
|
||||
<header role="banner">
|
||||
<a href="{$titleLink}" class="pure-menu-link shaarli-title" id="shaarli-title-mobile">
|
||||
<img src="img/favicon_32.png" width="16" height="16" class="head-logo" alt="logo" />
|
||||
<header role="banner">
|
||||
<a href="{$titleLink}" class="pure-menu-link shaarli-title" id="shaarli-title-mobile">
|
||||
<img src="{$asset_path}/img/favicon_16.png#" width="16" height="16" class="head-logo" alt="logo" />
|
||||
{$shaarlititle}
|
||||
</a>
|
||||
</header>
|
||||
<a href="#" class="menu-toggle" id="menu-toggle" aria-label="Menu"><s class="bar" aria-hidden="true"></s><s class="bar" aria-hidden="true"></s></a>
|
||||
</header>
|
||||
<a href="#" class="menu-toggle" id="menu-toggle" aria-label="{'Menu'|t}"><s class="bar" aria-hidden="true"></s><s class="bar" aria-hidden="true"></s></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1">
|
||||
<div class="pure-menu menu-transform pure-menu-horizontal pure-g">
|
||||
<ul class="pure-menu-list pure-u-lg-5-6 pure-u-1">
|
||||
<li class="pure-menu-item">
|
||||
<img src="img/logo_myShaarli.png" class="head-logo" alt="logo" width="120px" height="45px"/>
|
||||
</li>
|
||||
<li><img src="{$asset_path}/img/logo_myShaarli.png#" class="head-logo" alt="logo" width="120px" height="45px"/></li>
|
||||
<li class="pure-menu-item pure-u-0 pure-u-lg-visible">
|
||||
<a href="{$titleLink}" class="pure-menu-link shaarli-title" id="shaarli-title-desktop">
|
||||
<img src="img/favicon_32.png" width="18" height="18" class="head-logo" alt="" />
|
||||
<img src="{$asset_path}/img/favicon_16.png#" width="16" height="16" class="head-logo" alt="logo" />
|
||||
{$shaarlititle}
|
||||
</a>
|
||||
</li>
|
||||
{if="$is_logged_in || $openshaarli"}
|
||||
<li class="pure-menu-item">
|
||||
<a href="?do=addlink" class="pure-menu-link" id="shaarli-menu-shaare">
|
||||
<a href="{$base_path}/admin/add-shaare" class="pure-menu-link" id="shaarli-menu-shaare">
|
||||
<i class="fa fa-plus" aria-hidden="true"></i> {'Shaare'|t}
|
||||
</a>
|
||||
</li>
|
||||
<li class="pure-menu-item" id="shaarli-menu-tools">
|
||||
<a href="?do=tools" class="pure-menu-link">{'Tools'|t}</a>
|
||||
<a href="{$base_path}/admin/tools" class="pure-menu-link">{'Tools'|t}</a>
|
||||
</li>
|
||||
{/if}
|
||||
<li class="pure-menu-item" id="shaarli-menu-tags">
|
||||
<a href="?do=tagcloud" class="pure-menu-link">{'Tag cloud'|t}</a>
|
||||
<a href="{$base_path}/tags/cloud" class="pure-menu-link">{'Tag cloud'|t}</a>
|
||||
</li>
|
||||
{if="$thumbnails_enabled"}
|
||||
<li class="pure-menu-item" id="shaarli-menu-picwall">
|
||||
<a href="?do=picwall{$searchcrits}" class="pure-menu-link">{'Picture wall'|t}</a>
|
||||
<a href="{$base_path}/picture-wall?{function="ltrim($searchcrits, '&')"}" class="pure-menu-link">{'Picture wall'|t}</a>
|
||||
</li>
|
||||
{/if}
|
||||
<li class="pure-menu-item" id="shaarli-menu-daily">
|
||||
<a href="?do=daily" class="pure-menu-link">{'Daily'|t}</a>
|
||||
<a href="{$base_path}/daily" class="pure-menu-link">{'Daily'|t}</a>
|
||||
</li>
|
||||
{loop="$plugins_header.buttons_toolbar"}
|
||||
<li class="pure-menu-item shaarli-menu-plugin">
|
||||
|
@ -53,15 +53,15 @@
|
|||
</li>
|
||||
{/loop}
|
||||
<li class="pure-menu-item pure-u-lg-0 shaarli-menu-mobile" id="shaarli-menu-mobile-rss">
|
||||
<a href="?do={$feed_type}{$searchcrits}" class="pure-menu-link">{'RSS Feed'|t}</a>
|
||||
<a href="{$base_path}/feed/{$feed_type}?{$searchcrits}" class="pure-menu-link">{'RSS Feed'|t}</a>
|
||||
</li>
|
||||
{if="$is_logged_in"}
|
||||
<li class="pure-menu-item pure-u-lg-0 shaarli-menu-mobile" id="shaarli-menu-mobile-logout">
|
||||
<a href="?do=logout" class="pure-menu-link">{'Logout'|t}</a>
|
||||
<a href="{$base_path}/admin/logout" class="pure-menu-link">{'Logout'|t}</a>
|
||||
</li>
|
||||
{else}
|
||||
<li class="pure-menu-item pure-u-lg-0 shaarli-menu-mobile" id="shaarli-menu-mobile-login">
|
||||
<a href="?do=login" class="pure-menu-link">{'Login'|t}</a>
|
||||
<a href="{$base_path}/login" class="pure-menu-link">{'Login'|t}</a>
|
||||
</li>
|
||||
{/if}
|
||||
</ul>
|
||||
|
@ -75,13 +75,13 @@
|
|||
</a>
|
||||
</li>
|
||||
<li class="pure-menu-item" id="shaarli-menu-desktop-rss">
|
||||
<a href="?do={$feed_type}{$searchcrits}" class="pure-menu-link" title="{'RSS Feed'|t}" aria-label="{'RSS Feed'|t}">
|
||||
<i class="fa fa-rss" aria-hidden="true"></i>
|
||||
<a href="{$base_path}/feed/{$feed_type}?{$searchcrits}" class="pure-menu-link" title="{'RSS Feed'|t}" aria-label="{'RSS Feed'|t}">
|
||||
<i class="fa fa-rss" aria-hidden="true"></i>
|
||||
</a>
|
||||
</li>
|
||||
{if="!$is_logged_in"}
|
||||
<li class="pure-menu-item" id="shaarli-menu-desktop-login">
|
||||
<a href="?do=login" class="pure-menu-link"
|
||||
<a href="{$base_path}/login" class="pure-menu-link"
|
||||
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>
|
||||
|
@ -89,8 +89,8 @@
|
|||
</li>
|
||||
{else}
|
||||
<li class="pure-menu-item" id="shaarli-menu-desktop-logout">
|
||||
<a href="?do=logout" class="pure-menu-link" aria-label="{'Logout'|t}" title="{'Logout'|t}">
|
||||
<i class="fa fa-sign-out" aria-hidden="true"></i>
|
||||
<a href="{$base_path}/admin/logout" class="pure-menu-link" aria-label="{'Logout'|t}" title="{'Logout'|t}">
|
||||
<i class="fa fa-sign-out" aria-hidden="true"></i>
|
||||
</a>
|
||||
</li>
|
||||
{/if}
|
||||
|
@ -100,43 +100,90 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content" class="container">
|
||||
<main id="content" class="container" role="main">
|
||||
<div id="search" class="subheader-form searchform-block header-search">
|
||||
<form method="GET" class="pure-form searchform" name="searchform">
|
||||
<input type="text" tabindex="1" id="searchform_value" name="searchterm" placeholder="{'Search text'|t}"
|
||||
<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" tabindex="2" name="searchtags" id="tagfilter_value" placeholder="{'Filter by tag'|t}"
|
||||
<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"><i class="fa fa-search"></i></button>
|
||||
<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">Delete</a>
|
||||
<a href="" id="actions-delete" class="button">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
{'Delete'|t}
|
||||
</a>
|
||||
<a href="" class="actions-change-visibility button" data-visibility="public">
|
||||
<i class="fa fa-globe" aria-hidden="true"></i>
|
||||
{'Set public'|t}
|
||||
</a>
|
||||
<a href="" class="actions-change-visibility button" data-visibility="private">
|
||||
<i class="fa fa-user-secret" aria-hidden="true"></i>
|
||||
{'Set private'|t}
|
||||
</a>
|
||||
<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>
|
||||
<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>
|
||||
<a href="" class="button action">
|
||||
<i class="fa fa-tag" aria-hidden="true"></i>
|
||||
{$value === 'add' ? t('Add tag') : t('Delete tag')}
|
||||
</a>
|
||||
<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" placeholder="{'Username'|t}" tabindex="3">
|
||||
<input type="password" name="password" placeholder="{'Password'|t}" tabindex="5">
|
||||
<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" tabindex="6" checked>
|
||||
<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" tabindex="7">
|
||||
<input type="submit" value="Login">
|
||||
</div>
|
||||
</form>
|
||||
{/if}
|
||||
|
@ -174,8 +221,22 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
{if="!empty($global_warnings) && $is_logged_in"}
|
||||
<div class="pure-g pure-alert pure-alert-warning pure-alert-closable" id="shaarli-warnings-alert">
|
||||
{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">
|
||||
{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">
|
||||
{loop="global_warnings"}
|
||||
|
@ -188,4 +249,18 @@
|
|||
</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">
|
||||
{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>
|
||||
|
|
|
@ -6,47 +6,54 @@
|
|||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
|
||||
<div class="pure-g myShaarli_picwall">
|
||||
<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">
|
||||
{$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"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
|
||||
<div id="picwall-container" class="picwall-container">
|
||||
{loop="$linksToDisplay"}
|
||||
<div class="picwall-pictureframe">
|
||||
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore}
|
||||
<img data-src="{$value.thumbnail}#" class="b-lazy"
|
||||
src=""
|
||||
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
|
||||
<a href="{$value.real_url}"><span class="info">{$value.title}</span></a>
|
||||
{loop="$value.picwall_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
{/loop}
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="plugin_zone_end_picwall" class="plugin_zone">
|
||||
{loop="$plugin_end_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
{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 class="pure-u-lg-1-6 pure-u-1-24"></div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<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">
|
||||
{$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"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
|
||||
<div id="picwall-container" class="picwall-container" role="list">
|
||||
{loop="$linksToDisplay"}
|
||||
<div class="picwall-pictureframe" role="listitem">
|
||||
{ignore}RainTPL hack: put the 2 src on two different line to avoid path replace bug{/ignore}
|
||||
<img data-src="{$root_path}/{$value.thumbnail}#" class="b-lazy"
|
||||
src=""
|
||||
alt="" width="{$thumbnails_width}" height="{$thumbnails_height}" />
|
||||
<a href="{$value.real_url}"><span class="info">{$value.title}</span></a>
|
||||
{loop="$value.picwall_plugin"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
{/loop}
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<div id="plugin_zone_end_picwall" class="plugin_zone">
|
||||
{loop="$plugin_end_zone"}
|
||||
{$value}
|
||||
{/loop}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-lg-1-6 pure-u-1-24"></div>
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
<script src="js/thumbnails.min.js?v={$version_hash}"></script>
|
||||
<script src="{$asset_path}/js/thumbnails.min.js?v={$version_hash}#"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
<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 need to enable Javascript to change plugin loading order.'|t}
|
||||
{'You have to enable JavaScript to change plugin loading order.'|t}
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</noscript>
|
||||
|
||||
<form method="POST" action="?do=save_pluginadmin" name="pluginform" id="pluginform" class="pluginform-container">
|
||||
<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">
|
||||
|
@ -32,7 +32,7 @@
|
|||
<table id="plugin_table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="center">{'Disable'|t}</th>
|
||||
<th class="center">{'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>
|
||||
|
@ -61,7 +61,7 @@
|
|||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th class="center">{'Disable'|t}</th>
|
||||
<th class="center">{'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>
|
||||
|
@ -82,7 +82,7 @@
|
|||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="center">{'Enable'|t}</th>
|
||||
<th class="center">{'Enabled'|t}</th>
|
||||
<th>{'Name'|t}</th>
|
||||
<th><div class="pure-u-0 pure-u-lg-visible">{'Description'|t}</div></th>
|
||||
</tr>
|
||||
|
@ -105,7 +105,7 @@
|
|||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th class="center">{'Enable'|t}</th>
|
||||
<th class="center">{'Enabled'|t}</th>
|
||||
<th>{'Name'|t}</th>
|
||||
<th><div class="pure-u-0 pure-u-lg-visible">{'Description'|t}</div></th>
|
||||
</tr>
|
||||
|
@ -117,7 +117,7 @@
|
|||
|
||||
<div class="center more">
|
||||
{"More plugins available"|t}
|
||||
<a href="doc/html/Community-&-Related-software/#third-party-plugins">{"in the documentation"|t}</a>.
|
||||
<a href="{$root_path}/doc/html/Community-&-Related-software/#third-party-plugins">{"in the documentation"|t}</a>.
|
||||
</div>
|
||||
<div class="center">
|
||||
<input type="submit" value="{'Save'|t}" name="save">
|
||||
|
@ -127,7 +127,7 @@
|
|||
<input type="hidden" name="token" value="{$token}">
|
||||
</form>
|
||||
|
||||
<form action="?do=save_pluginadmin" method="POST">
|
||||
<form action="{$base_path}/admin/plugins" method="POST">
|
||||
<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">
|
||||
|
@ -173,10 +173,11 @@
|
|||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="token" value="{$token}">
|
||||
</form>
|
||||
|
||||
{include="page.footer"}
|
||||
<script src="js/pluginsadmin.min.js?v={$version_hash}"></script>
|
||||
<script src="{$asset_path}/js/pluginsadmin.min.js?v={$version_hash}#"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
13
tpl/myShaarli/pluginscontent.html
Normal file
13
tpl/myShaarli/pluginscontent.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
|
||||
<head>
|
||||
{include="includes"}
|
||||
</head>
|
||||
<body>
|
||||
{include="page.header"}
|
||||
|
||||
{$content}
|
||||
|
||||
{include="page.footer"}
|
||||
</body>
|
||||
</html>
|
129
tpl/myShaarli/server.html
Normal file
129
tpl/myShaarli/server.html
Normal file
|
@ -0,0 +1,129 @@
|
|||
<!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-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>
|
||||
|
||||
<h3 class="window-subtitle">{'General'|t}</h3>
|
||||
|
||||
<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>
|
||||
{loop="$trusted_proxies"}
|
||||
{$value}<br>
|
||||
{/loop}
|
||||
</p>
|
||||
{else}
|
||||
<p>{'N/A'|t}</p>
|
||||
{/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>
|
||||
|
||||
<h3 class="window-subtitle">{'Thumbnails'|t}</h3>
|
||||
|
||||
<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>
|
||||
{if="$thumbnails_mode==='all'"}
|
||||
{'All'|t}
|
||||
{elseif="$thumbnails_mode==='common'"}
|
||||
{'Only common media hosts'|t}
|
||||
{else}
|
||||
{'None'|t}
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{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}
|
||||
|
||||
<h3 class="window-subtitle">{'Cache'|t}</h3>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
68
tpl/myShaarli/server.requirements.html
Normal file
68
tpl/myShaarli/server.requirements.html
Normal file
|
@ -0,0 +1,68 @@
|
|||
<div class="server-tables">
|
||||
<h3 class="window-subtitle">{'Permissions'|t}</h3>
|
||||
|
||||
{if="count($permissions) > 0"}
|
||||
<p class="center">
|
||||
<i class="fa fa-close fa-color-red" aria-hidden="true"></i>
|
||||
{'There are permissions that need to be fixed.'|t}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{loop="$permissions"}
|
||||
<div class="center">{$value}</div>
|
||||
{/loop}
|
||||
</p>
|
||||
{else}
|
||||
<p class="center">
|
||||
<i class="fa fa-check fa-color-green" aria-hidden="true"></i>
|
||||
{'All read/write permissions are properly set.'|t}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<h3 class="window-subtitle">PHP</h3>
|
||||
|
||||
<p class="center">
|
||||
<strong>{'Running PHP'|t} {$php_version}</strong>
|
||||
{if="$php_has_reached_eol"}
|
||||
<i class="fa fa-circle fa-color-orange" aria-label="hidden"></i><br>
|
||||
{'End of life: '|t} {$php_eol}
|
||||
{else}
|
||||
<i class="fa fa-circle fa-color-green" aria-label="hidden"></i><br>
|
||||
{/if}
|
||||
</p>
|
||||
|
||||
<table class="center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{'Extension'|t}</th>
|
||||
<th>{'Usage'|t}</th>
|
||||
<th>{'Status'|t}</th>
|
||||
<th>{'Loaded'|t}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{loop="$php_extensions"}
|
||||
<tr>
|
||||
<td>{$value.name}</td>
|
||||
<td>{$value.desc}</td>
|
||||
<td>{$value.required ? t('Required') : t('Optional')}</td>
|
||||
<td>
|
||||
{if="$value.loaded"}
|
||||
{$classLoaded="fa-color-green"}
|
||||
{$strLoaded=t('Loaded')}
|
||||
{else}
|
||||
{$strLoaded=t('Not loaded')}
|
||||
{if="$value.required"}
|
||||
{$classLoaded="fa-color-red"}
|
||||
{else}
|
||||
{$classLoaded="fa-color-orange"}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<i class="fa fa-circle {$classLoaded}" aria-label="{$strLoaded}" title="{$strLoaded}"></i>
|
||||
</td>
|
||||
</tr>
|
||||
{/loop}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
|
@ -15,7 +15,7 @@
|
|||
<h2 class="window-title">{'Tag cloud'|t} - {$countTags} {'tags'|t}</h2>
|
||||
{if="!empty($search_tags)"}
|
||||
<p class="center">
|
||||
<a href="?searchtags={$search_tags|urlencode}" class="pure-button pure-button-shaarli">
|
||||
<a href="{$base_path}/?searchtags={$search_tags_url}" class="pure-button pure-button-shaarli">
|
||||
{'List all links with those tags'|t}
|
||||
</a>
|
||||
</p>
|
||||
|
@ -26,14 +26,15 @@
|
|||
<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" placeholder="{'Filter by tag'|t}"
|
||||
<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"><i class="fa fa-search"></i></button>
|
||||
<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>
|
||||
|
@ -47,8 +48,8 @@
|
|||
|
||||
<div id="cloudtag" class="cloudtag-container">
|
||||
{loop="tags"}
|
||||
<a href="?searchtags={$key|urlencode} {$search_tags|urlencode}" style="font-size:{$value.size}em;">{$key}</a
|
||||
><a href="?addtag={$key|urlencode}" title="{'Filter by tag'|t}" class="count">{$value.count}</a>
|
||||
<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"}
|
||||
{$value}
|
||||
{/loop}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<h2 class="window-title">{'Tag list'|t} - {$countTags} {'tags'|t}</h2>
|
||||
{if="!empty($search_tags)"}
|
||||
<p class="center">
|
||||
<a href="?searchtags={$search_tags|urlencode}" class="pure-button pure-button-shaarli">
|
||||
<a href="{$base_path}/?searchtags={$search_tags_url}" class="pure-button pure-button-shaarli">
|
||||
{'List all links with those tags'|t}
|
||||
</a>
|
||||
</p>
|
||||
|
@ -26,14 +26,14 @@
|
|||
<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" placeholder="{'Filter by tag'|t}"
|
||||
<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"><i class="fa fa-search"></i></button>
|
||||
<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>
|
||||
|
@ -47,17 +47,17 @@
|
|||
|
||||
<div id="taglist" class="taglist-container">
|
||||
{loop="tags"}
|
||||
<div class="tag-list-item pure-g" data-tag="{$key}">
|
||||
<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"><i class="fa fa-trash"></i></a>
|
||||
<a href="?do=changetag&fromtag={$key|urlencode}" class="rename-tag">
|
||||
<i class="fa fa-pencil-square-o {$key}"></i>
|
||||
<a href="#" class="delete-tag" aria-label="{'Delete'|t}"><i class="fa fa-trash" aria-hidden="true"></i></a>
|
||||
<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="?addtag={$key|urlencode}" title="{'Filter by tag'|t}" class="count">{$value}</a>
|
||||
<a href="?searchtags={$key|urlencode} {$search_tags|urlencode}" class="tag-link">{$key}</a>
|
||||
<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}
|
||||
|
@ -66,7 +66,7 @@
|
|||
{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"></i></a>
|
||||
<a href="#" class="validate-rename-tag"><i class="fa fa-check" aria-hidden="true"></i></a>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div class="pure-g">
|
||||
<div class="pure-u-1 pure-alert pure-alert-success tag-sort">
|
||||
{'Sort by:'|t}
|
||||
<a href="?do=tagcloud">{'Cloud'|t}</a> ·
|
||||
<a href="?do=taglist&sort=usage">{'Most used'|t}</a> ·
|
||||
<a href="?do=taglist&sort=alpha">{'Alphabetical'|t}</a>
|
||||
<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>
|
||||
</div>
|
|
@ -38,11 +38,11 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="ids" value="{function="implode($ids, ',')"}" />
|
||||
<input type="hidden" name="ids" value="{function="implode(',', $ids)"}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{include="page.footer"}
|
||||
<script src="js/thumbnails_update.min.js?v={$version_hash}"></script>
|
||||
<script src="{$asset_path}/js/thumbnails_update.min.js?v={$version_hash}#"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -11,48 +11,46 @@
|
|||
<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="?do=configure" title="{'Change Shaarli settings: title, timezone, etc.'|t}">
|
||||
<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="?do=pluginadmin" title="{'Enable, disable and configure plugins'|t}">
|
||||
<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="?do=changepasswd" title="{'Change your password'|t}">
|
||||
<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="?do=changetag" title="{'Rename or delete a tag in all links'|t}">
|
||||
<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="?do=import"
|
||||
<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="?do=export"
|
||||
<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>
|
||||
|
||||
{if="$thumbnails_enabled"}
|
||||
<div class="tools-item">
|
||||
<a href="?do=thumbs_update" 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}
|
||||
|
||||
{loop="$tools_plugin"}
|
||||
<div class="tools-item">
|
||||
{$value}
|
||||
|
@ -67,7 +65,7 @@
|
|||
<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</h2>
|
||||
<h2 class="window-title">{'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}
|
||||
|
@ -86,7 +84,7 @@
|
|||
alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}');
|
||||
}
|
||||
window.open(
|
||||
'{$pageabsaddr}?post='%20+%20encodeURIComponent(url)+
|
||||
'{$pageabsaddr}admin/shaare?post='%20+%20encodeURIComponent(url)+
|
||||
'&title='%20+%20encodeURIComponent(title)+
|
||||
'&description='%20+%20encodeURIComponent(desc)+
|
||||
'&source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1'
|
||||
|
@ -108,7 +106,7 @@
|
|||
alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}');
|
||||
}
|
||||
window.open(
|
||||
'{$pageabsaddr}?private=1&post='+
|
||||
'{$pageabsaddr}admin/shaare?private=1&post='+
|
||||
'&description='%20+%20encodeURIComponent(desc)+
|
||||
'&source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1'
|
||||
);
|
||||
|
@ -123,31 +121,10 @@
|
|||
<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">{'3rd party'|t}</h2>
|
||||
<h2 class="window-title">{'Third-party resources'|t}</h2>
|
||||
<div class="tools-item">
|
||||
<a href="https://addons.mozilla.org/fr/firefox/addon/shaarli/">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">Firefox {'plugin'|t}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="tools-item">
|
||||
<a href="https://chrome.google.com/webstore/detail/shiny-shaarli/hajdfkmbdmadjmmpkkbbcnllepomekin">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">Chrome {'plugin'|t}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="tools-item">
|
||||
<a href="https://play.google.com/store/apps/details?id=com.dimtion.shaarlier&hl=fr">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">Android Shaarlier</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="tools-item">
|
||||
<a href="https://stakali.toneiv.eu/">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">Android Stakali</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="tools-item">
|
||||
<a href="https://itunes.apple.com/app/ShaarliOS/id1027441388?mt=8"
|
||||
title="iOS">
|
||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">iOS</span>
|
||||
<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>
|
||||
|
|
Loading…
Reference in a new issue