first commit

This commit is contained in:
2026-01-13 15:35:11 -05:00
commit b00950d5e8
186 changed files with 25169 additions and 0 deletions
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="404"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div class="container">
<div class="text-center">
<img src="{$asset_path}/dist/img/sad_star.png#" alt="Nothing found">
</div>
<div class="nothing-found">{'Sorry, nothing to see here.'|t} That's a <strong>404</strong>.</div>
<p class="text-center">{$error_message}</p>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="addlink"}
{include="includes"}
</head>
<body onload="document.addform.post.focus();">
{include="page.header"}
<div id="headerform" class="page-add container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form method="GET" action="{$base_path}/admin/shaare" name="addform" class="form-add card">
<div class="card-title">{"Shaare a new link"|t}</div>
<div class="card-body">
<div class="form-entry">
<label for="post">{'URL or leave empty to post a note'|t}</label><br/>
<input type="text" name="post" id="post" class="autofocus" placeholder="Type a url...">
</div>
</div>
<div class="card-footer">
<button type="submit" class="button-raised button-primary pull-right">{'Add link'|t}</button>
<div class="clearfix"></div>
</div>
</form>
</div>
<div class="col-md-6 col-md-offset-3">
<button type="button" class="button pull-right button-batch-addform"><i class="mdi mdi-playlist-plus" aria-hidden="true"></i>&nbsp;{'BULK CREATION'|t}</button>
<div class="clearfix"></div>
<form class="card batch-addform hidden" method="POST" action="{$base_path}/admin/shaare-batch" name="batch-addform">
<div class="card-header">{"Shaare multiple new links"|t}</div>
<div class="card-body">
<div class="form-entry">
<label for="urls">{'Add one URL per line to create multiple bookmarks.'|t}</label>
<textarea name="urls" id="urls" rows="4"></textarea>
</div>
<div class="form-entry">
<label for="tags">{'Tags'|t}</label><br/>
<input type="text" name="tags" id="tags" class="lf_input" data-list="{loop="$tags"}{$key}, {/loop}" data-multiple data-autofirst autocomplete="off">
</div>
<input type="hidden" name="private" value="0">
<div class="form-entry">
<input type="checkbox" name="private" {if="$default_private_links"} checked="checked"{/if} id="lf_private" class="filled-in"/>
<label for="lf_private">{'Private'|t}</label>
</div>
</div>
<div class="card-footer">
<input type="hidden" name="token" value="{$token}">
<button type="submit" class="button-raised button-primary pull-right">{'Add links'|t}</button>
<div class="clearfix"></div>
</div>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="changepassword"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div class="container page-changepassword">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form method="POST" action="#" name="changepasswordform" id="changepasswordform" class="card">
<div class="card-title">{'Change password'|t}</div>
<div class="card-body">
<div class="form-entry">
<label for="oldpassword">{'Current password'|t}</label>
<input type="password" name="oldpassword" id="oldpassword" class="autofocus">
</div>
<div class="form-entry">
<label for="setpassword">{'New password'|t}</label>
<input type="password" name="setpassword" id="setpassword">
</div>
<input type="hidden" name="token" value="{$token}">
</div>
<div class="card-footer">
<button type="submit" name="Save" class="button-raised button-primary pull-right">{'Change'|t}</button>
<div class="clearfix"></div>
</div>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="changetag"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div class="container page-changetag">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form method="POST" action="" name="changetag" id="changetag" class="card">
<div class="card-title">{"Manage tags"|t}</div>
<div class="card-body">
<input type="hidden" name="token" value="{$token}">
<p>All modifications are case sensitive.</p>
<div class="form-entry">
<label for="fromtag">Modify this tag&#8230;</label>
<input type="text" name="fromtag" id="fromtag" value="{$fromtag}" class="autofocus"
autocomplete="off" data-multiple data-minChars="1"
data-list="{loop="$tags"}{$key}, {/loop}"/>
</div>
<div class="form-entry">
<label for="totag">&#8230;into this tag</label>
<input type="text" name="totag" id="totag">
</div>
<p>{'You can also edit tags in the'|t} <a href="{$base_path}/tags/list?sort=usage">{'tag list'|t}</a>.</p>
</div>
<div class="card-footer">
<button type="submit" id="button-delete" name="deletetag" class="button-raised button-alert pull-right" value="Delete tag">{'Delete tag'|t}</button>
<button type="submit" name="renametag" class="button-raised pull-right" value="Rename tag">{'Rename tag'|t}</button>
<div class="clearfix"></div>
</div>
</form>
</div>
<div class="col-md-6 col-md-offset-3">
<form method="POST" action="{$base_path}/admin/tags/change-separator" name="changeseparator" id="changeseparator" class="card">
<div class="card-header">{"Change tags separator"|t}</div>
<div class="card-body">
<p>
{'Your current tag separator is'|t} <code>{$tags_separator}</code>{if="!empty($tags_separator_desc)"} ({$tags_separator_desc}){/if}.
</p>
<div class="form-entry">
<label for="separator">{'New separator'|t}</label>
<input type="text" name="separator" id="separator" autocomplete="off"/>
<input type="hidden" name="token" value="{$token}">
</div>
</div>
<div class="card-footer">
<p>
{'Note that hashtags won\'t fully work with a non-whitespace separator.'|t}
</p>
<button type="submit" name="saveseparator" class="button-raised button-primary pull-right">{'Save'|t}</button>
<div class="clearfix"></div>
</div>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,242 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="configure"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div class="container page-configure">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form method="POST" action="#" name="configform" id="configform" class="card">
<input type="hidden" name="token" value="{$token}"/>
<div class="card-title">Configuration</div>
<div class="card-body">
<div class="form-entry">
<label for="title">Shaarli {'title'|t}</label>
<input type="text" name="title" id="title" class="autofocus" size="50" value="{$title}" />
</div>
<div class="form-entry">
<label for="titleLink">{'Home link'|t}</label>
<input type="text" name="titleLink" id="titleLink" size="50" value="{$titleLink}">
<div class="sublabel">{'Default value'|t}: {$base_path}/</div>
</div>
<div class="form-entry">
<label for="theme">{'Theme'|t}</label>
<select name="theme" id="theme">
{loop="$theme_available"}
<option value="{$value}" {if="$value === $theme"}selected{/if}>
{$value|ucfirst}
</option>
{/loop}
</select>
</div>
<div class="form-entry">
<label for="theme">{'Description formatter'|t}</label>
<select name="formatter" id="formatter">
{loop="$formatter_available"}
<option value="{$value}" {if="$value === $formatter"}selected="selected"{/if}>
{$value|ucfirst}
</option>
{/loop}
</select>
</div>
<div class="form-entry">
<label for="language">{'Language'|t}</label>
<select name="language" id="language">
{loop="$languages"}
<option value="{$key}" {if="$key === $language"}selected{/if}>
{$value|ucfirst}
</option>
{/loop}
</select>
</div>
<div class="form-entry">
<label for="continent">{'Timezone'|t}</label>
<div class="row">
<div class="col-sm-6" id="timezone-continent">
<select name="continent" id="continent">
{loop="$continents"}
{if="$key !== 'selected'"}
<option value="{$value}" {if="$continents.selected === $value"}selected{/if}>
{$value}
</option>
{/if}
{/loop}
</select>
</div>
<div class="col-sm-6" id="timezone-city">
<select name="city" id="city">
{loop="$cities"}
{if="$key !== 'selected'"}
<option value="{$value.city}" {if="$cities.selected === $value.city"}selected{/if} data-continent="{$value.continent}">
{$value.city}
</option>
{/if}
{/loop}
</select>
</div>
</div>
<div class="sublabel">{'Continent'|t} &middot; {'City'|t}</div>
</div>
</div>
<div class="list-side-right">
<div class="list-body">
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Disable session cookie hijacking protection'|t}</div>
<div class="list-item-sublabel">{'Check this if you get disconnected or if your IP address changes often'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label>
<input type="checkbox" name="disablesessionprotection" id="disablesessionprotection" {if="$session_protection_disabled"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Private links by default'|t}</div>
<div class="list-item-sublabel">{'All new links are private by default'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label>
<input type="checkbox" name="privateLinkByDefault" id="privateLinkByDefault" {if="$private_links_default"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'RSS direct links'|t}</div>
<div class="list-item-sublabel">Enabling it will show a permalink in the description, and the feed item will be linked to the absolute URL. Disabling it swaps this behaviour around (permalink in title and link in description).</div>
</div>
<div class="list-item-side">
<div class="switch">
<label>
<input type="checkbox" name="enableRssPermalinks" id="enableRssPermalinks" {if="$enable_rss_permalinks"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Hide public links'|t}</div>
<div class="list-item-sublabel">{'Do not show any links if the user is not logged in'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label>
<input type="checkbox" name="hidePublicLinks" id="hidePublicLinks" {if="$hide_public_links"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Automatically retrieve description for new bookmarks'|t}</div>
<div class="list-item-sublabel">{'Shaarli will try to retrieve the description from meta HTML headers'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label>
<input type="checkbox" name="retrieveDescription" id="retrieveDescription" {if="$retrieve_description"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Check updates'|t}</div>
<div class="list-item-sublabel">{'Notify me when a new release is ready'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label>
<input type="checkbox" name="updateCheck" id="updateCheck" {if="$enable_update_check"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Enable thumbnails'|t}</div>
<div class="list-item-sublabel">
{if="! $gd_enabled"}
{'You need to enable the extension <code>php-gd</code> to use thumbnails.'|t}
{elseif="$thumbnails_enabled"}
<a href="{$base_path}/admin/thumbnails">{'Synchronize thumbnails'|t}</a>
{/if}
</div>
</div>
<div class="list-item-side">
<select name="enableThumbnails" id="enableThumbnails" class="align">
<option value="all" {if="$thumbnails_mode=='all'"}selected{/if}>
{'All'|t}
</option>
<option value="common" {if="$thumbnails_mode=='common'"}selected{/if}>
{'Only common media hosts'|t}
</option>
<option value="none" {if="$thumbnails_mode=='none'"}selected{/if}>
{'None'|t}
</option>
</select>
</div>
</div>
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Enable REST API'|t}</div>
<div class="list-item-sublabel">{'Allow third party software to use Shaarli such as mobile application'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label>
<input type="checkbox" name="enableApi" id="enableApi" {if="$api_enabled"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="list">
<div class="list-item">
<div class="form-entry">
<label for="apiSecret">{'API secret'|t}</label>
<input type="text" name="apiSecret" id="apiSecret" size="50" value="{$api_secret}" placeholder="Type a random string..." />
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" name="Save" class="button-raised button-primary pull-right">{'Save'|t}</button>
<div class="clearfix"></div>
</div>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="daily"}
{include="includes"}
</head>
<body class="dark-toolbar">
{include="page.header"}
<div class="subheader is-dark">
<div class="container text-center">
<a class="button-inverse button-default{if="array_key_exists('day', $_GET) || (!array_key_exists('week', $_GET) && !array_key_exists('month', $_GET))"} active{/if}" href="{$base_path}/daily?day" title="{'Daily'|t}">{'Daily'|t}</a>
<a class="button-inverse button-default{if="array_key_exists('week', $_GET)"} active{/if}" href="{$base_path}/daily?week" title="{'Weekly'|t}">{'Weekly'|t}</a>
<a class="button-inverse button-default{if="array_key_exists('month', $_GET)"} active{/if}" href="{$base_path}/daily?month" title="{'Monthly'|t}">{'Monthly'|t}</a>
</div>
</div>
<div class="daily">
<div id="plugin_zone_start_picwall" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
<div class="daily-header">
<h1>{$localizedType} Shaarli</h1>
<p class="daily-header-subtitle">{function="t('All links of one :type in a single page.', '', 1, 'shaarli', [':type' => t($type)])"}</p>
<div class="container">
<div class="row">
<div class="col-xs-6">
<a {if="$previousday"}href="{$base_path}/daily?{$type}={$previousday}"{else}href="#"{/if} class="button" {if="!$previousday"}disabled{/if}>
<i class="mdi mdi-arrow-left"></i> {function="t('Previous :type', '', 1, 'shaarli', [':type' => t($type)], true)"}
</a>
</div>
<div class="col-xs-6">
<a {if="$nextday"}href="{$base_path}/daily?{$type}day={$nextday}"{else}href="#"{/if} class="button" {if="!$nextday"}disabled{/if}>
{function="t('Next :type', '', 1, 'shaarli', [':type' => t($type)], true)"} <i class="mdi mdi-arrow-right"></i>
</a>
</div>
</div>
<hr class="darker">
</div>
</div>
<h2 class="daily-title">{$dayDesc}</h2>
<div id="plugin_zone_about_daily" class="plugin_zone">
{loop="$daily_about_plugin"}
{$value}
{/loop}
</div>
{if="$linksToDisplay"}
<div class="daily-grid clearfix" data-columns>
{loop="$linksToDisplay"}
{$link=$value}
<div class="daily-item">
<div class="daily-card">
<a href="{$link.real_url}" class="daily-item-header ripple ripple-primary">
{$link.title}
</a>
{if="$thumbnails_enabled && !empty($link.thumbnail)"}
<div class="daily-item-image" style="background-image: url({$root_path}/{$link.thumbnail}#)"></div>
{/if}
{if="$link.formatedDescription"}
<div class="daily-item-body">
{$link.formatedDescription}
</div>
{/if}
<div class="daily-item-footer clearfix">
{if="!$hide_timestamps || $is_logged_in"}
<a href="{$base_path}/shaare/{$value.shorturl}" class="daily-item-footer-subtitle" title="{'Permalink'|t}">
{if="$type === 'week'"}
{function="strftime('%a %e %b, %H:%M', $link.timestamp)"}
{else}
{if="$type === 'month'"}
{function="strftime('%a %e %b %Y, %H:%M', $link.timestamp)"}
{else}
{function="strftime('%H:%M', $link.timestamp)"}
{/if}
{/if}
</a>
{/if}
{if="$link.tags"}
<div class="daily-item-tags">
{$tags=implode(', ', $link['taglist'])}
{$tags}
</div>
{/if}
<div>
{loop="$link.link_plugin"}
{$value}
{/loop}
</div>
</div>
</div>
</div>
{/loop}
</div>
{else}
<div>No articles on this day.</div>
{/if}
<div id="plugin_zone_end_picwall" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,35 @@
<?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} &#8212; {/if}
<a href="{$index_url}shaare/{$value.shorturl}">{'Permalink'|t}</a>
{if="$value.tags"} &#8212; {$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} -->
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="editlinkbatch"}
{include="includes"}
</head>
<body class="page-edit-link-batch">
{include="page.header"}
<div id="progress-overlay" class="fullscreen hidden">
<div class="content-fullscreen">
<div class="container">
<div class="mbl row">
<div class="col-md-8 col-md-offset-2">
<div class="is-inverted">
<div class="progress-counter">
<span class="progress-current">0</span> / <span class="progress-total"></span>
</div>
<div class="progress-bar">
<div class="progress-actual"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="text-center">
<button type="submit" name="save_edit_batch" class="button-raised button-primary">{'Save all'|t}</button>
</div>
{loop="$links"}
{$index=$key}
{include="editlink"}
{/loop}
<div class="text-center">
<button type="submit" name="save_edit_batch" class="button-raised button-primary">{'Save all'|t}</button>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,99 @@
{if="empty($batch_mode)"}
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="editlink"}
{include="includes"}
</head>
<body {if="!empty($_GET['source']) && $_GET['source']=='bookmarklet'"}class="from-bookmarklet"{/if}>
{include="page.header"}
{else}
{ignore}Lil hack: when included in a loop in batch mode, `$value` is assigned by RainTPL with template vars.{/ignore}
{function="extract($value) ? '' : ''"}
{/if}
{$asyncLoadClass=$link_is_new && $async_metadata && empty($link.title) ? 'loading-wrapper' : ''}
{if="!isset($index)"}
{$index=""}
{/if}
<div id="editlinkform{$index}" class="editlinkform container page-edit">
<div class="row editlinkform-row">
<div class="col-md-6 col-md-offset-3 editlinkform-col">
<form method="post" name="linkform" class="card" action="{$base_path}/admin/shaare">
{if="isset($link.id)"}
<input type="hidden" name="lf_id" value="{$link.id}">
{/if}
<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}
<div class="card-header">
{if="!$link_is_new"}Edit a link{else}Add a new link{/if}
{if="!$link_is_new"}<span class="card-subheader"> - {'created on'|t} {$link.created|format_date}</span>{/if}
<button type="button" class="button-expand button-header visible-md visible-lg" title="Expand / reduce width"></button>
</div>
<div class="card-body">
<div class="form-entry">
<label for="lf_url{$index}">{'URL'|t}</label><br/>
<input type="text" name="lf_url" id="lf_url{$index}" value="{$link.url}" placeholder="Type a url...">
</div>
<div class="form-entry">
<label for="lf_title{$index}">{'Title'|t}</label><br/>
<div class="{$asyncLoadClass}">
<input type="text" name="lf_title" id="lf_title{$index}" {if="empty($batch_mode) && $link.title==''"}class="autofocus"{/if} value="{$link.title}" placeholder="Title...">
</div>
</div>
<div class="form-entry">
<label for="lf_description{$index}">{'Description'|t}</label><br/>
<div class="{$asyncLoadClass}">
<textarea name="lf_description" id="lf_description{$index}" {if="empty($batch_mode) && $link.description==''"}class="autofocus"{/if} placeholder="Describe the link..." rows="4">{$link.description}</textarea>
</div>
</div>
<div class="form-entry">
<label for="lf_tags{$index}">{'Tags'|t}</label><br/>
<div class="{$asyncLoadClass}">
<input type="text" id="lf_tags{$index}" name="lf_tags" {if="empty($batch_mode)"}class="autofocus"{/if} value="{$link.tags}" class="lf_input"
data-list="{loop="$tags"}{$key}, {/loop}" data-multiple autocomplete="off" />
</div>
</div>
{if="isset($edit_link_plugin)"}
{loop="$edit_link_plugin"}
<div class="form-entry">
{$value}
</div>
{/loop}
{/if}
<div class="form-entry">
<input type="checkbox" class="filled-in" {if="$link.private === true"}checked="checked"{/if} name="lf_private" id="lf_private{$index}"/>
<label for="lf_private{$index}">{'Private'|t}</label>
</div>
{if="$formatter==='markdown'"}
<div class="form-entry">
{'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>
<div class="card-footer">
<button type="submit" name="save_edit" class="button-raised button-primary pull-right">{'Save'|t}</button>
{if="!$link_is_new"}
<a href="{$base_path}/admin/shaare/delete?id={$link.id}&amp;token={$token}"
name="delete_link" class="button-raised button-alert">{'Delete'|t}</a>
{/if}
{if="!empty($batch_mode)"}
<button type="button" name="cancel-batch-link" title="{'Remove this bookmark from batch creation/modification.'|t}" class="button pull-right ripple-primary">{'Cancel'|t}</button>
{/if}
<div class="clearfix"></div>
</div>
</form>
</div>
</div>
</div>
{if="empty($batch_mode)"}
{include="page.footer"}
{/if}
</body>
</html>
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="error"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div id="pageError" class="container text-center">
<h2>{$message}</h2>
<div>
<img src="{$asset_path}/dist/img/sad_star.png#" alt="">
</div>
{if="!empty($text)"}
<p>{$text}</p>
{/if}
{if="!empty($stacktrace)"}
<pre>
{$stacktrace}
</pre>
{/if}
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,10 @@
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<!-- This is an automatically generated file.
It will be read and overwritten.
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>
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="export"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div id="toolsdiv" class="container page-export">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form class="card" method="post" action="{$base_path}/admin/export">
<input type="hidden" name="token" value="{$token}">
<h1 class="card-header">{"Export Database"|t}</h1>
<div class="list-side-right">
<div class="list-body">
<div class="list-item no-border">
<div class="list-item-content">
<div class="list-item-label">{'Prepend note permalinks with this Shaarli instance\'s URL'|t}</div>
<div class="list-item-sublabel">{'Useful to import bookmarks in a web browser'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label>
<input type="checkbox" name="prepend_note_url" id="prepend_note_url"/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
<div class="list-item">
<label class="list-item-content" for="selection-all">
<div class="list-item-label">Export all</div>
<div class="list-item-sublabel">Export all links</div>
</label>
<div class="list-item-side">
<input name="selection" class="with-gap" type="radio" value="all" id="selection-all" checked />
<label for="selection-all"></label>
</div>
</div>
<div class="list-item no-border">
<label class="list-item-content" for="selection-public">
<div class="list-item-label">Export public</div>
<div class="list-item-sublabel">Export public links only</div>
</label>
<div class="list-item-side">
<input name="selection" class="with-gap" type="radio" value="public" id="selection-public" />
<label for="selection-public"></label>
</div>
</div>
<div class="list-item no-border">
<label class="list-item-content" for="selection-private">
<div class="list-item-label">Export private</div>
<div class="list-item-sublabel">Export private links only</div>
</label>
<div class="list-item-side">
<input name="selection" class="with-gap" type="radio" value="private" id="selection-private" />
<label for="selection-private"></label>
</div>
</div>
</div>
</div>
<div class="card-footer clearfix">
<button type="submit" class="button-raised button-primary pull-right">{'Export'|t}</button>
</div>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>{$pagetitle}</title>
<subtitle>Shaared links</subtitle>
{if="$show_dates"}
<updated>{$last_update}</updated>
{/if}
<link rel="self" href="{$self_link}#" />
<link rel="search" type="application/opensearchdescription+xml" href="{$index_url}open-search#"
title="Shaarli search - {$shaarlititle}" />
{loop="$plugins_feed_header"}
{$value}
{/loop}
<author>
<name>{$pagetitle}</name>
<uri>{$index_url}</uri>
</author>
<id>{$index_url}</id>
<generator>Shaarli</generator>
{loop="$links"}
<entry>
<title>{$value.title}</title>
{if="$usepermalinks"}
<link href="{$value.guid}#" />
{else}
<link href="{$value.url}#" />
{/if}
<id>{$value.guid}</id>
{if="$show_dates"}
<published>{$value.pub_iso_date}</published>
<updated>{$value.up_iso_date}</updated>
{/if}
<content type="html" xml:lang="{$language}"><![CDATA[{$value.description}]]></content>
{loop="$value.taglist"}
<category scheme="{$index_url}?searchtags=" term="{$value|strtolower}" label="{$value}" />
{/loop}
{loop="$value.feed_plugins"}
{$value}
{/loop}
</entry>
{/loop}
</feed>
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{$pagetitle}</title>
<link>{$index_url}</link>
<description>Shaared links</description>
<language>{$language}</language>
<copyright>{$index_url}</copyright>
<generator>Shaarli</generator>
<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="$plugins_feed_header"}
{$value}
{/loop}
{loop="$links"}
<item>
<title>{$value.title}</title>
<guid isPermaLink="{if="$usepermalinks"}true{else}false{/if}">{$value.guid}</guid>
{if="$usepermalinks"}
<link>{$value.guid}</link>
{else}
<link>{$value.url}</link>
{/if}
{if="$show_dates"}
<pubDate>{$value.pub_iso_date}</pubDate>
<atom:modified>{$value.up_iso_date}</atom:modified>
{/if}
<description><![CDATA[{$value.description}]]></description>
{loop="$value.taglist"}
<category domain="{$index_url}?searchtags=">{$value}</category>
{/loop}
{loop="$value.feed_plugins"}
{$value}
{/loop}
</item>
{/loop}
</channel>
</rss>
@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="import"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div id="uploaddiv" class="container page-import">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form method="post" action="{$base_path}/admin/import" enctype="multipart/form-data" name="uploadform" id="uploadform" class="card">
<input type="hidden" name="token" value="{$token}">
<input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}">
<div class="card-title">{"Import Database"|t}</div>
<div class="card-body">
<p>Import Netscape HTML bookmarks (as exported from Firefox/Chrome/Opera/Delicious/Diigo...).</p>
<div class="form-entry">
<label for="filetoupload">File to upload</label>
<input type="file" id="filetoupload" name="filetoupload" class="autofocus"/>
<div class="sublabel">{'Maximum size allowed:'|t} <strong>{$maxfilesizeHuman}</strong></div>
</div>
<div class="form-entry">
<input type="checkbox" class="filled-in" name="overwrite" id="overwrite">
<label for="overwrite">{'Overwrite existing bookmarks'|t}</label>
</div>
</div>
<div class="list-side-right">
<div class="list-body">
<div class="list-item">
<label class="list-item-content" for="privacy-default">
<div class="list-item-label">Default</div>
<div class="list-item-sublabel">{'Use values from the imported file, default to public'|t}</div>
</label>
<div class="list-item-side">
<input name="privacy" class="with-gap" type="radio" value="default" id="privacy-default" checked />
<label for="privacy-default"></label>
</div>
</div>
<div class="list-item no-border">
<label class="list-item-content" for="privacy-private">
<div class="list-item-label">Private</div>
<div class="list-item-sublabel">{'Import all bookmarks as private'|t}</div>
</label>
<div class="list-item-side">
<input name="privacy" class="with-gap" type="radio" value="private" id="privacy-private" />
<label for="privacy-private"></label>
</div>
</div>
<div class="list-item no-border">
<label class="list-item-content" for="privacy-public">
<div class="list-item-label">Public</div>
<div class="list-item-sublabel">{'Import all bookmarks as public'|t}</div>
</label>
<div class="list-item-side">
<input name="privacy" class="with-gap" type="radio" value="public" id="privacy-public" />
<label for="privacy-public"></label>
</div>
</div>
<div class="list-item">
<div class="form-entry">
<label for="default-tags">{'Add default tags'|t}</label>
<input type="text" name="default_tags" id="default-tags" placeholder="Separate tags with comma...">
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" name="import_file" class="button-raised button-primary pull-right">{'Import'|t}</button>
<div class="clearfix"></div>
</div>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,78 @@
<title>{$pagetitle}</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<meta name="referrer" content="same-origin">
<link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" />
<link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" />
<link rel="apple-touch-icon" sizes="57x57" href="{$asset_path}/dist/img/favicons/apple-touch-icon-57x57.png#">
<link rel="apple-touch-icon" sizes="60x60" href="{$asset_path}/dist/img/favicons/apple-touch-icon-60x60.png#">
<link rel="apple-touch-icon" sizes="72x72" href="{$asset_path}/dist/img/favicons/apple-touch-icon-72x72.png#">
<link rel="apple-touch-icon" sizes="76x76" href="{$asset_path}/dist/img/favicons/apple-touch-icon-76x76.png#">
<link rel="icon" type="image/png" href="{$asset_path}/dist/img/favicons/favicon-32x32.png#" sizes="32x32">
<link rel="icon" type="image/png" href="{$asset_path}/dist/img/favicons/favicon-96x96.png#" sizes="96x96">
<link rel="icon" type="image/png" href="{$asset_path}/dist/img/favicons/favicon-16x16.png#" sizes="16x16">
<link rel="manifest" href="{$asset_path}/dist/img/favicons/manifest.json#">
<link rel="shortcut icon" href="{$asset_path}/dist/img/favicons/favicon.ico#">
<link rel="search" type="application/opensearchdescription+xml" href="{$base_path}/open-search#" title="Shaarli search - {$shaarlititle}"/>
<meta name="msapplication-TileColor" content="#603cba">
<meta name="msapplication-config" content="{$asset_path}/dist/img/favicons/browserconfig.xml#">
{if="$pageName === '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="mb_substr(strip_tags($ogDescription), 0, 300)"}{if="strlen($ogDescription) > 300"}...{/if}" />
{if="!empty($link.thumbnail)"}
<meta property="og:image" content="{$index_url}{$link.thumbnail}" />
{elseif="is_file('tpl/material/opengraph.png')"}
<meta property="og:image" content="{$index_url}tpl/material/opengraph.png" />
{/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}
{else}
<meta property="og:title" content="{$pagetitle}" />
<meta property="og:type" content="website" />
{if="is_file('tpl/material/opengraph.png')"}
<meta property="og:image" content="{$index_url}tpl/material/opengraph.png" />
{/if}
{/if}
<link type="text/css" rel="stylesheet" href="{$asset_path}/dist/lib.css?v={$version_hash}#" />
<link type="text/css" rel="stylesheet" href="{$asset_path}/dist/bundle.css?v={$version_hash}#" />
{if="$conf->get('config.MATERIAL_COLOR')"}
{$themeColor=$conf->get('config.MATERIAL_COLOR')}
<meta name="theme-color" content="{$themeColor}">
{else}
<meta name="theme-color" content="#2196f3">
{/if}
{loop="$plugins_includes.css_files"}
<link type="text/css" rel="stylesheet" href="{$root_path}/{$value}?v={$version_hash}#"/>
{/loop}
{if="is_file('data/user.css')"}
<link type="text/css" rel="stylesheet" href="{$root_path}/data/user.css#" />
{/if}
{$tagSeparator=str_replace("'", "\\'", $tags_separator)}
<script>
var shaarli = {
source: '{$source}',
basePath: '{$base_path}',
rootPath: '{$root_path}',
assetPath: '{$asset_path}',
datePattern: '{$conf->get('config.MATERIAL_DATE_PATTERN')}',
isAuth: {if="$is_logged_in"}true{else}false{/if},
pageName: '{$pageName}',
asyncMetadata: {if="isset($async_metadata) && $async_metadata"}true{else}false{/if},
tagsSeparator: '{$tagSeparator}'
};
</script>
{if="file_exists('tpl/material/extra.html')"}
{include="extra"}
{/if}
@@ -0,0 +1,78 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="install"}
{include="includes"}
</head>
<body>
<div id="install" class="page-install">
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form method="post" action="{$base_path}/install" name="installform" id="installform" class="card">
<div class="card-title">Welcome to your Shaarli</div>
<div class="card-body">
<p>{'It looks like it\'s the first time you run Shaarli. Please configure it.'|t}</p>
<div class="form-entry">
<label for="setlogin">{'Username'|t}</label>
<input type="text" name="setlogin" id="setlogin" class="autofocus"/>
</div>
<div class="form-entry">
<label for="setpassword">{'Password'|t}</label>
<input type="password" id="setpassword" name="setpassword"/>
</div>
<div class="form-entry">
<label for="continent">{'Timezone'|t}</label>
<div class="row">
<div class="col-sm-6" id="timezone-continent">
<select name="continent" id="continent">
{loop="$continents"}
{if="$key !== 'selected'"}
<option value="{$value}" {if="$continents.selected === $value"}selected{/if}>
{$value}
</option>
{/if}
{/loop}
</select>
</div>
<div class="col-sm-6" id="timezone-city">
<select name="city" id="city">
{loop="$cities"}
{if="$key !== 'selected'"}
<option value="{$value.city}" {if="$cities.selected === $value.city"}selected{/if} data-continent="{$value.continent}">
{$value.city}
</option>
{/if}
{/loop}
</select>
</div>
</div>
</div>
<div class="form-entry">
<label for="title">{'Shaarli title'|t}</label>
<input type="text" name="title" id="title" placeholder="{'My links'|t}"/>
</div>
<div class="form-entry">
<input type="checkbox" class="filled-in" name="updateCheck" id="updateCheck" checked="checked">
<label for="updateCheck">{'Notify me when a new release is ready'|t}</label>
</div>
<div class="form-entry">
<input type="checkbox" class="filled-in" name="enableApi" id="enableApi">
<label for="enableApi">{'Enable REST API'|t}</label>
<div class="sublabel">{'Allow third party software to use Shaarli such as mobile application'|t}</div>
</div>
</div>
<div class="card-footer">
<button type="submit" name="Save" class="button-raised button-primary pull-right">{'Install'|t}</button>
<div class="clearfix"></div>
</div>
</form>
</div>
</div>
</div>
{include="server.requirements"}
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,152 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="linklist"}
{include="includes"}
</head>
<body>
{include="page.header"}
{$dateFormat=!empty($conf->get('config.MATERIAL_PHP_DATE_PATTERN')) ? $conf->get('config.MATERIAL_PHP_DATE_PATTERN') : '%c'}
{$qrCodeDisabled=!empty($conf->get('config.MATERIAL_NO_QRCODE')) ? $conf->get('config.MATERIAL_NO_QRCODE') : false}
<div id="linklist" class="container">
{loop="$plugin_start_zone"}
{$value}
{/loop}
{include="linklist.paging"}
{if="count($links)==0"}
<div class="text-center">
<img src="{$asset_path}/dist/img/sad_star.png#" alt="Nothing found" />
</div>
<div class="nothing-found">Sorry... We found nothing{if="!empty($search_term)"} for <strong>{$search_term}</strong>{/if}{if="!empty($search_tags)"}{$exploded_tags=explode(' ', $search_tags)} tagged <strong>{loop="$exploded_tags"} {$value}{/loop}</strong>{/if}.</div>
{elseif="!empty($search_term) or !empty($search_tags) or !empty($visibility) or $untaggedonly"}
<div id="searchcriteria">
{function="sprintf(t('%s result', '%s results', $result_count), $result_count)"}
{if="!empty($search_term)"} {'for'|t} <strong>{$search_term}</strong>{/if}
{if="!empty($search_tags)"}{$exploded_tags=tags_str2array($search_tags, $tags_separator)} {'tagged'|t} <i>
{loop="$exploded_tags"}
<a href="{$base_path}/remove-tag/{function="urlencode($value)"}" class="link-tag-filter" title="{'Remove tag'|t}">{$value}&nbsp;
<span class="remove">&#x2715;</span>
</a>
{/loop}
</i>
{/if}
{if="!empty($visibility)"}
{'with status'|t}
<strong>
{$visibility|t}
</strong>
{/if}
{if="$untaggedonly"}
<strong>
{'without any tag'|t}
</strong>
{/if}
</div>
{/if}
<div class="links-list">
{ignore}Set translation here, for performances{/ignore}
{$strPrivate=t('Private')}
{$strEdit=t('Edit')}
{$strDelete=t('Delete')}
{$strFold=t('Fold')}
{$strEdited=t('Edited: ')}
{$strPermalink=t('Permalink')}
{$strPermalinkLc=t('permalink')}
{$strAddTag=t('Add tag')}
{$strToggleSticky=t('Toggle sticky')}
{$strSticky=t('Sticky')}
{ignore}End of translations{/ignore}
{loop="$links"}
<div id="{$value.id}" class="link-outer{if="$value.class"} {$value.class}{/if}" data-id="{$value.id}">
<div class="link-overlay"></div>
<div class="link-inner">
<div class="link-header">
<div class="row">
<div class="col-sm-8">
<a class="link-title" href="{$value.real_url}">
{if="strpos($value.url, $value.shorturl) !== false"}
<i class="mdi mdi-note"></i>
{/if}
{$value.title_html}
</a>
<a href="{$value.real_url}" class="link-url"><span title="Real URL">{$value.real_url}</span></a>
</div>
<div class="col-sm-4">
<div class="link-date">
{if="!$hide_timestamps || $is_logged_in"}
<span title="Permalink - {function="strftime($dateFormat, $value.timestamp)"}"><a href="{$base_path}/shaare/{$value.shorturl}" class="link-actual-date">{function="strftime($dateFormat, $value.timestamp)"}</a></span>
{else}
<span title="Short link here"><a href="{$base_path}/shaare/{$value.shorturl}">Permalink</a></span>
{/if}
{loop="$value.link_plugin"}
<span class="link-plugin">{$value}</span>
{/loop}
{ignore}
{/ignore}
</div>
</div>
</div>
</div>
<div class="link-content">
<div>
{if="$thumbnails_enabled && $value.thumbnail !== false"}
<div class="thumb{if="$value.thumbnail === null"} hidden{/if}" {if="$value.thumbnail === null"}data-async-thumbnail="1"{/if}>
<a href="{$value.real_url}">
{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 link-thumbnail"
src="#"
alt="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
</a>
</div>
{/if}
{if="$value.description"}
<div class="link-description">{$value.description}</div>
{/if}
</div>
</div>
<div class="link-footer is-flex">
<div class="link-tag-list is-flex-grown">
{if="$value.tags"}
{loop="$value.taglist"}
<span class="link-tag" title="Find links with the same tag"><a href="{$base_path}/add-tag/{$value1.taglist_urlencoded.$key2}">{$value1.taglist_html.$key2}</a></span>
{/loop}
{/if}
</div>
<div class="link-actions is-flex-end">
{if="!$qrCodeDisabled"}
<a href="#" data-permalink="{$value.real_url}" title="Show link QR Code" class="qrcode"><i class="mdi mdi-qrcode"></i></a>
{/if}
{if="$is_logged_in"}
<a href="{$base_path}/admin/shaare/delete?id={$value.id}&amp;token={$token}" title="{$strDelete}" class="button-delete"><i class="mdi mdi-delete"></i></a>
<a href="{$base_path}/admin/shaare/{$value.id}" title="{$strEdit}"><i class="mdi mdi-pencil"></i></a>
<a href="{$base_path}/admin/shaare/{$value.id}/pin?token={$token}" title="{$strToggleSticky}" {if="isset($value.sticky) && $value.sticky"}class="is-pinned"{/if}><i class="mdi mdi-pin"></i></a>
{else}
{if="isset($value.sticky) && $value.sticky"}
<span title="{$strSticky}"><i class="mdi mdi-pin"></i></span>
{/if}
{/if}
</div>
</div>
</div>
</div>
{/loop}
</div>
{include="linklist.paging"}
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,33 @@
{if="$page_max > 1"}
{if="$is_logged_in"}
{$total="$linkcount"}
{else}
{if="empty($privateLinkcount)"}
{$total="$linkcount"}
{else}
{$total="$linkcount" - "$privateLinkcount"}
{/if}
{/if}
{$from=("$page_current" - 1) * "$links_per_page" + 1}
{$to=min($total, ("$page_current" - 1) * "$links_per_page" + "$links_per_page")}
<div class="paging clearfix">
<div class="paging-links">
<div class="paging-current"><strong>{$from}-{$to}</strong> of {$total}</div>
<!--<div class="paging-current">p<span class="hidden-xs">age</span> {$page_current} / {$page_max}</div>-->
<div>{if="$next_page_url"}<a href="{$next_page_url}" class="paging-newer" title="Newer"><i class="mdi mdi-arrow-left"></i></a>{/if}</div>
<div>{if="$previous_page_url"}<a href="{$previous_page_url}" class="paging-older" title="Older"><i class="mdi mdi-arrow-right"></i></a>{/if}</div>
</div>
<div>
{loop="$action_plugin"}
<div class="paging_privatelinks">
<a
{loop="$value.attr"}
{$key}="{$value}"
{/loop}>
{$value.html}
</a>
</div>
{/loop}
</div>
</div>
{/if}
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="loginform"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div id="headerform" class="page-login container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form method="post" name="loginform" class="card">
<div class="card-title">{'Login'|t}</div>
<div class="card-body">
<div class="form-entry">
<label for="login">{'Username'|t}</label><br/>
<input type="text" name="login" id="login" {if="empty($username)"}class="autofocus"{/if} tabindex="1" {if="!empty($username)"}value="{$username}"{/if}>
</div>
<div class="form-entry">
<label for="password">{'Password'|t}</label><br/>
<input type="password" name="password" id="password" {if="!empty($username)"}class="autofocus"{/if} tabindex="2" >
</div>
<div class="form-entry">
<input type="checkbox" class="filled-in" name="longlastingsession" id="longlastingsession" tabindex="3"
{if="$remember_user_default"}checked="checked"{/if}>
<label for="longlastingsession">{'Remember me'|t}</label>
</div>
</div>
<div class="card-footer">
<button type="submit" class="button-raised button-primary pull-right" tabindex="4">{'Login'|t}</button>
<input type="hidden" name="token" value="{$token}">
{if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl}">{/if}
<div class="clearfix"></div>
</div>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<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}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
QVRIx5WWaWxU5xWG3++7986dfYYZb+MN2xiMDRiDFePUiQsNoiwpUNpAmhInJVEqpa0oQUlbJVKq
olaiqpLKUtOKhAJRm1BKRVWctuykpFjAgPcFx/uMl5mxPTOeuXPv3O3rjyiV0lIpfX+dc36c55xf
70vwP9TZ2fFpSQCwT5u6unX4f0QeNLx27RoMQwfRveTd11T23M+8S9w+Z3NRma1W4Hk6/nEimFpM
Xnun9Xpmz1MPY+feOhBi/fwAAOjq7iJEqmQqCZf5i7NvyNZ/bJPYgAjCiJc2Zmhyw68SM/T1+NlK
uf61BPoH+tHU1PT5ACMjI8RXvACvpZ5NT0+fmrG+2TKqtDLV0BgA2AUfXS3+UtfDX2ixCf73E+oA
rat92CTkv9fRBwEkSaLDt/JZR/v0Q7qjb8dQ5hjSqmYSOCkzBbogL+ij2RN8bik9wK88Al9tH4tG
ow88lvb19yEyPwfGGLq6OungYD9fUlosrqwoQVVVUeOU8qE/mU0ZTq6KNvreNort+5hugkayQUgY
qQld/u6qnVRhkciscOdOkNy5E0RnZ+e/AbwsZxAaHyORZA+prW01CTlnGppOqAcwUnCmlDAkAyin
Dapb2t7lNeRijpwvTGlJROXugoKS+upz/S19Kj9lJjxXGY1VU49tGevt7WOCSMHTeAXclePsQts9
Jq9oLR7rPVkHxpUYkK2c07ZDiieRNcAx3ZlNphcnsxbiMuEsXFSTZpabp+VVS17UNSV/8n7+gN75
+C1DM6VEjkgatiz/5IOCAheiUdeyr+198keKZXLzTKYjMDk/ZzGJhkV9AiPSdWaYIAY4U7TYNJMR
pugMqgHcXTiJqDK8ycMv2+TPWyWtKFw3KEdtJxNz8u8+/PNYIqeUgY/Oz+Z7q5X3gtqvG7qip8yM
HqdZg5kGgwGACoQQQkEMQ2DMIFnGE04xCRQTZFaexUT6jEEImJ2njjxx9fr13hfqfULTQ4apHept
lxf4mrqS3Tek0w1toTc1K6WcXfAwnyWH8kSkIueEhdhNrzUAv16fSCUzNwR3vr/G2lKWojMqbxF4
FWlLPDvBR+RBNpTsNqfkV7htuUe/UVq456qdzzvFh2KjdSH0I6ODs1ps9NHcw2jMfRYcEQyOCiox
aWR0fOQWVLFNUuOnrXJxfIPnpXLRKzocLpsJanhUU/bfjJ4gfwm/ys3JGX1cuS3UBvauLa/MBe9z
5c/xGRdSKpiVmhhN98JK/w4DGgg4uLh8u1NfPhWbmzszeH3G1rxv3dL7+qXyGaXHJi46s4QQophp
TKSDkHWGlAqmGCbAGAUA3sY5LlRZv3w44Dhnm0iFzbnsGfJR5E+EEsppTBVXuBptL5b8YQMlwnO+
Z2wtea4cl8Rc3KXJ4zShRm0CFaCaGhSDwGSMlbtLhSr7FnVhKhscC4+AO3L0x5PSFBdfE9i40SE6
xLSWRCIbJ6phIqEysqvk+2aJ0vhB1NK353zyaL3GS76NgRbVYykkt2OXuaQqMwuxkk0FT+OJpS+z
piXPRP1KzRvz4dRvO68PaWCMEQAIDcbqFiLJtyaSA/Ef3NnMGttgvHS7mUUWw7cTMemtY/cPsw3n
oe2+4mGXpt7VGWPJ6zOn1V2Xfaz5AxgvBzexodmeGWmCbWWTDOGpSZIIqeAe2/IYvnXgWbomUj2T
lNlwUP7bV64lzuRIeoodqDxi1OKRs/e0i08dH/6JPWtk6KKaZd3xj2jAXkY3BvZGK1xrhZvRNktP
fNA0ubQrxyxV4jHpSkWoXJPKYqBetxeRpgsMWwE5b/bxaYxUDSWmzCLbStqQuy02LY4/cWLsqH8i
HYNbyEeJczkJSzH2855DwsXp932F9hXEKQSQ1UHa568iRAa3uFyeNVolMBmeIrzT4cTXm37KMuvA
xb8XXTqiDELRgKg8h/dGWwP9iSDaIzcYJSCbA/uNR3N2sNahV/hbsSA70vEdW66tCOOpj8FRkIgU
Q5ybLUopiTzeTpFWUoTXdR3knwQMzLANOyQX50fWhDktLeAX3UcIA2EEQHPgi6TBsrWzaLGm7emC
H7bY+GPlV6YumiEpDhslxGBgROApz+yyhROzduIEzwngDh48iD3jO0nBRAUUXtHcoq+ZWbI5EWWa
WTieFjoKsaVoN92T88J4vlz+asXqpb+hEcdotbdueZ47vyiqhpA2UoRQwpoLtpNHxR0382jR8RzT
k8xYMyCMMfR33Uc8rxdrA9tpuHPyS7pPOTRPZ1arepa4rUsybiWnnU9a39ZXxdur+XoGAGMdoXLi
M789axnfNxDr8omiDcvF1f3OhPf18efjF/nfz6PGvv6zlrlwWwYBgcBZbKH4WKHODLHEURDxbHDF
QWGePftHUlZWjsy8guYnH2EgwORfZ5cuavEqgGhLnL6+sycvRP1Fbux/fheIn3wCCN4N/qdPMwA4
2fYOeoe7kc6kcfCbh8n+r7YwAOjs6QCl9DNx5t7dew+MOf8CcuqqoLxlhwgAAAAASUVORK5CYII=
</Image>
</OpenSearchDescription>
@@ -0,0 +1,31 @@
<div id="footer" class="container">
<div>
<b><a href="https://github.com/shaarli/Shaarli">Shaarli</a></b>
{if="$is_logged_in"} v{$version}{/if}
- {'The personal, minimalist, super fast, database-free, bookmarking service'|t} {'by the Shaarli community'|t}
{if="$is_logged_in"} - <a href="{$root_path}/doc/html/index.html" rel="nofollow">{'Documentation'|t}</a>{/if}
- Theme by <a href="https://github.com/kalvn">kalvn</a>
</div>
<div>
{loop="$plugins_footer.text"}
{$value}
{/loop}
</div>
{loop="$plugins_footer.endofpage"}
{$value}
{/loop}
{if="$newVersion"}
<div id="newversion"><span id="version_id">&#x25CF;</span> Shaarli {$newVersion} <a href="https://github.com/shaarli/Shaarli/releases">{'is available'|t}</a>.</div>
{/if}
{if="isset($versionError) && $versionError"}
<div id="newversion">
Error: {$versionError}
</div>
{/if}
<input type="hidden" name="token" value="{$token}" id="token" />
</div>
<script src="{$asset_path}/dist/bundle.js?v={$version_hash}#"></script>
{loop="$plugins_footer.js_files"}
<script src="{$root_path}/{$value}?v={$version_hash}#"></script>
{/loop}
@@ -0,0 +1,273 @@
<!--
{$isCalledFromBookmarklet=array_key_exists('source', $_GET) && in_array($_GET['source'], array('bookmarklet'))}
{$displayAddNewLinkIcon=(($is_logged_in || $openshaarli) && in_array($pageName, array('linklist', 'tools', 'tag.cloud', 'tag.list', 'picwall', 'daily')))}
{$plugins=$conf->get('general.enabled_plugins')}
{$filterClass=(($visibility==='private'||$visibility==='public'||$untaggedonly)?'has-filters':'')}
-->
{if="$isCalledFromBookmarklet"}
{ignore} When called as a popup from bookmarklet, do not display menu. {/ignore}
{else}
<div class="header-main container-fluid">
<div class="row">
<div class="col-lg-3 is-flex">
<a href="{$titleLink}" class="header-brand ripple">{$shaarlititle}</a>
<a href="#" class="icon-unfold hidden-lg ripple" title="Show/hide menu"><i class="mdi mdi-chevron-down"></i></a>
</div>
<div class="col-lg-6 header-middle">
<div class="header-nav">
<div class="col-xs-6 col-sm-3 text-center">
<a href="{$base_path}/tags/cloud" class="toolbar-link button-inverse ripple">{'Tag cloud'|t}</a>
</div>
<div class="col-xs-6 col-sm-3 text-center">
<a href="{$base_path}/picture-wall?{function="ltrim($searchcrits, '&')"}" class="toolbar-link button-inverse ripple">{'Picture wall'|t}</a>
</div>
<div class="col-xs-6 col-sm-3 text-center">
<a href="{$base_path}/daily" class="toolbar-link button-inverse ripple">{'Daily'|t}</a>
</div>
<div class="col-xs-6 col-sm-3 text-center">
<button class="toolbar-link button-inverse ripple" id="button-search">{'Search'|t}</button>
</div>
</div>
</div>
<div class="col-lg-3">
<div class="header-buttons">
{if="isset($plugins_header.buttons_toolbar) ||isset($plugins_header.fields_toolbar)"}
<div class="toolbar-button-container">
<button type="button" class="icon-header popup-trigger ripple" data-popup="popup-plugin" title="More">
<i class="mdi mdi-dots-vertical"></i>
</button>
<div id="popup-plugin" class="popup popup-plugin hidden">
<div class="popup-title">Plugins<button class="popup-close"><i class="mdi mdi-close"></i></button></div>
<div class="popup-body">
{loop="$plugins_header.buttons_toolbar"}
<ul>
<li>
<a
{loop="$value.attr"}
{$key}="{$value}"
{/loop}>
{$value.html}
</a>
</li>
</ul>
{/loop}
{loop="$plugins_header.fields_toolbar"}
<form class="popup-content-area"
{loop="$value.attr"}
{$key}="{$value}"
{/loop} >
{loop="$value.inputs"}
<input
{loop="$value"}
{$key}="{$value}"
{/loop}>
{/loop}
</form>
{/loop}
</div>
</div>
</div>
{/if}
{if="$is_logged_in"}
<a href="{$base_path}/admin/logout" class="icon-header popup-trigger ripple" title="{'Logout'|t}">
<i class="mdi mdi-logout"></i>
</a>
<a href="{$base_path}/admin/tools" class="icon-header ripple" title="{'Tools'|t}">
<i class="mdi mdi-settings"></i>
</a>
{elseif="$openshaarli"}
<a href="{$base_path}/admin/tools" class="icon-header ripple" title="{'Tools'|t}">
<i class="mdi mdi-settings"></i>
</a>
{else}
<a href="{$base_path}/login" class="icon-header popup-trigger ripple" title="{'Login'|t}">
<i class="mdi mdi-account"></i>
</a>
{/if}
<div class="toolbar-button-container">
<button type="button" class="icon-header popup-trigger ripple" data-popup="popup-rss" title="{'RSS Feed'|t}">
<i class="mdi mdi-rss"></i>
</button>
<div id="popup-rss" class="popup popup-rss hidden">
<div class="popup-title">{'RSS Feed'|t}<button class="popup-close"><i class="mdi mdi-close"></i></button></div>
<div class="popup-body">
<ul>
<li><a href="{$base_path}/feed/{$feed_type}?{$searchcrits}" class="ripple">{'RSS Feed'|t}</a></li>
<li><a href="{$base_path}/daily-rss?day" class="ripple" title="1 RSS entry per day">Daily Feed</a></li>
<li><a href="{$base_path}/daily-rss?week" class="ripple" title="1 RSS entry per day">Weekly Feed</a></li>
<li><a href="{$base_path}/daily-rss?month" class="ripple" title="1 RSS entry per day">Monthly Feed</a></li>
</ul>
</div>
</div>
</div>
{if="$is_logged_in && $pageName === 'linklist'"}
<div class="toolbar-button-container">
<button type="button" class="icon-header ripple batch-trigger" title="Select multiple links for deletion">
<i class="mdi mdi-checkbox-marked-outline"></i>
</button>
</div>
{/if}
<div class="toolbar-button-container">
{if="$pageName === 'linklist'"}
<button type="button" class="header-button-filter popup-trigger icon-header ripple {$filterClass}" data-popup="popup-filter" title="{'Filters'|t}">
<i class="mdi mdi-filter"></i>
</button>
<div id="popup-filter" class="popup popup-filter hidden">
<div class="popup-title">{'Filters'|t}<button class="popup-close"><i class="mdi mdi-close"></i></button></div>
<div class="popup-body">
<h2>{'Links per page'|t}</h2>
<ul class="filters-links-per-page">
<li><a href="{$base_path}/links-per-page?nb=20" class="ripple {if="$links_per_page == 20"}is-bold{/if}">20 links</a></li>
<li><a href="{$base_path}/links-per-page?nb=50" class="ripple {if="$links_per_page == 50"}is-bold{/if}">50 links</a></li>
<li><a href="{$base_path}/links-per-page?nb=100" class="ripple {if="$links_per_page == 100"}is-bold{/if}">100 links</a></li>
</ul>
<form method="get" action="{$base_path}/links-per-page" class="popup-content-area">
<label for="filter-nb">Custom value</label>
<input type="text" id="filter-nb" name="nb" placeholder="Type a number..." value="{$links_per_page}"/>
</form>
<h2>{'Filters'|t}</h2>
<div class="list-side-right">
<div class="list-body">
{if="$is_logged_in"}
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Only private links'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label data-url="{$base_path}/admin/visibility/private">
<input type="checkbox" name="input-visibility-private" id="input-visibility-private" {if="$visibility==='private'"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Only public links'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label data-url="{$base_path}/admin/visibility/public">
<input type="checkbox" name="input-visibility-public" id="input-visibility-public" {if="$visibility==='public'"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
{/if}
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">{'Untagged links'|t}</div>
</div>
<div class="list-item-side">
<div class="switch">
<label data-url="{$base_path}/untagged-only">
<input type="checkbox" name="input-untaggedonly" id="input-untaggedonly" {if="$untaggedonly"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
{if="in_array('readitlater', $plugins)"}
<div class="list-item">
<div class="list-item-content">
<div class="list-item-label">Links to read later</div>
</div>
<div class="list-item-side">
<div class="switch">
<label data-url="{$base_path}/plugin/readitlater/toggle-filter">
<input type="checkbox" name="input-readlater" id="input-readlater" {if="$readitlaterOnly"}checked{/if}/>
<span class="lever"></span>
</label>
</div>
</div>
</div>
{/if}
</div>
</div>
</div>
</div>
{/if}
</div>
</div>
</div>
</div>
</div>
{if="$displayAddNewLinkIcon"}
<a href="{$base_path}/admin/add-shaare" class="button-floating ripple">
<i class="icon-add-link mdi mdi-plus"></i>
</a>
{/if}
<form id="hidden-tag-form" class="hidden" method="GET" name="tagfilter" action="{$base_path}/">
<input type="hidden" name="searchtags" id="tagfilter_value" value=""/>
</form>
<div class="notifications">
{if="!empty($plugin_errors) && $is_logged_in"}
{loop="plugin_errors"}
<div class="notification is-danger">
<button class="notification-close"><i class="mdi mdi-close"></i></button>
{$value}
</div>
{/loop}
{/if}
{if="!empty($global_errors)"}
{loop="global_errors"}
<div class="notification is-danger">
<button class="notification-close"><i class="mdi mdi-close"></i></button>
{$value}
</div>
{/loop}
{/if}
{if="!empty($global_warnings)"}
{loop="global_warnings"}
<div class="notification is-warning">
<button class="notification-close"><i class="mdi mdi-close"></i></button>
{$value}
</div>
{/loop}
{/if}
{if="!empty($global_successes)"}
{loop="global_successes"}
<div class="notification is-success">
<button class="notification-close"><i class="mdi mdi-close"></i></button>
{$value}
</div>
{/loop}
{/if}
</div>
{/if}
<div id="search-overlay" class="fullscreen hidden">
<div class="content-fullscreen">
<div class="container">
<div class="mbl row">
<form method="get" action="{$base_path}/" id="form-search" class="col-md-8 col-md-offset-2">
<div class="search-field">
<input type="search" id="searchform_value" class="input-big" name="searchterm"
value="{if="isset($search_type)"}{if="$search_type=='fulltext'"}{$search_crits}{elseif="$search_type=='tags'"}{loop="$search_crits"}{$value} {/loop}{else}{/if}{/if}"
placeholder="Search..." autocomplete="off" data-multiple data-minChars="1"
data-list="{loop="$tags"}{$key}, {/loop}" />
<div class="search-overlay-actions">
<button type="button" id="button-filter" class="button-raised ripple ripple-primary">
<i class="visible-xs mdi mdi-tag-multiple"></i>
<span class="hidden-xs"><i class="mdi mdi-magnify"></i>{'tags'|t}</span>
</button>
<button type="submit" id="button-search" class="button-raised button-primary ripple">
<i class="mdi mdi-magnify"></i>
<span class="hidden-xs">{'search'|t}</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div id="overlay" class="overlay hidden"></div>
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="custom"}
{include="includes"}
</head>
<body>
{include="page.header"}
You body goes here...
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html class="dark"{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="picwall"}
{include="includes"}
</head>
<body class="dark dark-toolbar">
{include="page.header"}
{if="count($linksToDisplay) === 0 && $is_logged_in"}
<div>
{'There is no cached thumbnail.'|t}
<a href="{$base_path}/admin/thumbnails">{'Try to synchronize them.'|t}</a>
</div>
{/if}
<div id="plugin_zone_start_picwall" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
<div id="picwall_container text-center" class="clearfix">
{loop="$linksToDisplay"}
<div class="picwall-pictureframe ripple">
{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="thumbnail" width="{$thumbnails_width}" height="{$thumbnails_height}" />
<a class="picwall-link" href="{$value.real_url}"><span class="info">{$value.title}</span></a>
{loop="$value.picwall_plugin"}
{$value}
{/loop}
</div>
{/loop}
</div>
<div id="plugin_zone_end_picwall" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
<div class="clearfix"></div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,120 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="pluginsadmin"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div id="pluginadmindiv" class="page-pluginadmin container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<noscript>
<p>{'You need to enable Javascript to change plugin loading order.'|t}</p>
</noscript>
<h1>{'Plugin administration'|t}</h1>
<p>Drag and drop your plugin to change the order in which they'll be called. Uncheck enabled plugin to disable them and vice-versa.</p>
<form action="{$base_path}/admin/plugins" method="post">
<input type="hidden" name="token" value="{$token}">
<section class="card">
<div class="card-title">{'Enabled Plugins'|t}</div>
{if="count($enabledPlugins)==0"}
<div class="card-body">
<p>{'No plugin enabled.'|t}</p>
</div>
{else}
<ul id="list-plugin-enabled" class="list-sortable list-checkable">
{loop="$enabledPlugins"}
<li class="list-item list-item-sortable" data-line="{$key}" data-order="{$counter}">
<input type="checkbox" class="filled-in" name="{$key}" id="checkbox-{$key}" checked>
<label for="checkbox-{$key}"></label>
<input type="hidden" name="order_{$key}" value="{$counter}">
<div class="list-item-content">
<h3 class="list-item-label">{function="str_replace('_', ' ', $key)"}</h3>
<div class="list-item-sublabel">{$value.description}</div>
</div>
<div class="list-sortable-handle mdi mdi-menu"></div>
</li>
{/loop}
</ul>
{/if}
</section>
<section class="card">
<div class="card-title">Disabled plugins</div>
{if="count($disabledPlugins)==0"}
<div class="card-body">
<p>{'No plugin disabled.'|t}</p>
</div>
{else}
<ul class="list-sortable list-checkable">
{loop="$disabledPlugins"}
<li class="list-item list-item-sortable" data-line="{$key}" data-order="{$counter}">
<input type="checkbox" class="filled-in" id="checkbox-{$key}" name="{$key}">
<label for="checkbox-{$key}"></label>
<div class="list-item-content">
<h3 class="list-item-label">{function="str_replace('_', ' ', $key)"}</h3>
<div class="list-item-sublabel">{$value.description}</div>
</div>
</li>
{/loop}
</ul>
{/if}
</section>
<div class="clearfix">
<p>
{"More plugins available"|t}
<a href="{$root_path}/doc/html/Community-&-Related-software/#third-party-plugins">{"in the documentation"|t}</a>.
</p>
<button type="submit" class="button-raised button-primary pull-right">Save plugins</button>
</div>
</form>
<hr class="darker">
<form action="{$base_path}/admin/plugins" method="post">
<input type="hidden" name="token" value="{$token}">
<section class="card">
<div class="card-title">Plugin parameters</div>
<div class="card-body">
{if="count($enabledPlugins)==0"}
<p>{'No plugin enabled.'|t}</p>
{else}
{$count=0}
{loop="$enabledPlugins"}
{if="count($value.parameters) > 0"}
{if="$count>0"}
<hr>
{/if}
{$count=$count+1}
<h2>{function="str_replace('_', ' ', $key)"}</h2>
{loop="$value.parameters"}
<div class="row plugin-param">
<div class="col-sm-4 plugin-param-key">
<label for="{$key}" {if="isset($value.desc)"}title="{$value.desc}"{/if}>{function="str_replace('_', ' ', $key)"}</label>
{if="isset($value.desc)"}<div class="sublabel">{$value.desc}</div>{/if}
</div>
<div class="col-sm-8">
<input type="text" name="{$key}" value="{$value.value}" id="{$key}" {if="isset($value.desc)"}placeholder="{$value.desc}"{/if}>
</div>
</div>
{/loop}
{/if}
{/loop}
{if="$count==0"}
<p>{'No parameter available.'|t}</p>
{/if}
{/if}
</div>
<div class="card-footer clearfix">
<button type="submit" name="parameters_form" class="button-raised button-primary pull-right">Save plugin parameters</button>
</div>
</section>
</form>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,119 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="server"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div id="toolsdiv" class="page-server">
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>{'Server administration'|t}</h1>
<div class="card">
<div class="card-header">{'General'|t}</div>
<div class="card-body">
<div class="list">
<div class="key-value-item">
<div>{'Index URL'|t}</div>
<div><a href="{$index_url}" title="{$pagetitle}">{$index_url}</a></div>
</div>
<div class="key-value-item">
<div>{'Base path'|t}</div>
<div>{$base_path}</div>
</div>
<div class="key-value-item">
<div>{'Client IP'|t}</div>
<div>{$client_ip}</div>
</div>
<div class="key-value-item">
<div>{'Trusted reverse proxies'|t}</div>
<div>
{if="count($trusted_proxies) > 0"}
<ul>
{loop="$trusted_proxies"}
<li>{$value}</li>
{/loop}
</ul>
{else}
{'N/A'|t}
{/if}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{include="server.requirements"}
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="card">
<div class="card-header">{'Version'|t}</div>
<div class="card-body">
<div class="list">
<div class="key-value-item">
<div>{'Current version'|t}</div>
<div>{$current_version}</div>
</div>
<div class="key-value-item">
<div>{'Latest release'|t}</div>
<div><a href="{$release_url}" title="{'Visit releases page on Github'|t}">{$latest_version}</a></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6 col-md-offset-3">
<div class="card">
<div class="card-header">{'Thumbnails'|t}</div>
<div class="card-body">
<div class="list">
<div class="key-value-item">
<div>{'Thumbnails status'|t}</div>
<div>
{if="$thumbnails_mode==='all'"}
{'All'|t}
{elseif="$thumbnails_mode==='common'"}
{'Only common media hosts'|t}
{else}
{'None'|t}
{/if}
</div>
</div>
</div>
</div>
{if="$thumbnails_mode!=='none'"}
<div class="card-footer">
<a href="{$base_path}/admin/thumbnails" title="{'Synchronize all link thumbnails'|t}" class="button-raised pull-right">{'Synchronize thumbnails'|t}</a>
<div class="clearfix"></div>
</div>
{/if}
</div>
</div>
<div class="col-md-6 col-md-offset-3">
<div class="card">
<div class="card-header">{'Cache'|t}</div>
<div class="card-footer">
<a href="{$base_path}/admin/clear-cache?type=main" class="button-raised pull-right">{'Clear main cache'|t}</a>
<a href="{$base_path}/admin/clear-cache?type=thumbnails" class="button-raised pull-right">{'Clear thumbnails cache'|t}</a>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,74 @@
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="card">
<div class="card-header">{'Permissions'|t}</div>
<div class="card-body">
{if="count($permissions) > 0"}
<p><i class="mdi mdi-close text-error"></i> {'There are permissions that need to be fixed.'|t}</p>
<ul>
{loop="$permissions"}
<li>{$value}</li>
{/loop}
</ul>
{else}
<p><i class="mdi mdi-check text-success"></i> {'All read/write permissions are properly set.'|t}</p>
{/if}
</div>
</div>
</div>
<div class="col-md-10 col-md-offset-1">
<div class="card">
<div class="card-header">PHP</div>
<div class="card-body">
<p>
<strong>{'Running PHP'|t} {$php_version}</strong>
{if="$php_has_reached_eol"}
<i class="mdi mdi-circle text-warning" aria-label="hidden"></i><br>
{'End of life: '|t} {$php_eol}
{else}
<i class="mdi mdi-circle text-success" aria-label="hidden"></i><br>
{/if}
</p>
<table>
<thead>
<tr>
<th>{'Extension'|t}</th>
<th>{'Usage'|t}</th>
<th>{'Status'|t}</th>
<th class="text-center">{'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 class="text-center">
{if="$value.loaded"}
{$classLoaded="text-success"}
{$strLoaded=t('Loaded')}
{else}
{$strLoaded=t('Not loaded')}
{if="$value.required"}
{$classLoaded="text-error"}
{else}
{$classLoaded="text-warning"}
{/if}
{/if}
<i class="mdi mdi-circle {$classLoaded}" aria-label="{$strLoaded}" title="{$strLoaded}"></i>
</td>
</tr>
{/loop}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="tag.cloud"}
{include="includes"}
</head>
<body>
{include="page.header"}
{include="tag.sort"}
<div class="center container">
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
<div id="cloudtag">
{loop="$tags"}
<a href="{$base_path}/?searchtags={$tags_url.$key1}{$tags_separator|urlencode}{$search_tags_url}" style="font-size:{$value.size}em;">{$key}</a
><span class="link-tag"><a href="{$base_path}/add-tag/{$tags_url.$key1}" title="{'Filter by tag'|t}" class="count">{$value.count}</a></span>
{loop="$value.tag_plugin"}
{$value}
{/loop}
{/loop}
</div>
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="tag.list"}
{include="includes"}
</head>
<body>
{include="page.header"}
{include="tag.sort"}
<div class="container">
{$countTags=count($tags)}
<div id="plugin_zone_start_tagcloud" class="plugin_zone">
{loop="$plugin_start_zone"}
{$value}
{/loop}
</div>
<div id="taglist" class="card">
<div class="card-header">
<div class="pull-right"><a href="{$base_path}/?searchtags={$search_tags|urlencode}" title="{'List all links with those tags'|t}">{$countTags} {'tags'|t}</a></div>
{'Tag list'|t}
</div>
<form class="card-search" method="get">
<input type="hidden" name="do" value="taglist">
<input type="search" name="searchtags" 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}"
>
</form>
{loop="tags"}
<div class="list-item-flex is-control-opaque-hover is-highlighted-hover">
<div class="list-item-start list-item-text">
{$value}
</div>
<div class="list-item-middle list-item-text">
<a href="{$base_path}/?searchtags={$key|urlencode} {$search_tags|urlencode}" class="tag-link">{$key}</a>
{loop="$value.tag_plugin"}
{$value}
{/loop}
</div>
<div class="list-item-end list-item-controls">
<a href="{$base_path}/add-tag/{$key|urlencode}" title="{'Add tag'|t} {$key} {'to the filters'|t}" class="count list-item-control">
<i class="mdi mdi-magnify-plus-outline"></i>
</a>
{if="$is_logged_in"}
<a href="{$base_path}/admin/tags?fromtag={$key|urlencode}" title="{'Rename tag'|t} {$key}" data-tag="{$key}" class="rename-tag list-item-control">
<i class="mdi mdi-pencil"></i>
</a>
<a href="#" class="delete-tag list-item-control" data-tag="{$key}" title="{'Delete tag'|t} {$key}"><i class="mdi mdi-delete"></i></a>
{/if}
</div>
</div>
{/loop}
</div>
<div id="plugin_zone_end_tagcloud" class="plugin_zone">
{loop="$plugin_end_zone"}
{$value}
{/loop}
</div>
</div>
{if="$is_logged_in"}
<input type="hidden" name="taglist" value="{loop="$tags"}{$key} {/loop}">
{/if}
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,7 @@
<div class="subheader">
<div class="container text-center">
<a class="button-inverse button-default{if="$pageName === 'tag.cloud'"} active{/if}" href="{$base_path}/tags/cloud" title="{'Cloud'|t}">{'Cloud'|t}</a>
<a class="button-inverse button-default{if="$pageName === 'tag.list' && $_GET['sort'] === 'usage'"} active{/if}" href="{$base_path}/tags/list?sort=usage" title="{'Most used'|t}">{'Most used'|t}</a>
<a class="button-inverse button-default{if="$pageName === 'tag.list' && $_GET['sort'] === 'alpha'"} active{/if}" href="{$base_path}/tags/list?sort=alpha" title="{'Alphabetical'|t}">{'Alphabetical'|t}</a>
</div>
</div>
@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="thumbnails"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div class="page-thumbnails container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="card">
<h1 class="card-header">{'Thumbnails update'|t}</h1>
<div class="card-body">
<div class="thumbnail-placeholder" style="width: {$thumbnails_width}px; height: {$thumbnails_height}px;">
</div>
<div class="thumbnail-link-title">
Loading...
</div>
<div class="progress-bar">
<div class="progress-actual"></div>
</div>
<div class="progress-counter">
<span class="progress-current">0</span> / <span class="progress-total">{$ids|count}</span>
</div>
<input type="hidden" name="ids" value="{function="implode(',', $ids)"}" />
</div>
</div>
</div>
</div>
</div>
{include="page.footer"}
</body>
</html>
@@ -0,0 +1,240 @@
<!DOCTYPE html>
<html{if="$language !== 'auto'"} lang="{$language}"{/if}>
<head>
{$pageName="tools"}
{include="includes"}
</head>
<body>
{include="page.header"}
<div id="toolsdiv" class="page-tools container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="card">
<h1 class="card-header">{'Settings'|t}</h1>
<div class="list-action list-big">
<a class="list-item ripple" href="{$base_path}/admin/configure">
<div class="row">
<div class="col-sm-2 col-xs-3">
<div class="round-image-container">
<i class="mdi mdi-settings" title="{'Configure your Shaarli'|t}"></i>
</div>
</div>
<div class="col-sm-10 col-xs-9">
<div class="list-item-label">{'Configure your Shaarli'|t}</div>
<div class="list-item-sublabel">{'Change Title, timezone...'|t}</div>
</div>
</div>
</a>
{if="!$openshaarli"}
<a class="list-item ripple" href="{$base_path}/admin/password">
<div class="row">
<div class="col-sm-2 col-xs-3">
<div class="round-image-container">
<i class="mdi mdi-lock" title="{'Change password'|t}"></i>
</div>
</div>
<div class="col-sm-10 col-xs-9">
<div class="list-item-label">{'Change password'|t}</div>
<div class="list-item-sublabel">{'Change your password'|t}</div>
</div>
</div>
</a>
{/if}
<a class="list-item ripple" href="{$base_path}/admin/plugins">
<div class="row">
<div class="col-sm-2 col-xs-3">
<div class="round-image-container">
<i class="mdi mdi-puzzle" title="{'Plugin administration'|t}"></i>
</div>
</div>
<div class="col-sm-10 col-xs-9">
<div class="list-item-label">{'Plugin administration'|t}</div>
<div class="list-item-sublabel">{'Enable, disable and configure plugins'|t}</div>
</div>
</div>
</a>
<a class="list-item ripple" href="{$base_path}/admin/server">
<div class="row">
<div class="col-sm-2 col-xs-3">
<div class="round-image-container">
<i class="mdi mdi-server" title="{'Check instance\'s server configuration'|t}"></i>
</div>
</div>
<div class="col-sm-10 col-xs-9">
<div class="list-item-label">{'Server administration'|t}</div>
<div class="list-item-sublabel">{'Check instance\'s server configuration'|t}</div>
</div>
</div>
</a>
<a class="list-item ripple" href="{$base_path}/admin/tags">
<div class="row">
<div class="col-sm-2 col-xs-3">
<div class="round-image-container">
<i class="mdi mdi-tag-multiple" title="{'Tags'|t}"></i>
</div>
</div>
<div class="col-sm-10 col-xs-9">
<div class="list-item-label">{'Tags'|t}</div>
<div class="list-item-sublabel">{'Rename or delete a tag in all links'|t}</div>
</div>
</div>
</a>
<a class="list-item ripple" href="{$base_path}/admin/import">
<div class="row">
<div class="col-sm-2 col-xs-3">
<div class="round-image-container">
<i class="mdi mdi-file-import" title="{'Import'|t}"></i>
</div>
</div>
<div class="col-sm-10 col-xs-9">
<div class="list-item-label">{'Import'|t}</div>
<div class="list-item-sublabel">{'Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)'|t}</div>
</div>
</div>
</a>
<a class="list-item ripple" href="{$base_path}/admin/export">
<div class="row">
<div class="col-sm-2 col-xs-3">
<div class="round-image-container">
<i class="mdi mdi-file-export" title="{'Export'|t}"></i>
</div>
</div>
<div class="col-sm-10 col-xs-9">
<div class="list-item-label">{'Export'|t}</div>
<div class="list-item-sublabel">{'Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)'|t}</div>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
{if="!empty($linkcount)"}
<div class="row">
<div class="col-md-8 col-md-offset-2">
<hr class="darker"/>
<h2 class="mtm">{'Statistics'|t}</h2>
<ul>
<li><strong>{$linkcount}</strong> links in total</li>
<li><strong>{$privateLinkcount}</strong> private links</li>
</ul>
</div>
</div>
{/if}
{if="isset($tools_plugin)"}
<div class="row">
<div class="col-md-8 col-md-offset-2">
<hr class="darker"/>
<h2 class="mtm">Plugin settings</h2>
{loop="$tools_plugin"}
{$value}
{/loop}
</div>
</div>
{/if}
<div class="row">
<div class="col-md-8 col-md-offset-2">
<hr class="darker"/>
<h2 class="mtm">Bookmarklet</h2>
<p>You can easily bookmark links from anywhere on the web via bookmarklets right below.</p>
<p>They can be dragged and dropped among your browser's bookmarks. Then, you just have to click on them from your bookmarks menu.</p>
<div class="row">
<div class="col-xs-6 text-center">
<a class="bookmarklet"
href="javascript:(
function(){
var%20url%20=%20location.href;
var%20title%20=%20document.title%20||%20url;
var%20desc=document.getSelection().toString();
if(desc.length>4000){
desc=desc.substr(0,4000)+'...';
alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}');
}
window.open(
'{$pageabsaddr}admin/shaare?post='%20+%20encodeURIComponent(url)+
'&amp;title='%20+%20encodeURIComponent(title)+
'&amp;description='%20+%20encodeURIComponent(desc)+
'&amp;source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1'
);
}
)();">
<img src="{$asset_path}/dist/img/tools/star-circle.png#" alt="" /> {'Shaare link'|t}
</a>
</div>
<div class="col-xs-6 text-center">
<a class="bookmarklet"
href="javascript:(
function(){
var%20desc=document.getSelection().toString();
if(desc.length>4000){
desc=desc.substr(0,4000)+'...';
alert('{function="str_replace(' ', '%20', t('The selected text is too long, it will be truncated.'))"}');
}
window.open(
'{$pageabsaddr}?private=1&amp;post='+
'&amp;description='%20+%20encodeURIComponent(desc)+
'&amp;source=bookmarklet','_blank','menubar=no,height=800,width=600,toolbar=no,scrollbars=yes,status=no,dialog=1'
);
}
)();">
<img src="{$asset_path}/dist/img/tools/star-circle.png#" alt="" /> {'Add Note'|t}
</a>
</div>
</div>
</div>
</div>
<div class="row mbm">
<div class="col-md-8 col-md-offset-2">
<hr class="darker"/>
<h2 class="mtm" id="firefox-api-title">{'3rd party'|t}</h2>
<ul>
<li>
<a href="https://addons.mozilla.org/fr/firefox/addon/shaarli/" title="Firefox {'Plugin'|t}" class="large-icon-button ripple">
<i class="mdi mdi-firefox"></i>
Firefox {'plugin'|t}
</a>
</li>
<li>
<a href="https://chromewebstore.google.com/detail/add-to-shaarli/jhfblapoehcfajokolimghdfmeeakbee" title="Chrome {'Plugin'|t}" class="large-icon-button ripple">
<i class="mdi mdi-google-chrome"></i>
Chrome {'plugin'|t}
</a>
</li>
<li>
<a href="https://f-droid.org/fr/packages/com.dimtion.shaarlier/" title="Android Shaarlier" class="large-icon-button ripple">
<i class="mdi mdi-android"></i>
Shaarlier
</a>
</li>
<li>
<a href="https://stakali.toneiv.eu/" title="Android Stakali" class="large-icon-button ripple">
<i class="mdi mdi-android"></i>
Stakali
</a>
</li>
<li>
<a href="https://github.com/lockcp/ShaarliOS" class="large-icon-button ripple">
<i class="mdi mdi-apple-ios"></i>
iOS
</a>
</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<p>Other <a href="https://shaarli.readthedocs.io/en/master/Community-and-related-software.html">{'Community and related software'|t}</a>.</p>
</div>
</div>
{loop="$tools_plugin"}
{$value}
{/loop}
</div>
{include="page.footer"}
</body>
</html>