new design, pagination & more

This commit is contained in:
Nicolas Lœuillet 2013-08-05 21:56:32 +02:00
parent 55821e04c1
commit 6a361945ea
31 changed files with 467 additions and 371 deletions

View file

@ -6,11 +6,9 @@ poche is based on :
* PHP Simple HTML DOM Parser (for Pocket import) http://simplehtmldom.sourceforge.net/ * PHP Simple HTML DOM Parser (for Pocket import) http://simplehtmldom.sourceforge.net/
* Session https://github.com/tontof/kriss_feed/blob/master/src/class/Session.php * Session https://github.com/tontof/kriss_feed/blob/master/src/class/Session.php
* Twig http://twig.sensiolabs.org * Twig http://twig.sensiolabs.org
* Flash messages https://github.com/plasticbrain/PHP-Flash-Messages
* Pagination https://github.com/daveismyname/pagination
poche is developed by Nicolas Lœuillet under the Do What the Fuck You Want to Public License poche is developed by Nicolas Lœuillet under the Do What the Fuck You Want to Public License
Contributors : Contributors : https://github.com/inthepoche/poche/graphs/contributors
Nicolas Lœuillet aka nico_somb
Tom.C. aka tmos
PeaceCopathe
Gregoire_M

198
inc/3rdparty/paginator.php vendored Normal file
View file

@ -0,0 +1,198 @@
<?php
/*
* PHP Pagination Class
*
* @author David Carr - dave@daveismyname.com - http://www.daveismyname.com
* @version 1.0
* @date October 20, 2013
*/
class Paginator{
/**
* set the number of items per page.
*
* @var numeric
*/
private $_perPage;
/**
* set get parameter for fetching the page number
*
* @var string
*/
private $_instance;
/**
* sets the page number.
*
* @var numeric
*/
private $_page;
/**
* set the limit for the data source
*
* @var string
*/
private $_limit;
/**
* set the total number of records/items.
*
* @var numeric
*/
private $_totalRows = 0;
/**
* __construct
*
* pass values when class is istantiated
*
* @param numeric $_perPage sets the number of iteems per page
* @param numeric $_instance sets the instance for the GET parameter
*/
public function __construct($perPage,$instance){
$this->_instance = $instance;
$this->_perPage = $perPage;
$this->set_instance();
}
/**
* get_start
*
* creates the starting point for limiting the dataset
* @return numeric
*/
private function get_start(){
return ($this->_page * $this->_perPage) - $this->_perPage;
}
/**
* set_instance
*
* sets the instance parameter, if numeric value is 0 then set to 1
*
* @var numeric
*/
private function set_instance(){
$this->_page = (int) (!isset($_GET[$this->_instance]) ? 1 : $_GET[$this->_instance]);
$this->_page = ($this->_page == 0 ? 1 : $this->_page);
}
/**
* set_total
*
* collect a numberic value and assigns it to the totalRows
*
* @var numeric
*/
public function set_total($_totalRows){
$this->_totalRows = $_totalRows;
}
/**
* get_limit
*
* returns the limit for the data source, calling the get_start method and passing in the number of items perp page
*
* @return string
*/
public function get_limit(){
return "LIMIT ".$this->get_start().",$this->_perPage";
}
/**
* page_links
*
* create the html links for navigating through the dataset
*
* @var sting $path optionally set the path for the link
* @var sting $ext optionally pass in extra parameters to the GET
* @return string returns the html menu
*/
public function page_links($path='?',$ext=null)
{
$adjacents = "2";
$prev = $this->_page - 1;
$next = $this->_page + 1;
$lastpage = ceil($this->_totalRows/$this->_perPage);
$lpm1 = $lastpage - 1;
$pagination = "";
if($lastpage > 1)
{
$pagination .= "<div class='pagination'>";
if ($this->_page > 1)
$pagination.= "<a href='".$path."$this->_instance=$prev"."$ext'>« previous</a>";
else
$pagination.= "<span class='disabled'>« previous</span>";
if ($lastpage < 7 + ($adjacents * 2))
{
for ($counter = 1; $counter <= $lastpage; $counter++)
{
if ($counter == $this->_page)
$pagination.= "<span class='current'>$counter</span>";
else
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
}
}
elseif($lastpage > 5 + ($adjacents * 2))
{
if($this->_page < 1 + ($adjacents * 2))
{
for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++)
{
if ($counter == $this->_page)
$pagination.= "<span class='current'>$counter</span>";
else
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
}
$pagination.= "...";
$pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
$pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";
}
elseif($lastpage - ($adjacents * 2) > $this->_page && $this->_page > ($adjacents * 2))
{
$pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
$pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
$pagination.= "...";
for ($counter = $this->_page - $adjacents; $counter <= $this->_page + $adjacents; $counter++)
{
if ($counter == $this->_page)
$pagination.= "<span class='current'>$counter</span>";
else
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
}
$pagination.= "..";
$pagination.= "<a href='".$path."$this->_instance=$lpm1"."$ext'>$lpm1</a>";
$pagination.= "<a href='".$path."$this->_instance=$lastpage"."$ext'>$lastpage</a>";
}
else
{
$pagination.= "<a href='".$path."$this->_instance=1"."$ext'>1</a>";
$pagination.= "<a href='".$path."$this->_instance=2"."$ext'>2</a>";
$pagination.= "..";
for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++)
{
if ($counter == $this->_page)
$pagination.= "<span class='current'>$counter</span>";
else
$pagination.= "<a href='".$path."$this->_instance=$counter"."$ext'>$counter</a>";
}
}
}
if ($this->_page < $counter - 1)
$pagination.= "<a href='".$path."$this->_instance=$next"."$ext'>next »</a>";
else
$pagination.= "<span class='disabled'>next »</span>";
$pagination.= "</div>\n";
}
return $pagination;
}
}

