Fix frontend pagination.

This commit is contained in:
flash 2018-05-16 22:48:33 +02:00
parent 233781a0f2
commit 48f68cfa2d
13 changed files with 157 additions and 93 deletions

View file

@ -11,6 +11,7 @@
&__option { &__option {
background: #9475b2; background: #9475b2;
color: #306;
height: 20px; height: 20px;
width: 20px; width: 20px;
@ -18,6 +19,11 @@
margin-right: 1px; margin-right: 1px;
} }
&--disabled {
color: #383838;
background: #777;
}
@media (max-width: @mio-news-mobile) { @media (max-width: @mio-news-mobile) {
height: 30px; height: 30px;
width: 30px; width: 30px;
@ -32,10 +38,12 @@
height: 100%; height: 100%;
text-align: center; text-align: center;
text-decoration: none; text-decoration: none;
color: #306; color: inherit;
&--prev, &--prev,
&--next, &--next,
&--first,
&--last,
&--active, &--active,
&:hover { &:hover {
font-weight: bold; font-weight: bold;

View file

@ -13,6 +13,7 @@
&__option { &__option {
background: #9475b2; background: #9475b2;
color: #306;
height: 20px; height: 20px;
width: 20px; width: 20px;
@ -20,6 +21,11 @@
margin-right: 1px; margin-right: 1px;
} }
&--disabled {
color: #383838;
background: #777;
}
@media (max-width: @mio-news-mobile) { @media (max-width: @mio-news-mobile) {
height: 30px; height: 30px;
width: 30px; width: 30px;
@ -34,10 +40,12 @@
height: 100%; height: 100%;
text-align: center; text-align: center;
text-decoration: none; text-decoration: none;
color: #306; color: inherit;
&--prev, &--prev,
&--next, &--next,
&--first,
&--last,
&--active, &--active,
&:hover { &:hover {
font-weight: bold; font-weight: bold;

View file

@ -7,8 +7,11 @@ $db = Database::connection();
$templating = $app->getTemplating(); $templating = $app->getTemplating();
$category_id = isset($_GET['c']) ? (int)$_GET['c'] : null; $category_id = isset($_GET['c']) ? (int)$_GET['c'] : null;
$post_id = isset($_GET['n']) ? (int)$_GET['n'] : null; $post_id = isset($_GET['p']) ? (int)$_GET['p'] : (isset($_GET['n']) ? (int)$_GET['n'] : null);
$page_id = (int)($_GET['p'] ?? 1); $posts_offset = (int)($_GET['o'] ?? 0);
$posts_take = 5;
$templating->vars(compact('posts_offset', 'posts_take'));
if ($post_id !== null) { if ($post_id !== null) {
$getPost = $db->prepare(' $getPost = $db->prepare('
@ -42,14 +45,18 @@ if ($post_id !== null) {
if ($category_id !== null) { if ($category_id !== null) {
$getCategory = $db->prepare(' $getCategory = $db->prepare('
SELECT SELECT
`category_id`, `category_name`, `category_description` c.`category_id`, c.`category_name`, c.`category_description`,
FROM `msz_news_categories` COUNT(p.`post_id`) AS `posts_count`
WHERE `category_id` = :category_id FROM `msz_news_categories` as c
LEFT JOIN `msz_news_posts` as p
ON c.`category_id` = p.`category_id`
WHERE c.`category_id` = :category_id
GROUP BY c.`category_id`
'); ');
$getCategory->bindValue(':category_id', $category_id, PDO::PARAM_INT); $getCategory->bindValue(':category_id', $category_id, PDO::PARAM_INT);
$category = $getCategory->execute() ? $getCategory->fetch() : false; $category = $getCategory->execute() ? $getCategory->fetch() : false;
if ($category === false) { if ($category === false || $posts_offset < 0 || $posts_offset >= $category['posts_count']) {
http_response_code(404); http_response_code(404);
echo $templating->render('errors.404'); echo $templating->render('errors.404');
return; return;
@ -70,20 +77,13 @@ if ($category_id !== null) {
ON u.`display_role` = r.`role_id` ON u.`display_role` = r.`role_id`
WHERE p.`category_id` = :category_id WHERE p.`category_id` = :category_id
ORDER BY `created_at` DESC ORDER BY `created_at` DESC
LIMIT 0, 5 LIMIT :offset, :take
'); ');
$getPosts->bindValue('offset', $posts_offset);
$getPosts->bindValue('take', $posts_take);
$getPosts->bindValue('category_id', $category['category_id'], PDO::PARAM_INT); $getPosts->bindValue('category_id', $category['category_id'], PDO::PARAM_INT);
$posts = $getPosts->execute() ? $getPosts->fetchAll() : false; $posts = $getPosts->execute() ? $getPosts->fetchAll() : false;
//$posts = $category->posts()->orderBy('created_at', 'desc')->paginate(5, ['*'], 'p', $page_id);
//if (!is_valid_page($posts, $page_id)) {
if ($posts === false) {
http_response_code(404);
echo $templating->render('errors.404');
return;
}
$getFeatured = $db->prepare(' $getFeatured = $db->prepare('
SELECT `post_id`, `post_title` SELECT `post_id`, `post_title`
FROM `msz_news_posts` FROM `msz_news_posts`
@ -95,7 +95,7 @@ if ($category_id !== null) {
$getFeatured->bindValue('category_id', $category['category_id'], PDO::PARAM_INT); $getFeatured->bindValue('category_id', $category['category_id'], PDO::PARAM_INT);
$featured = $getFeatured->execute() ? $getFeatured->fetchAll() : []; $featured = $getFeatured->execute() ? $getFeatured->fetchAll() : [];
echo $templating->render('news.category', compact('category', 'posts', 'featured', 'page_id')); echo $templating->render('news.category', compact('category', 'posts', 'featured'));
return; return;
} }
@ -112,6 +112,23 @@ $getCategories = $db->prepare('
'); ');
$categories = $getCategories->execute() ? $getCategories->fetchAll() : []; $categories = $getCategories->execute() ? $getCategories->fetchAll() : [];
$postsCount = (int)$db->query('
SELECT COUNT(p.`post_id`) as `posts_count`
FROM `msz_news_posts` as p
LEFT JOIN `msz_news_categories` as c
ON p.`category_id` = c.`category_id`
WHERE p.`is_featured` = true
AND c.`is_hidden` = false
')->fetchColumn();
$templating->var('posts_count', $postsCount);
if ($posts_offset < 0 || $posts_offset >= $postsCount) {
http_response_code(404);
echo $templating->render('errors.404');
return;
}
$getPosts = $db->prepare(' $getPosts = $db->prepare('
SELECT SELECT
p.`post_id`, p.`post_title`, p.`post_text`, p.`created_at`, p.`post_id`, p.`post_title`, p.`post_text`, p.`created_at`,
@ -128,17 +145,16 @@ $getPosts = $db->prepare('
WHERE p.`is_featured` = true WHERE p.`is_featured` = true
AND c.`is_hidden` = false AND c.`is_hidden` = false
ORDER BY p.`created_at` DESC ORDER BY p.`created_at` DESC
LIMIT 0, 5 LIMIT :offset, :take
'); ');
$getPosts->bindValue('offset', $posts_offset);
$getPosts->bindValue('take', $posts_take);
$posts = $getPosts->execute() ? $getPosts->fetchAll() : []; $posts = $getPosts->execute() ? $getPosts->fetchAll() : [];
//$posts = NewsPost::where('is_featured', true)->orderBy('created_at', 'desc')->paginate(5, ['*'], 'p', $page_id); if (!$posts) {
//if (!is_valid_page($posts, $page_id)) {
if ($posts === false) {
http_response_code(404); http_response_code(404);
echo $templating->render('errors.404'); echo $templating->render('errors.404');
return; return;
} }
echo $templating->render('news.index', compact('categories', 'posts', 'page_id')); echo $templating->render('news.index', compact('categories', 'posts'));

View file

@ -7,7 +7,8 @@ require_once __DIR__ . '/../misuzu.php';
$db = Database::connection(); $db = Database::connection();
$templating = $app->getTemplating(); $templating = $app->getTemplating();
$page_id = (int)($_GET['p'] ?? 1); $query_offset = (int)($_GET['o'] ?? 0);
$query_take = 15;
if (!$app->hasActiveSession()) { if (!$app->hasActiveSession()) {
http_response_code(403); http_response_code(403);
@ -397,9 +398,13 @@ switch ($settings_mode) {
break; break;
case 'sessions': case 'sessions':
/*$sessions = $settings_user->sessions() $getSessionCount = $db->prepare('
->orderBy('session_id', 'desc') SELECT COUNT(`session_id`)
->paginate(15, ['*'], 'p', $page_id);*/ FROM `msz_sessions`
WHERE `user_id` = :user_id
');
$getSessionCount->bindValue('user_id', $app->getUserId());
$sessionCount = $getSessionCount->execute() ? $getSessionCount->fetchColumn() : 0;
$getSessions = $db->prepare(' $getSessions = $db->prepare('
SELECT SELECT
@ -408,19 +413,30 @@ switch ($settings_mode) {
FROM `msz_sessions` FROM `msz_sessions`
WHERE `user_id` = :user_id WHERE `user_id` = :user_id
ORDER BY `session_id` DESC ORDER BY `session_id` DESC
LIMIT 0, 15 LIMIT :offset, :take
'); ');
$getSessions->bindValue('offset', $query_offset);
$getSessions->bindValue('take', $query_take);
$getSessions->bindValue('user_id', $app->getUserId()); $getSessions->bindValue('user_id', $app->getUserId());
$sessions = $getSessions->execute() ? $getSessions->fetchAll() : []; $sessions = $getSessions->execute() ? $getSessions->fetchAll() : [];
$templating->var('active_session_id', $app->getSessionId()); $templating->vars([
$templating->var('user_sessions', $sessions); 'active_session_id' => $app->getSessionId(),
'user_sessions' => $sessions,
'sessions_offset' => $query_offset,
'sessions_take' => $query_take,
'sessions_count' => $sessionCount,
]);
break; break;
case 'login-history': case 'login-history':
/*$login_attempts = $settings_user->loginAttempts() $getLoginAttemptsCount = $db->prepare('
->orderBy('attempt_id', 'desc') SELECT COUNT(`attempt_id`)
->paginate(15, ['*'], 'p', $page_id);*/ FROM `msz_login_attempts`
WHERE `user_id` = :user_id
');
$getLoginAttemptsCount->bindValue('user_id', $app->getUserId());
$loginAttemptsCount = $getLoginAttemptsCount->execute() ? $getLoginAttemptsCount->fetchColumn() : 0;
$getLoginAttempts = $db->prepare(' $getLoginAttempts = $db->prepare('
SELECT SELECT
@ -429,12 +445,19 @@ switch ($settings_mode) {
FROM `msz_login_attempts` FROM `msz_login_attempts`
WHERE `user_id` = :user_id WHERE `user_id` = :user_id
ORDER BY `attempt_id` DESC ORDER BY `attempt_id` DESC
LIMIT 0, 15 LIMIT :offset, :take
'); ');
$getLoginAttempts->bindValue('offset', $query_offset);
$getLoginAttempts->bindValue('take', $query_take);
$getLoginAttempts->bindValue('user_id', $app->getUserId()); $getLoginAttempts->bindValue('user_id', $app->getUserId());
$loginAttempts = $getLoginAttempts->execute() ? $getLoginAttempts->fetchAll() : []; $loginAttempts = $getLoginAttempts->execute() ? $getLoginAttempts->fetchAll() : [];
$templating->var('user_login_attempts', $loginAttempts); $templating->vars([
'user_login_attempts' => $loginAttempts,
'login_attempts_offset' => $query_offset,
'login_attempts_take' => $query_take,
'login_attempts_count' => $loginAttemptsCount,
]);
break; break;
} }

View file

@ -240,7 +240,6 @@ class Application extends ApplicationBase
$this->templatingInstance->addFilter('byte_symbol'); $this->templatingInstance->addFilter('byte_symbol');
$this->templatingInstance->addFilter('country_name', 'get_country_name'); $this->templatingInstance->addFilter('country_name', 'get_country_name');
$this->templatingInstance->addFilter('flip', 'array_flip'); $this->templatingInstance->addFilter('flip', 'array_flip');
$this->templatingInstance->addFilter('create_pagination');
$this->templatingInstance->addFilter('first_paragraph'); $this->templatingInstance->addFilter('first_paragraph');
$this->templatingInstance->addFilter('colour_get_css'); $this->templatingInstance->addFilter('colour_get_css');
$this->templatingInstance->addFilter('colour_get_inherit'); $this->templatingInstance->addFilter('colour_get_inherit');

View file

@ -16,70 +16,83 @@
</ul> </ul>
{% endmacro %} {% endmacro %}
{% macro pagination_segment(url_window, base_url, currentPage, classPrefix) %} {% macro paginate(itemCount, itemRange, currentOffset, baseUrl, classPrefix, alwaysRender, useRanges, offsetParam) %}
{% for page, url in url_window %}
<li class="{{ classPrefix }}pagination__option{{ currentPage == page ? ' ' ~ classPrefix ~ 'pagination__option--active' : '' }}">
<a href="{{ base_url ~ url|slice(2) }}" class="{{ classPrefix }}pagination__link{{ currentPage == page ? ' ' ~ classPrefix ~ 'pagination__link--active' : '' }}">
{{ page }}
</a>
</li>
{% endfor %}
{% endmacro %}
{% macro paginate(paginator, base_url, classPrefix, alwaysRender) %}
{% set alwaysRender = alwaysRender|default(false) %} {% set alwaysRender = alwaysRender|default(false) %}
{% if alwaysRender or paginator.lastPage > 1 %} {% if alwaysRender or itemCount > itemRange %}
{% set classPrefix = classPrefix|default('') %} {% set classPrefix = classPrefix|default('') %}
{% set separator = '%3F' in base_url|default('')|url_encode ? '&' : '?' %} {% set separator = '%3F' in baseUrl|default('')|url_encode ? '&' : '?' %}
{% set base_url = base_url ~ separator %} {% set baseUrl = baseUrl ~ separator %}
{% set pageCount = (itemCount / itemRange)|round(0, 'ceil') %}
{% set currentPage = currentOffset // itemRange %}
{% set useRanges = useRanges|default(true) %}
{% set offsetParam = offsetParam|default(useRanges ? 'o' : 'p') %}
<ul class="{{ classPrefix }}pagination"> <ul class="{{ classPrefix }}pagination">
{% if paginator.onFirstPage %} {% if currentPage < 1 %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--prev"> <li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--first {{ classPrefix }}pagination__option--disabled">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--first">
&laquo;
</span>
</li>
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--prev {{ classPrefix }}pagination__option--disabled">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--prev"> <span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--prev">
&laquo; &lsaquo;
</span> </span>
</li> </li>
{% else %} {% else %}
{% set firstUrl = baseUrl|slice(0, (baseUrl|length) - (separator|length)) %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--first">
<a href="{{ firstUrl }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--first" rel="first">
&laquo;
</a>
</li>
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--prev"> <li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--prev">
<a href="{{ base_url ~ paginator.previousPageUrl|slice(2) }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--prev" rel="prev"> <a href="{{ currentPage < 2 ? firstUrl : baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((currentPage - 1) * itemRange) : currentPage) }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--prev" rel="prev">
&laquo; &lsaquo;
</a> </a>
</li> </li>
{% endif %} {% endif %}
<li class="{{ classPrefix }}pagination__separator"></li> <li class="{{ classPrefix }}pagination__separator"></li>
{% from _self import pagination_segment %} {% set paginationStart = currentPage - 3 %}
{% set url_window = paginator|create_pagination %} {% set paginationStop = currentPage + 3 %}
{% if url_window.first is iterable %} {% for i in paginationStart..paginationStop %}
{{ pagination_segment(url_window.first, base_url, paginator.currentPage, classPrefix) }} {% if i >= 0 and i < pageCount %}
<li class="{{ classPrefix }}pagination__separator"></li> <li class="{{ classPrefix }}pagination__option{{ currentPage == i ? ' ' ~ classPrefix ~ 'pagination__option--active' : '' }}">
{% endif %} <a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? i * itemRange : i + 1) }}" class="{{ classPrefix }}pagination__link{{ currentPage == i ? ' ' ~ classPrefix ~ 'pagination__link--active' : '' }}">
{{ i + 1 }}
{% if url_window.slider is iterable %}
{{ pagination_segment(url_window.slider, base_url, paginator.currentPage, classPrefix) }}
<li class="{{ classPrefix }}pagination__separator"></li>
{% endif %}
{% if url_window.last is iterable %}
{{ pagination_segment(url_window.last, base_url, paginator.currentPage, classPrefix) }}
<li class="{{ classPrefix }}pagination__separator"></li>
{% endif %}
{% if paginator.hasMorePages %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--next">
<a href="{{ base_url ~ paginator.nextPageUrl|slice(2) }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--next" rel="next">
&raquo;
</a> </a>
</li> </li>
{% endif %}
{% endfor %}
<li class="{{ classPrefix }}pagination__separator"></li>
{% if currentPage >= pageCount - 1 %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--next {{ classPrefix }}pagination__option--disabled">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--next">
&rsaquo;
</span>
</li>
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--last {{ classPrefix }}pagination__option--disabled">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--last">
&raquo;
</span>
</li>
{% else %} {% else %}
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--next"> <li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--next">
<span class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--next"> <a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((currentPage + 1) * itemRange) : currentPage + 2) }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--next" rel="next">
&rsaquo;
</a>
</li>
<li class="{{ classPrefix }}pagination__option {{ classPrefix }}pagination__option--last">
<a href="{{ baseUrl ~ offsetParam ~ '=' ~ (useRanges ? ((pageCount - 1) * itemRange) : pageCount) }}" class="{{ classPrefix }}pagination__link {{ classPrefix }}pagination__link--last" rel="last">
&raquo; &raquo;
</span> </a>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>

View file

@ -3,7 +3,7 @@
{% from '@mio/news/macros.twig' import news_preview %} {% from '@mio/news/macros.twig' import news_preview %}
{% set title = category.category_name ~ ' :: News' %} {% set title = category.category_name ~ ' :: News' %}
{% set canonical_url = '/news.php?c=' ~ category.category_id ~ (page_id > 1 ? '&p=' ~ page_id : '') %} {% set canonical_url = '/news.php?c=' ~ category.category_id ~ (posts_offset > 0 ? '&o=' ~ posts_offset : '') %}
{% block news_content %} {% block news_content %}
<div class="container news__container"> <div class="container news__container">
@ -34,12 +34,12 @@
</div> </div>
<div class="container__content"> <div class="container__content">
{% for featured_post in featured %} {% for featured_post in featured %}
<a class="news__list__item" href="/news.php?n={{ featured_post.post_id }}">{{ featured_post.post_title }}</a> <a class="news__list__item" href="/news.php?p={{ featured_post.post_id }}">{{ featured_post.post_title }}</a>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{% endif %} {% endif %}
{# paginate(posts, '?c=' ~ category.category_id, 'news__') #} {{ paginate(category.posts_count, posts_take, posts_offset, '/news.php?c=' ~ category.category_id, 'news__') }}
</div> </div>
</div> </div>
</div> </div>

View file

@ -3,7 +3,7 @@
{% from '@mio/news/macros.twig' import news_preview %} {% from '@mio/news/macros.twig' import news_preview %}
{% set title = 'News' %} {% set title = 'News' %}
{% set canonical_url = '/news.php' ~ (page_id > 1 ? '?p=' ~ page_id : '') %} {% set canonical_url = '/news.php' ~ (posts_offset > 0 ? '?o=' ~ posts_offset : '') %}
{% block news_content %} {% block news_content %}
<div class="container news__container"> <div class="container news__container">
@ -34,7 +34,7 @@
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
{# paginate(posts, '', 'news__') #} {{ paginate(posts_count, posts_take, posts_offset, '/news.php', 'news__') }}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,12 +1,12 @@
{% macro news_preview(post) %} {% macro news_preview(post) %}
<div class="container news__preview"> <div class="container news__preview">
<a href="/news.php?n={{ post.post_id }}" class="container__title container__title--link news__preview__title"> <a href="/news.php?p={{ post.post_id }}" class="container__title container__title--link news__preview__title">
{{ post.post_title }} {{ post.post_title }}
</a> </a>
<div class="container__content news__preview__content"> <div class="container__content news__preview__content">
<div class="news__preview__text"> <div class="news__preview__text">
{{ post.post_text|first_paragraph|raw }} {{ post.post_text|first_paragraph|raw }}
<p><b><i><a href="/news.php?n={{ post.post_id }}">View full post</a></i></b></p> <p><b><i><a href="/news.php?p={{ post.post_id }}">View full post</a></i></b></p>
</div> </div>
<div class="news__preview__info"> <div class="news__preview__info">
<div class="news__preview__date"> <div class="news__preview__date">

View file

@ -1,7 +1,7 @@
{% extends '@mio/news/master.twig' %} {% extends '@mio/news/master.twig' %}
{% set title = post.post_title ~ ' :: News' %} {% set title = post.post_title ~ ' :: News' %}
{% set canonical_url = '/news.php?n=' ~ post.post_id %} {% set canonical_url = '/news.php?p=' ~ post.post_id %}
{% block news_content %} {% block news_content %}
<div class="container news__post"> <div class="container news__post">

View file

@ -15,10 +15,7 @@
<div class="settings__avatar__forms"> <div class="settings__avatar__forms">
<form class="settings__avatar__form" method="post" action="?m=avatar" enctype="multipart/form-data"> <form class="settings__avatar__form" method="post" action="?m=avatar" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="{{ avatar_max_filesize }}"> <input type="hidden" name="MAX_FILE_SIZE" value="{{ avatar_max_filesize }}">
<label class="input__upload__label"> <input accept="image/png,image/jpeg,image/gif" type="file" name="avatar" id="avatar-selection">
<input accept="image/png,image/jpeg,image/gif" type="file" name="avatar" class="input__upload" id="avatar-selection">
Pick file...
</label>
<button class="input__button" name="upload" value="{{ csrf_token() }}">Upload</button> <button class="input__button" name="upload" value="{{ csrf_token() }}">Upload</button>
</form> </form>

View file

@ -49,6 +49,6 @@
</div> </div>
{% endfor %} {% endfor %}
{# paginate(user_login_attempts, '?m=login-history', 'settings__') #} {{ paginate(login_attempts_count, login_attempts_take, login_attempts_offset, '?m=login-history', 'settings__') }}
</div> </div>
{% endblock %} {% endblock %}

View file

@ -60,6 +60,6 @@
</div> </div>
{% endfor %} {% endfor %}
{# paginate(user_sessions, '?m=sessions', 'settings__') #} {{ paginate(sessions_count, sessions_take, sessions_offset, '?m=sessions', 'settings__') }}
</div> </div>
{% endblock %} {% endblock %}