Implementing tag filters

This commit is contained in:
Lucas Cimon 2017-08-14 22:18:28 +02:00
parent 89ff3dee70
commit 8d5d7491bc
9 changed files with 78 additions and 50 deletions

View File

@ -29,7 +29,8 @@
- "--ignore=Bad value \"DUMMY\" for attribute \"datetime\""
- "--ignore=Bad value \"DUMMY\" for attribute \"lang\" on element \"html\""
- "--ignore=Bad value \"DUMMY\" for attribute \"type\" on element \"link\": Subtype missing"
exclude: templates/tipue_search.html
files: ^templates/[^/]*\.html$
exclude: ^templates/(index|tipue_search)\.html$
- repo: local
hooks:
- id: make

View File

@ -113,7 +113,7 @@ a {
font-weight: 800;
color: white; }
.mg-tag-filters {
.mg-header-extra {
flex: 1;
display: flex;
justify-content: flex-end; }
@ -129,10 +129,6 @@ a {
.mg-tag-filter:hover {
border-color: #b2b2b2;
text-decoration: none;}
.mg-tag-filter:hover {
text-decoration: none; }
.mg-tag-filter:not(:disabled) {
cursor: pointer; }
.mg-nav-small {
width: 100% }

View File

@ -1,22 +0,0 @@
// Avoid `console` errors in browsers that lack a console.
(function() {
var method;
var noop = function () {};
var methods = [
'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
'timeStamp', 'trace', 'warn'
];
var length = methods.length;
var console = (window.console = window.console || {});
while (length--) {
method = methods[length];
// Only stub undefined methods.
if (!console[method]) {
console[method] = noop;
}
}
}());

View File

@ -55,7 +55,6 @@
<link rel="stylesheet" href="{{ SITEURL }}/theme/css/solarized-highlight.css">
<link rel="stylesheet" href="{{ SITEURL }}/theme/css/main.css">
<script src="{{ SITEURL }}/theme/js/html5shiv-3.7.2.min.js"></script>
</head>
<body>
<!--[if lt IE 7]>
@ -71,13 +70,10 @@
<div class="mg-tagline uk-navbar-content">{% if SITESUBTITLE %}{{ SITESUBTITLE }}{% endif %}</div>
</div>
{% if MG_FILTER_TAGS %}
<div class="mg-tag-filters uk-hidden-small">
{% for filter_tag in MG_FILTER_TAGS %}
<button class="mg-tag-filter">{{ filter_tag.replace('lang:', '') }}</button>
{% endfor %}
<div class="mg-header-extra uk-hidden-small">
{% block header_extra %}
{% endblock %}
</div>
{% endif %}
<div class="mg-nav-small uk-visible-small">
<a class="mg-nav-menu-toggle-small uk-navbar-toggle" href="#mg-offcanvas" data-uk-offcanvas></a>
@ -250,20 +246,27 @@
</div>
</aside>
<script src="{{ SITEURL }}/theme/js/html5shiv-3.7.2.min.js"></script>
<script src="{{ SITEURL }}/theme/js/jquery-1.10.2.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>
<script src="{{ SITEURL }}/theme/js/uikit-2.27.4.min.js"></script>
{% if not DISABLE_SEARCH %}
<script src="{{ SITEURL }}/theme/js/uikit-2.27.4-search.min.js"></script>
<script src="{{ SITEURL }}/theme/js/tipuesearch_set.js"></script>
<script src="{{ SITEURL }}/theme/js/tipuesearch.js"></script>
<script>
{% include 'js/enable-search.js' %}
</script>
{% endif %}
{% if SHARE %}
<script src="{{ SITEURL }}/theme/js/jquery.sticky-kit.js"></script>
<script src="{{ SITEURL }}/theme/js/plugins.js"></script>
{% if DISABLE_SEARCH %}
<script src="{{ SITEURL }}/theme/js/main.js"></script>
{% else %}
<script src="{{ SITEURL }}/theme/js/main-search.js"></script>
<script>
{% include 'js/social.js' %}
</script>
{% endif %}
{% if MG_FILTER_TAGS %}
<script>
{% include 'js/filter-tags.js' %}
</script>
{% endif %}
{% include 'disqus_count.html' %}

View File

@ -1,12 +1,22 @@
{% extends "base.html" %}
{% block content_title %}{% endblock %}
{% block header_extra %}
{% if MG_FILTER_TAGS %}
{% for filter_tag in MG_FILTER_TAGS %}
<button class="mg-tag-filter" onclick="toggleTagFilter('{{ filter_tag }}')">{{ filter_tag.replace('lang:', '') }}</button>
{% endfor %}
{% endif %}
{% endblock %}
{% block content %}
<div class="uk-width-medium-4-5">
{% if articles %}
{% for article in (articles_page.object_list if articles_page else articles) %}
{% if loop.index == 1 %}
{% if not MG_NO_EXCERPT and loop.index == 1 %}
{% include "partials/article-excerpt.html" %}
{% else %}
{% include "partials/article-short.html" %}

View File

@ -1,9 +1,4 @@
'use strict';
$(document).ready(function() {
$('.mg-container-social').height($('article').height());
$('#mg-panel-social').stick_in_parent({offset_top: 35});
$('.tipue_search').tipuesearch({
'show': 10,
'mode': 'json',

View File

@ -0,0 +1,46 @@
/*
* Filters state can be one of:
* - undefined => disabled
* - true => select ONLY articles with this tag
* - false => do NOT select articles with this tag
* */
window.tagFilters = {}
function toggleTagFilter(tag) {
var filterState = window.tagFilters[tag]
if (filterState === true) {
filterState = false;
} else if (filterState === false) {
filterState = undefined;
} else {
filterState = true;
}
window.tagFilters[tag] = filterState;
updateArticlesVisibility();
}
function updateArticlesVisibility() {
var anyTrueFilter = Object.keys(window.tagFilters).some(function (tagFilter) {
return !!window.tagFilters[tagFilter];
});
Array.prototype.slice.call(document.getElementsByTagName('article')).forEach(function (article) {
if (!article.dataset.tags) { // article-excerpt: we ignore it
return;
}
var articleTags = JSON.parse(article.dataset.tags);
var anyTagWhitelisted = articleTags.some(function (tag) { return window.tagFilters[tag] === true; });
var anyTagBlacklisted = articleTags.some(function (tag) { return window.tagFilters[tag] === false; });
// Now implementing the core logic
var shouldDisplay = !anyTagBlacklisted;
if (shouldDisplay && anyTrueFilter) {
shouldDisplay = anyTagWhitelisted;
}
if (shouldDisplay) {
article.classList.remove('uk-hidden');
} else {
article.classList.add('uk-hidden');
}
});
}

View File

@ -1,5 +1,3 @@
'use strict';
$(document).ready(function() {
$('.mg-container-social').height($('article').height());
$('#mg-panel-social').stick_in_parent({offset_top: 35});

View File

@ -1,4 +1,5 @@
<article itemtype="http://schema.org/BlogPosting" itemscope="itemscope" itemprop="blogPost">
<article class="uk-article" itemtype="http://schema.org/BlogPosting" itemscope="itemscope" itemprop="blogPost"
data-tags='{{ article.tags|map(attribute='name')|list|tojson }}'>
<div class="mg-article-short">
{% if article.featured_image %}
<img class="mg-article-image" src="{{ article.featured_image }}" alt="">