View file

@ -13,11 +13,13 @@ class Poche
public $store; public $store;
public $tpl; public $tpl;
public $messages; public $messages;
public $pagination;
function __construct($storage_type) function __construct($storage_type)
{ {
$this->store = new $storage_type(); $this->store = new $storage_type();
$this->init(); $this->init();
$this->messages = new Messages();
# installation # installation
if(!$this->store->isInstalled()) if(!$this->store->isInstalled())
@ -46,6 +48,8 @@ class Poche
$filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain'); $filter = new Twig_SimpleFilter('getDomain', 'Tools::getDomain');
$this->tpl->addFilter($filter); $this->tpl->addFilter($filter);
$this->pagination = new Paginator(PAGINATION, 'p');
Tools::initPhp(); Tools::initPhp();
Session::init(); Session::init();
} }
@ -54,7 +58,7 @@ class Poche
{ {
Tools::logm('poche still not installed'); Tools::logm('poche still not installed');
echo $this->tpl->render('install.twig', array( echo $this->tpl->render('install.twig', array(
'token' => Session::getToken(), 'token' => Session::getToken()
)); ));
if (isset($_GET['install'])) { if (isset($_GET['install'])) {
if (($_POST['password'] == $_POST['password_repeat']) if (($_POST['password'] == $_POST['password_repeat'])
@ -62,6 +66,11 @@ class Poche
# let's rock, install poche baby ! # let's rock, install poche baby !
$this->store->install($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login'])); $this->store->install($_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']));
Session::logout(); Session::logout();
Tools::logm('poche is now installed');
Tools::redirect();
}
else {
Tools::logm('error during installation');
Tools::redirect(); Tools::redirect();
} }
} }
@ -89,30 +98,32 @@ class Poche
if (DOWNLOAD_PICTURES) { if (DOWNLOAD_PICTURES) {
$content = filtre_picture($parametres_url['content'], $url->getUrl(), $last_id); $content = filtre_picture($parametres_url['content'], $url->getUrl(), $last_id);
} }
#$msg->add('s', _('the link has been added successfully')); $this->messages->add('s', _('the link has been added successfully'));
} }
else { else {
#$msg->add('e', _('error during insertion : the link wasn\'t added')); $this->messages->add('e', _('error during insertion : the link wasn\'t added'));
Tools::logm('error during insertion : the link wasn\'t added'); Tools::logm('error during insertion : the link wasn\'t added');
} }
} }
else { else {
#$msg->add('e', _('error during url preparation : the link wasn\'t added')); $this->messages->add('e', _('error during fetching content : the link wasn\'t added'));
Tools::logm('error during content fetch'); Tools::logm('error during content fetch');
} }
Tools::redirect();
break; break;
case 'delete': case 'delete':
if ($this->store->deleteById($id)) { if ($this->store->deleteById($id)) {
if (DOWNLOAD_PICTURES) { if (DOWNLOAD_PICTURES) {
remove_directory(ABS_PATH . $id); remove_directory(ABS_PATH . $id);
} }
#$msg->add('s', _('the link has been deleted successfully')); $this->messages->add('s', _('the link has been deleted successfully'));
Tools::logm('delete link #' . $id); Tools::logm('delete link #' . $id);
} }
else { else {
#$msg->add('e', _('the link wasn\'t deleted')); $this->messages->add('e', _('the link wasn\'t deleted'));
Tools::logm('error : can\'t delete link #' . $id); Tools::logm('error : can\'t delete link #' . $id);
} }
Tools::redirect();
break; break;
case 'toggle_fav' : case 'toggle_fav' :
$this->store->favoriteById($id); $this->store->favoriteById($id);
@ -169,9 +180,14 @@ class Poche
break; break;
default: # home view default: # home view
$entries = $this->store->getEntriesByView($view); $entries = $this->store->getEntriesByView($view);
$this->pagination->set_total(count($entries));
$page_links = $this->pagination->page_links('?view=' . $view . '&sort=' . $_SESSION['sort'] . '&');
$datas = $this->store->getEntriesByView($view, $this->pagination->get_limit());
$tpl_vars = array( $tpl_vars = array(
'entries' => $entries, 'entries' => $datas,
'page_links' => $page_links,
); );
Tools::logm('display ' . $view . ' view');
break; break;
} }
@ -183,6 +199,7 @@ class Poche
if (MODE_DEMO) { if (MODE_DEMO) {
$this->messages->add('i', 'in demo mode, you can\'t update your password'); $this->messages->add('i', 'in demo mode, you can\'t update your password');
Tools::logm('in demo mode, you can\'t do this'); Tools::logm('in demo mode, you can\'t do this');
Tools::redirect('?view=config');
} }
else { else {
if (isset($_POST['password']) && isset($_POST['password_repeat'])) { if (isset($_POST['password']) && isset($_POST['password_repeat'])) {
@ -195,6 +212,7 @@ class Poche
} }
else { else {
$this->messages->add('e', 'the two fields have to be filled & the password must be the same in the two fields'); $this->messages->add('e', 'the two fields have to be filled & the password must be the same in the two fields');
Tools::redirect('?view=config');
} }
} }
} }
@ -205,7 +223,7 @@ class Poche
if (!empty($_POST['login']) && !empty($_POST['password'])) { if (!empty($_POST['login']) && !empty($_POST['password'])) {
if (Session::login($_SESSION['login'], $_SESSION['pass'], $_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']))) { if (Session::login($_SESSION['login'], $_SESSION['pass'], $_POST['login'], Tools::encodeString($_POST['password'] . $_POST['login']))) {
Tools::logm('login successful'); Tools::logm('login successful');
$this->messages->add('s', 'login successful, welcome to your poche'); $this->messages->add('s', 'welcome to your poche');
if (!empty($_POST['longlastingsession'])) { if (!empty($_POST['longlastingsession'])) {
$_SESSION['longlastingsession'] = 31536000; $_SESSION['longlastingsession'] = 31536000;
$_SESSION['expires_on'] = time() + $_SESSION['longlastingsession']; $_SESSION['expires_on'] = time() + $_SESSION['longlastingsession'];
@ -216,11 +234,11 @@ class Poche
session_regenerate_id(true); session_regenerate_id(true);
Tools::redirect($referer); Tools::redirect($referer);
} }
$this->messages->add('e', 'login failed, bad login or password'); $this->messages->add('e', 'login failed: bad login or password');
Tools::logm('login failed'); Tools::logm('login failed');
Tools::redirect(); Tools::redirect();
} else { } else {
$this->messages->add('e', 'login failed, you have to fill all fields'); $this->messages->add('e', 'login failed: you have to fill all fields');
Tools::logm('login failed'); Tools::logm('login failed');
Tools::redirect(); Tools::redirect();
} }
@ -228,7 +246,7 @@ class Poche
public function logout() public function logout()
{ {
$this->messages->add('s', 'logout successful, see you soon!'); $this->messages->add('s', 'see you soon!');
Tools::logm('logout'); Tools::logm('logout');
Session::logout(); Session::logout();
Tools::redirect(); Tools::redirect();

View file

@ -197,7 +197,7 @@ class Tools
{ {
if (DEBUG_POCHE) { if (DEBUG_POCHE) {
$t = strval(date('Y/m/d_H:i:s')) . ' - ' . $_SERVER["REMOTE_ADDR"] . ' - ' . strval($message) . "\n"; $t = strval(date('Y/m/d_H:i:s')) . ' - ' . $_SERVER["REMOTE_ADDR"] . ' - ' . strval($message) . "\n";
file_put_contents('./log.txt', $t, FILE_APPEND); file_put_contents(CACHE . '/log.txt', $t, FILE_APPEND);
} }
} }

View file

@ -8,7 +8,7 @@
* @license http://www.wtfpl.net/ see COPYING file * @license http://www.wtfpl.net/ see COPYING file
*/ */
define ('POCHE_VERSION', '1.0-alpha'); define ('POCHE_VERSION', '1.0-beta');
define ('MODE_DEMO', FALSE); define ('MODE_DEMO', FALSE);
define ('DEBUG_POCHE', FALSE); define ('DEBUG_POCHE', FALSE);
define ('CONVERT_LINKS_FOOTNOTES', FALSE); define ('CONVERT_LINKS_FOOTNOTES', FALSE);
@ -22,24 +22,26 @@ define ('TPL', './tpl');
define ('LOCALE', './locale'); define ('LOCALE', './locale');
define ('CACHE', './cache'); define ('CACHE', './cache');
define ('LANG', 'fr_FR.UTF8'); define ('LANG', 'fr_FR.UTF8');
define ('PAGINATION', '10');
define ('THEME', 'light');
$storage_type = 'sqlite'; # sqlite, mysql, (file, not yet) $storage_type = 'sqlite'; # sqlite, mysql, (file, not yet)
# /!\ Be careful if you change the lines below /!\ # /!\ Be careful if you change the lines below /!\
require_once './inc/poche/Tools.class.php'; require_once './inc/poche/Tools.class.php';
require_once './inc/poche/Url.class.php'; require_once './inc/poche/Url.class.php';
require_once './inc/3rdparty/Session.class.php';
require_once './inc/3rdparty/class.messages.php';
require_once './inc/poche/Poche.class.php'; require_once './inc/poche/Poche.class.php';
require_once './inc/3rdparty/Readability.php'; require_once './inc/3rdparty/Readability.php';
require_once './inc/3rdparty/Encoding.php'; require_once './inc/3rdparty/Encoding.php';
require_once './inc/3rdparty/Session.class.php';
require_once './inc/store/store.class.php'; require_once './inc/store/store.class.php';
require_once './inc/store/' . $storage_type . '.class.php'; require_once './inc/store/' . $storage_type . '.class.php';
require_once './vendor/autoload.php'; require_once './vendor/autoload.php';
require_once './inc/3rdparty/simple_html_dom.php'; require_once './inc/3rdparty/simple_html_dom.php';
require_once './inc/3rdparty/class.messages.php'; require_once './inc/3rdparty/paginator.php';
if (DOWNLOAD_PICTURES) { if (DOWNLOAD_PICTURES) {
require_once './inc/poche/pochePictures.php'; require_once './inc/poche/pochePictures.php';
} }
$poche = new Poche($storage_type); $poche = new Poche($storage_type);
$poche->messages = new Messages();

View file

@ -114,7 +114,7 @@ class Sqlite extends Store {
return $entry[0]; return $entry[0];
} }
public function getEntriesByView($view) { public function getEntriesByView($view, $limit = '') {
parent::__construct(); parent::__construct();
switch ($_SESSION['sort']) switch ($_SESSION['sort'])
@ -152,6 +152,8 @@ class Sqlite extends Store {
break; break;
} }
$sql .= ' ' . $limit;
$query = $this->executeQuery($sql, $params); $query = $this->executeQuery($sql, $params);
$entries = $query->fetchAll(); $entries = $query->fetchAll();

View file

@ -62,7 +62,8 @@ else {
} }
# because messages can be added in $poche->action(), we have to add this entry now (we can add it before) # because messages can be added in $poche->action(), we have to add this entry now (we can add it before)
$tpl_vars = array_merge($tpl_vars, array('messages' => $poche->messages->display())); $messages = $poche->messages->display('all', FALSE);
$tpl_vars = array_merge($tpl_vars, array('messages' => $messages));
# Aaaaaaand action ! # Aaaaaaand action !
echo $poche->tpl->render($tpl_file, $tpl_vars); echo $poche->tpl->render($tpl_file, $tpl_vars);

View file

@ -1,3 +1,3 @@
<footer class="mr2 mt3 smaller"> <footer class="w600p center mt3 smaller txtright">
<p>{% trans "powered by" %} <a href="http://inthepoche.com">poche</a></p> <p>{% trans "powered by" %} <a href="http://inthepoche.com">poche</a></p>
</footer> </footer>

View file

@ -4,5 +4,6 @@
<link rel="apple-touch-icon-precomposed" href="./tpl/img/apple-touch-icon-precomposed.png"> <link rel="apple-touch-icon-precomposed" href="./tpl/img/apple-touch-icon-precomposed.png">
<link rel="stylesheet" href="./tpl/css/knacss.css" media="all"> <link rel="stylesheet" href="./tpl/css/knacss.css" media="all">
<link rel="stylesheet" href="./tpl/css/style.css" media="all"> <link rel="stylesheet" href="./tpl/css/style.css" media="all">
<link rel="stylesheet" href="./tpl/css/style-light.css" media="all" title="light-style"> <link rel="stylesheet" href="./tpl/css/style-{{ constant('THEME') }}.css" media="all" title="{{ constant('THEME') }} theme">
<link rel="stylesheet" href="./tpl/css/messages.css" media="all"> <link rel="stylesheet" href="./tpl/css/messages.css" media="all">
<link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>

View file

@ -1,5 +1 @@
<ul id="messages"> {{ messages | raw }}
{% for message in messages %}
<li>{{ message|e }}</li>
{% endfor %}
</ul>

View file

@ -1,3 +1,3 @@
<header> <header class="w600p center mbm">
<h1><a href="./"><img src="./tpl/img/logo.png" alt="logo poche" /></a>poche</h1> <h1><a href="./" title="{% trans "back to home" %}" ><img src="./tpl/img/logo.png" alt="logo poche" /></a></h1>
</header> </header>

View file

@ -11,49 +11,47 @@
</ul> </ul>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div id="content"> <h2>{% trans "Bookmarklet" %}</h2>
<h2>{% trans "Bookmarklet" %}</h2> <p>{% trans "Thanks to the bookmarklet, you will be able to easily add a link to your poche." %} {% trans "Have a look to this documentation:" %} <a href="http://inthepoche.com/?pages/Documentation">inthepoche.com</a>.</p>
<p>{% trans "Thanks to the bookmarklet, you will be able to easily add a link to your poche." %} {% trans "Have a look to this documentation:" %} <a href="http://inthepoche.com/?pages/Documentation">inthepoche.com</a>.</p> <p>{% trans "Drag & drop this link to your bookmarks bar and have fun with poche." %}</p>
<p>{% trans "Drag & drop this link to your bookmarks bar and have fun with poche." %}</p> <p class="txtcenter"><a ondragend="this.click();" style="cursor: move; border: 1px dashed grey; background: white; padding: 5px;" title="i am a bookmarklet, use me !" href="javascript:if(top['bookmarklet-url@inthepoche.com']){top['bookmarklet-url@inthepoche.com'];}else{(function(){var%20url%20=%20location.href%20||%20url;window.open('{{ poche_url }}?action=add&url='%20+%20btoa(url),'_self');})();void(0);}">{% trans "poche it!" %}</a></p>
<p><a ondragend="this.click();" style="cursor: move; border: 1px dashed grey; background: white;" title="i am a bookmarklet, use me !" href="javascript:if(top['bookmarklet-url@inthepoche.com']){top['bookmarklet-url@inthepoche.com'];}else{(function(){var%20url%20=%20location.href%20||%20url;window.open('{{ poche_url }}?action=add&url='%20+%20btoa(url),'_self');})();void(0);}">{% trans "poche it!" %}</a></p>
<h2>{% trans "Updating poche" %}</h2> <h2>{% trans "Updating poche" %}</h2>
<p><ul> <p><ul>
<li>{% trans "your version" %} : <strong>{{ constant('POCHE_VERSION') }}</strong></li> <li>{% trans "your version" %} : <strong>{{ constant('POCHE_VERSION') }}</strong></li>
<li>{% trans "latest stable version" %} : {{ prod }}. {% if compare_prod == -1 %}<strong><a href="http://inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche">{% trans "a more recent stable version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li> <li>{% trans "latest stable version" %} : {{ prod }}. {% if compare_prod == -1 %}<strong><a href="http://inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche">{% trans "a more recent stable version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li>
<li>{% trans "latest dev version" %} : {{ dev }}. {% if compare_dev == -1 %}<strong><a href="http://inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche">{% trans "a more recent development version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li> <li>{% trans "latest dev version" %} : {{ dev }}. {% if compare_dev == -1 %}<strong><a href="http://inthepoche.com/?pages/T%C3%A9l%C3%A9charger-poche">{% trans "a more recent development version is available." %}</a></strong>{% else %}{% trans "you are up to date." %}{% endif %}</li>
</ul> </ul>
</p> </p>
<h2>{% trans "Change your password" %}</h2> <h2>{% trans "Change your password" %}</h2>
<form method="post" action="?config" name="loginform"> <form method="post" action="?config" name="loginform">
<fieldset class="w500p"> <fieldset class="w500p">
<div class="row"> <div class="row">
<label class="col w150p" for="password">{% trans "New password" %}</label> <label class="col w150p" for="password">{% trans "New password:" %}</label>
<input class="col" type="password" id="password" name="password" placeholder="{% trans "Password" %}" tabindex="2"> <input class="col" type="password" id="password" name="password" placeholder="{% trans "Password" %}" tabindex="2">
</div> </div>
<div class="row"> <div class="row">
<label class="col w150p" for="password_repeat">{% trans "Repeat your new password" %}</label> <label class="col w150p" for="password_repeat">{% trans "Repeat your new password:" %}</label>
<input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="{% trans "Password" %}" tabindex="3"> <input class="col" type="password" id="password_repeat" name="password_repeat" placeholder="{% trans "Password" %}" tabindex="3">
</div> </div>
<div class="row mts txtcenter"> <div class="row mts txtcenter">
<button class="bouton" type="submit" tabindex="4">{% trans "Update" %}</button> <button class="bouton" type="submit" tabindex="4">{% trans "Update" %}</button>
</div> </div>
</fieldset> </fieldset>
<input type="hidden" name="returnurl" value="{{ referer }}"> <input type="hidden" name="returnurl" value="{{ referer }}">
<input type="hidden" name="token" value="{{ token }}"> <input type="hidden" name="token" value="{{ token }}">
</form> </form>
<h2>{% trans "Import" %}</h2> <h2>{% trans "Import" %}</h2>
<p>{% trans "Please execute the import script locally, it can take a very long time." %}</p> <p>{% trans "Please execute the import script locally, it can take a very long time." %}</p>
<p>{% trans "More infos in the official doc:" %} <a href="http://inthepoche.com/?pages/Documentation">inthepoche.com</a></p> <p>{% trans "More infos in the official doc:" %} <a href="http://inthepoche.com/?pages/Documentation">inthepoche.com</a></p>
<p><ul> <p><ul>
<li><a href="./?import&from=pocket">{% trans "import from Pocket" %}</a> (you must have a "ril_export.html" file on your server)</li> <li><a href="./?import&from=pocket">{% trans "import from Pocket" %}</a> (you must have a "ril_export.html" file on your server)</li>
<li><a href="./?import&from=readability">{% trans "import from Readability" %}</a> (you must have a "readability" file on your server)</li> <li><a href="./?import&from=readability">{% trans "import from Readability" %}</a> (you must have a "readability" file on your server)</li>
<li><a href="./?import&from=instapaper">{% trans "import from Instapaper" %}</a> (you must have a "instapaper-export.html" file on your server)</li> <li><a href="./?import&from=instapaper">{% trans "import from Instapaper" %}</a> (you must have a "instapaper-export.html" file on your server)</li>
</ul></p> </ul></p>
<h2>{% trans "Export your poche datas" %}</h2> <h2>{% trans "Export your poche datas" %}</h2>
<p><a href="./?export" target="_blank">{% trans "Click here" %}</a> {% trans "to export your poche datas." %}</p> <p><a href="./?export" target="_blank">{% trans "Click here" %}</a> {% trans "to export your poche datas." %}</p>
</div>
{% endblock %} {% endblock %}

View file

@ -1,4 +1,4 @@
.messages { width: 100%; -moz-border-radius: 4px; border-radius: 4px; display: block; padding: 10px 0; margin: 10px auto 10px; clear: both; } .messages { width: 400px; -moz-border-radius: 4px; border-radius: 4px; display: block; padding: 10px 0; margin: 10px auto 10px; clear: both; }
.messages a.closeMessage { margin: -14px -8px 0 0; display:none; width: 16px; height: 16px; float: right; background: url(../img/messages/close.png) no-repeat; } .messages a.closeMessage { margin: -14px -8px 0 0; display:none; width: 16px; height: 16px; float: right; background: url(../img/messages/close.png) no-repeat; }
/*.messages:hover a.closeMessage { visibility:visible; }*/ /*.messages:hover a.closeMessage { visibility:visible; }*/
.messages p { margin: 3px 0 3px 10px !important; padding: 0 10px 0 23px !important; font-size: 14px; line-height: 16px; } .messages p { margin: 3px 0 3px 10px !important; padding: 0 10px 0 23px !important; font-size: 14px; line-height: 16px; }

View file

@ -1,94 +0,0 @@
/*** GENERAL ***/
body {
color: #fff;
background-color: #0d0d0d;
}
a, a:hover, a:visited {
color: #fff;
}
#main ul#links li a.current {
background-color: #000;
color: #fff;
}
#links a:hover, .backhome a:hover, .support a:hover{
background-color: #fff;
color: #000;
}
input[type=submit].delete {
background : url('../img/dark/remove.png') no-repeat center center;
color : transparent;
}
#main .entrie {
color: #fff;
background-color: #000;
border: 1px solid #fff;
}
#main .entrie h2 a:hover {
color: #29B1E3;
}
a.fav span {
background: url('../img/dark/star-on.png') no-repeat;
}
a.fav span:hover {
background: url('../img/dark/star-off.png') no-repeat;
}
a.fav-off span {
background: url('../img/dark/star-off.png') no-repeat;
}
a.fav-off span:hover {
background: url('../img/dark/star-on.png') no-repeat;
}
a.archive span {
background: url('../img/dark/checkmark-on.png') no-repeat;
}
a.archive span:hover {
background: url('../img/dark/checkmark-off.png') no-repeat;
}
a.archive-off span {
background: url('../img/dark/checkmark-off.png') no-repeat;
}
a.archive-off span:hover {
background: url('../img/dark/checkmark-on.png') no-repeat;
}
a.twitter span {
background: url('../img/dark/twitter.png') no-repeat;
}
/*** ***/
/*** ARTICLE PAGE ***/
body.article {
color: #fff;
background-color: #0d0d0d;
}
#article header {
border-bottom: 1px solid #222222;
}
#article article {
border-bottom: 1px solid #222222;
}
.vieworiginal a {
color: #888888;
}
.entrie {
background-color: #fff;
}

View file

@ -1,47 +1,12 @@
/*** GENERAL ***/
body { a.back span {
color: #222222; background: url('../img/light/left.png') no-repeat;
background-color: #F1F1F1;
} }
a, a:hover, a:visited { a.top span {
color: #000; background: url('../img/light/top.png') no-repeat;
} }
.bouton {
background-color: #000;
color: #fff;
border: none;
}
.bouton:hover {
background-color: #222222;
color: #F1F1F1;
}
#main ul#links li a.current {
background-color: #000;
color: #fff;
}
#links a:hover, .backhome a:hover, .support a:hover{
background-color: #040707;
color: #F1F1F1;
}
input[type=submit].delete {
background : url('../img/light/remove.png') no-repeat center center;
color : transparent;
}
#main .entrie {
color: #2e2e2e;
background-color: #ffffff;
border: 1px solid #000;
}
#main .entrie h2 a:hover {
color: #F5BE00;
}
a.fav span { a.fav span {
background: url('../img/light/star-on.png') no-repeat; background: url('../img/light/star-on.png') no-repeat;
@ -83,26 +48,6 @@ a.email span {
background: url('../img/light/envelop.png') no-repeat; background: url('../img/light/envelop.png') no-repeat;
} }
/*** ***/ a.delete span {
/*** ARTICLE PAGE ***/ background: url('../img/light/remove.png') no-repeat;
body.article {
color: #222222;
background-color: #F1F1F1;
}
#article header {
border-bottom: 1px solid #222222;
}
#article article {
border-bottom: 1px solid #222222;
}
.vieworiginal a {
color: #888888;
}
.entrie {
background-color: #fff;
} }

View file

@ -1,6 +1,6 @@
/*** GENERAL ***/
body { body {
font: 20px/1.3em Palatino,Georgia,serif; font-size: 16px;
font-family: 'Roboto', sans-serif;
margin: 10px; margin: 10px;
} }
@ -16,6 +16,10 @@ header h1 {
border-radius: 2px; border-radius: 2px;
} }
#main {
margin: 0 auto;
}
#main ul#links { #main ul#links {
padding: 0; padding: 0;
list-style-type: none; list-style-type: none;
@ -36,6 +40,7 @@ header h1 {
padding: 0; padding: 0;
list-style-type: none; list-style-type: none;
text-align: center; text-align: center;
opacity: 0.5;
} }
#main ul#sort li { #main ul#sort li {
@ -47,31 +52,16 @@ header h1 {
cursor: pointer; cursor: pointer;
} }
ul#messages {
} #links a{
#main, #article {
margin: 0 auto;
}
#links a, .backhome a, .support a{
text-decoration: none; text-decoration: none;
padding: 5px 10px; padding: 5px 10px;
} }
#links a:hover, .backhome a:hover, .support a:hover{ #links a:hover{
-webkit-border-radius: 2px; -webkit-border-radius: 2px;
border-radius: 2px; border-radius: 2px;
} }
.support {
font-size: 14px;
}
footer {
text-align: right;
}
/*** ***/ /*** ***/
/*** LINKS DISPLAY ***/ /*** LINKS DISPLAY ***/
@ -80,33 +70,41 @@ footer {
cursor: pointer; cursor: pointer;
} }
input[type=submit].delete {
width : 16px;
height :16px;
border : none;
cursor: pointer;
font-size : 0;
}
#main #content { #main #content {
margin-top: 20px; margin-top: 20px;
} }
#main .entrie { #main #content h2 {
padding: 15px; font-size: 1.3em;
min-height: 8em; text-decoration: none;
border: 1px solid; }
#main #content .entrie {
border-bottom: 1px solid #222222;
} }
#main .entrie h2 a { #main .entrie h2 a {
text-decoration: none; text-decoration: none;
} }
#main .entrie ul.tools {
list-style-type: none;
}
#main .entrie ul.tools li {
/*display: inline;*/
}
.tools { .tools {
float: right; float: right;
text-align: right; text-align: right;
opacity: 0.5;
} }
.tools p {
font-size: 0.8em;}
/*
.tools ul { .tools ul {
padding: 0; margin: 0; padding: 0; margin: 0;
list-style-type: none; list-style-type: none;
@ -118,19 +116,7 @@ input[type=submit].delete {
.tools a.tool { .tools a.tool {
cursor: pointer; cursor: pointer;
} }*/
#article .tools {
position: relative;
display: inline;
top: 0px;
right: 0px;
width: 100%;
}
#article .tools ul li{
display: inline;
}
#main .entrie .tools a.tool span, #article .tools a.tool span { #main .entrie .tools a.tool span, #article .tools a.tool span {
display: inline-block; display: inline-block;
@ -146,10 +132,9 @@ input[type=submit].delete {
/*** ***/ /*** ***/
/*** ARTICLE PAGE ***/ /*** ARTICLE PAGE ***/
body.article { #article {
font: 20px/1.3em Palatino,Georgia,serif; margin: 0 auto;
} }
#article header { #article header {
text-align: left; text-align: left;
} }
@ -158,58 +143,106 @@ body.article {
text-decoration: none; text-decoration: none;
} }
.vieworiginal a { .vieworiginal a, .vieworiginal a:hover, .vieworiginal a:visited {
text-decoration: none; text-decoration: none;
color: #888888;
} }
.backhome { .backhome {
display: inline; display: inline;
} }
#article .tools {
position: relative;
display: inline;
top: 0px;
right: 0px;
width: 100%;
}
#article .tools ul li{
display: inline;
}
/*** GENERAL ***/
body {
color: #000;
}
a, a:hover, a:visited {
color: #000;
}
.bouton {
background-color: #000;
color: #fff;
border: none;
}
.bouton:hover {
background-color: #222222;
color: #F1F1F1;
}
#main ul#links li a.current {
background-color: #000;
color: #fff;
}
#links a:hover{
background-color: #040707;
color: #F1F1F1;
}
/*** ***/ /*** ***/
/*** ARTICLE PAGE ***/
#main #article header, #article article {
{ border-bottom: 1px solid #222222;
max-width: 60em; /* 960 px */
margin: 0 auto;
}
#content
{
width: 103.125%; /* 990px */
overflow: hidden;
margin-left: -1.562%; /* 15px */
margin-bottom: -1.875em; /* 30px */
} }
.entrie
{ /* Pagination */
width: 30.303%; /* 300px */ .pagination {
background-color: #fff; clear: both;
float: left; padding-bottom: 20px;
margin: 0 1.515% 1.875em; /* 15px 30px */ padding-top: 10px;
text-align: right;
}
.pagination a {
border: 1px solid #D5D5D5;
color: #333;
font-size: 11px;
font-weight: bold;
height: 25px;
padding: 4px 8px;
text-decoration: none;
margin:2px;
}
.pagination a:hover, .pagination a:active {
background:#efefef;
}
.pagination span.current {
background-color: #ccc;
border: 1px solid #D5D5D5;
color: #000;
font-size: 11px;
font-weight: bold;
height: 25px;
padding: 4px 8px;
text-decoration: none;
margin:2px;
}
.pagination span.disabled {
border: 1px solid #EEEEEE;
color: #DDDDDD;
margin:2px;
padding: 4px 8px;
font-size: 11px;
font-weight: bold;
} }
@media only screen and ( max-width: 40em ) /* 640px */ footer {
{ clear: both;
.entrie
{
width: 46.876%; /* 305px */
margin-bottom: 0.938em; /* 15px */
}
}
@media only screen and ( max-width: 20em ) /* 320px */
{
#content
{
width: 100%;
margin-left: 0;
}
.entrie
{
width: 100%;
margin-left: 0;
margin-right: 0;
}
} }

View file

@ -5,39 +5,29 @@
{% endblock %} {% endblock %}
{% block precontent %} {% block precontent %}
<ul id="sort"> <ul id="sort">
<li><a href="./?sort=ia"><img src="./tpl/img/up.png" title="{% trans "by date asc" %}" /></a> {% trans "by date" %} <a href="./?sort=id"><img src="./tpl/img/down.png" title="{% trans "by date desc" %}" /></a></li> <li><a href="./?sort=ia&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/top.png" alt="{% trans "by date asc" %}" title="{% trans "by date asc" %}" /></a> {% trans "by date" %} <a href="./?sort=id&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/down.png" alt="{% trans "by date desc" %}" title="{% trans "by date desc" %}" /></a></li>
<li><a href="./?sort=ta"><img src="./tpl/img/up.png" title="{% trans "by title asc" %}" /></a> {% trans "by title" %} <a href="./?sort=td"><img src="./tpl/img/down.png" title="{% trans "by title desc" %}" /></a></li> <li><a href="./?sort=ta&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/top.png" alt="{% trans "by title asc" %}" title="{% trans "by title asc" %}" /></a> {% trans "by title" %} <a href="./?sort=td&view={{ view }}"><img src="./tpl/img/{{ constant('THEME') }}/down.png" alt="{% trans "by title desc" %}" title="{% trans "by title desc" %}" /></a></li>
</ul> </ul>
{% endblock %} {% endblock %}
{% block messages %}
{% include '_messages.twig' %}
{% endblock %}
{% block content %} {% block content %}
<div id="content"> {{ page_links | raw }}
{% for entry in entries %} {% for entry in entries %}
<div id="entry-{{ entry.id|e }}" class="entrie mb2"> <div id="entry-{{ entry.id|e }}" class="entrie">
<span class="content"> <h2><a href="index.php?view=view&id={{ entry.id|e }}">{{ entry.title|e }}</a></h2>
<h2 class="h6-like"> <ul class="tools">
<a href="index.php?view=view&id={{ entry.id|e }}">{{ entry.title|e }}</a> <li>
</h2> <a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li>
<div class="tools"> <li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li>
<ul> <li><a title="{% trans "delete" %}" class="tool delete" href="./?action=delete&id={{ entry.id|e }}"><span></span></a></li>
<li> </li>
<a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li> </ul>
<li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li> <p>{{ entry.content|striptags|slice(0, 300) }}...</p>
<li><form method="post" style="display: inline;"><input type="hidden" name="token" id="token" value="{{ token }}" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="view" name="view" value="{{ view }}" /><input type="hidden" id="id" name="id" value="{{ entry.id|e }}" /><input type="submit" class="delete" title="{% trans "toggle delete" %}" /></form> <p class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></p>
</li>
</ul>
</div>
<div class="url">{{ entry.url | e | getDomain }}</div>
</span>
</div>
{% endfor %}
</div> </div>
{% endfor %}
{{ page_links | raw }}
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<script type="text/javascript" src="./tpl/js/jquery-1.9.1.min.js"></script> <script type="text/javascript" src="./tpl/js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="./tpl/js/jquery.masonry.min.js"></script>
<script type="text/javascript">$(window).load(function(){var e=3,t=function(){e=$(window).width()>640?3:$(window).width()>320?2:1};t();$(window).resize(t);$("#content").masonry({itemSelector:".entrie",columnWidth:function(t){return t/e}})})</script>
{% endblock %} {% endblock %}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 B

View file

Before

Width:  |  Height:  |  Size: 216 B

After

Width:  |  Height:  |  Size: 216 B

BIN
tpl/img/light/left.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

0
tpl/img/up.png → tpl/img/light/top.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

View file

@ -12,13 +12,17 @@
{% include '_head.twig' %} {% include '_head.twig' %}
{% include '_bookmarklet.twig' %} {% include '_bookmarklet.twig' %}
</head> </head>
<body class="light-style"> <body>
{% include '_top.twig' %} {% include '_top.twig' %}
<div id="main"> <div id="main">
{% block menu %}{% endblock %} {% block menu %}{% endblock %}
{% block precontent %}{% endblock %} {% block precontent %}{% endblock %}
{% block messages %}{% endblock %} {% block messages %}
{% include '_messages.twig' %}
{% endblock %}
<div id="content" class="w600p center">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div>
{% block js %}{% endblock %} {% block js %}{% endblock %}
</div> </div>
{% include '_footer.twig' %} {% include '_footer.twig' %}

View file

@ -1,18 +1,17 @@
{% extends "layout.twig" %} {% extends "layout.twig" %}
{% block title %}{% trans "home" %}{% endblock %} {% block title %}{% trans "home" %}{% endblock %}
{% block messages %}
{% include '_messages.twig' %}
{% endblock %}
{% block content %} {% block content %}
<div id="article" class="w600p"> <div id="article">
<div class="tools"> <div class="tools">
<ul> <ul class="tools">
<li><a href="./" title="{% trans "back to home" %}" class="tool">&larr;</a></li> <li>
<li><a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li> <li><a href="{{ referer }}" title="{% trans "back to home" %}" class="tool back"><span></span></a></li>
<li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li> <a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li>
<li><form method="post" style="display: inline;" action="index.php"><input type="hidden" name="token" id="token" value="{{ token }}" /><input type="hidden" id="view" name="view" value="index" /><input type="hidden" id="action" name="action" value="delete" /><input type="hidden" id="id" name="id" value="{{ entry.id|e }}" /><input type="submit" class="delete" title="{% trans "toggle delete" %}" /></form></li> <li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li>
{% if constant('SHARE_TWITTER') == 1 %}<li><a href="https://twitter.com/home?status={{entry.title}}%20{{ entry.url|e }}%20via%20@getpoche" target="_blank" class="tool twitter"><span></span></a></li>{% endif %} <li><a title="{% trans "delete" %}" class="tool delete" href="./?action=delete&id={{ entry.id|e }}"><span></span></a></li>
{% if constant('SHARE_MAIL') == 1 %}<li><a href="mailto:?subject={{ entry.title|e }}&body={{ entry.url|e }} via @getpoche" class="tool email"><span></span></a></li>{% endif %} {% if constant('SHARE_TWITTER') == 1 %}<li><a href="https://twitter.com/home?status={{entry.title}}%20{{ entry.url|e }}%20via%20@getpoche" target="_blank" class="tool twitter" title="{% trans "tweet" %}"><span></span></a></li>{% endif %}
{% if constant('SHARE_MAIL') == 1 %}<li><a href="mailto:?subject={{ entry.title|e }}&body={{ entry.url|e }} via @getpoche" class="tool email" title="{% trans "email" %}"><span></span></a></li>{% endif %}
</li>
</ul> </ul>
</div> </div>
<header class="mbm"> <header class="mbm">
@ -20,17 +19,22 @@
<div class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></div> <div class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></div>
</header> </header>
<article> <article>
<div id="readityourselfcontent"> {{ content | raw }}
{{ content | raw }} <div class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></div>
</div>
</article> </article>
<div class="vieworiginal txtright small"><a href="{{ entry.url|e }}" target="_blank" title="{% trans "original" %} : {{ entry.title|e }}">{{ entry.url | e | getDomain }}</a></div> <div class="tools">
<div class="backhome"> <ul class="tools">
<a href="./" title="{% trans "back to home" %}">&larr;</a> <li>
<a href="#" title="{% trans "back to top" %}">&uarr;</a> <li><a href="{{ referer }}" title="{% trans "back to home" %}" class="tool back"><span></span></a></li>
</div> <li><a href="#" title="{% trans "back to top" %}" class="tool top"><span></span></a></li>
<div class="support"> <a title="{% trans "toggle mark as read" %}" class="tool archive {% if entry.is_read == 0 %}archive-off{% endif %}" href="./?action=toggle_archive&id={{ entry.id|e }}"><span></span></a></li>
{% trans "this article appears wrong?" %} <a href="https://github.com/inthepoche/poche/issues/new">{% trans "create an issue" %}</a> {% trans "or" %} <a href="mailto:support@inthepoche.com?subject=Wrong display in poche&body={{ entry.url|e }}">{% trans "contact us by mail" %}</a> <li><a title="{% trans "toggle favorite" %}" class="tool fav {% if entry.is_fav == 0 %}fav-off{% endif %}" href="./?action=toggle_fav&id={{ entry.id|e }}"><span></span></a></li>
<li><a title="{% trans "delete" %}" class="tool delete" href="./?action=delete&id={{ entry.id|e }}"><span></span></a></li>
{% if constant('SHARE_TWITTER') == 1 %}<li><a href="https://twitter.com/home?status={{entry.title}}%20{{ entry.url|e }}%20via%20@getpoche" target="_blank" class="tool twitter" title="{% trans "tweet" %}"><span></span></a></li>{% endif %}
{% if constant('SHARE_MAIL') == 1 %}<li><a href="mailto:?subject={{ entry.title|e }}&body={{ entry.url|e }} via @getpoche" class="tool email" title="{% trans "email" %}"><span></span></a></li>{% endif %}
</li>
</ul>
<p>{% trans "this article appears wrong?" %} <a href="https://github.com/inthepoche/poche/issues/new">{% trans "create an issue" %}</a> {% trans "or" %} <a href="mailto:support@inthepoche.com?subject=Wrong display in poche&body={{ entry.url|e }}">{% trans "contact us by mail" %}</a></p>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}