Вывести в меню индикатор новых новостей и статей на сайте Тильда

Author Автор: Роман Чернышов    Опубликовано: 28 августа 2024

Доброго времени друзья! Сегодня я хочу поделиться с вами скриптом, для сайта созданного с помощью конструктора сайтов Тильда, скрипт позволяет вывести в меню, индикатор новых новостей(статей и прочих записей) для пользователя, на против каждого пункта меню, в шапке сайта. Как оказалось данный скрипт очень востребован, поэтому спешу поделиться им с вами.

Принцип работы

Скрипт написан на JavaScript, с использованием библиотеки jQuery, а также дополнительного плагина для работы с Cookie. Скрипт добавляется на все страницы сайта(в шапку сайта). И работает следующим образом:

  • Пользователь заходит на сайт, скрипт записывает информацию о посещении в Cookie браузера;
  • Пользователь посещает сайт повторно, загружается скрипт, после чего скрипт опрашивает все разделы(с новостями, статьями т.д.) сайта, и сравнивает полученную информацию с данными в Cookie пользователя. Если выясняется, что с момента последнего посещения на сайт были добавлены новые материалы, скрипт выведет соответствующий индикатор в меню сайта.

Как это выглядит?

Меню на полной версии сайта будет выглядеть так, с отображением напротив каждого пункта меню индикатора количество новых новостей:

Меню для ПК на сайте Тильда с индикатором количества записей

Меню в мобильной версии сайта:

Мобильное меню сайта на Тильда с индикатором количества новостей

Скрипт

jQuery(document).ready(function($) {
    // Стиль оформления индикатора
    $('head').append(`
        <style>
        .new-post {
    background: red;
    color: #fff;
    border-radius: 50%;
    width: 20px;
    height: 20px;
    font-size: 12px;
    line-height: 20px;
    position: absolute;
    top: 0;
    right: -13px;
        }
        .t-menu__link-item {position: relative;text-align: center;}
        .t-menu__link-item .new-post {
            right: -20px;
        }
        </style>
    `);
    // Режим отладки, будет выводить в консоль информацию о работе скрипта
    var debug = true;
 
    // ID Проекта(сайта) на Tilda
    var projectid = ''; 
    // Список ID каналов новостей (чтобы узнать их, нужно посмотреть в "инструментах разработчика", в браузере, запросы к API Tilda, и из них получить эти ID)    
    var feed = {
        '86438483XXXX': {url: '/articles', feeduid: '86438483XXXX', total: 0, type: 'feed'},
        '56743949YYYY': {url: '/news', feeduid: '56743949YYYY', total: 0, type: 'feed'},
    };
 
    //var lastfeed = window.localStorage.getItem('lastfeed') != null ? JSON.parse(window.localStorage.getItem('lastfeed')) : null;
    var lastfeed = $.cookie('lastfeed') != null ? JSON.parse($.cookie('lastfeed')) : null;
 
    if(lastfeed != null) {
        if(Object.keys(feed)[0] in lastfeed) {} else {
            lastfeed = null; 
            //window.localStorage.setItem('lastfeed', null); 
            $.cookie('lastfeed', null);
            if(debug) console.log('Set Lastfeed to Null (Fixed)');
        } // Если в Storage данные не корректны, затираем его
    }
    var ajaxload = 0;
 
    if(debug) console.log(lastfeed);    
    $.each(feed, function(i, v) {
 
        ajaxload++;
 
        var url = '';
        var data = null;
        var method = 'GET';
        if(v.type == 'feed') { // Запросы к API Tilda чтобы получить информацию о количестве статей
            url = "https://feeds.tildaapi.com/api/getfeed/?feeduid=" + v.feeduid + 
		"&recid=&c=&size=&slice=1&sort%5Bdate%5D=desc&filters%5Bdate%5D=&getparts=true";
        } else {
            method = 'POST';
	    // Запросы к API Tilda чтобы получить информацию о количестве записей на остальных страницах (разделах)
            url = "https://members.tildaapi.com/api/getpage/";
            data = {pageid: v.feeduid, pageurl: "https://" + window.location.hostname + 
		v.url, projectid: projectid, token: "", tzoffset: -180};
        }
 
        $.ajax({
            method: method,
            url: url,
            data: data,
            dataType: "json",
            success: function(data) {
 
                if(v.type == 'page' && 'data' in data) {
                    var doc = new DOMParser().parseFromString(data.data.html, "text/html");
                    data.total = doc.querySelectorAll("ul li.t-item").length;
                }
 
                if( 'status' in data) {
                    if(data.status == 'error') {
                        ajaxload--;    
                        return;
                        }
                }
 
                if(debug) console.log('Total on Feed URL: ' + v.url + ', UID: ' + v.feeduid + ': ' + data.total);
 
                if(lastfeed != null && window.location.pathname == v.url) {
                    if(debug) console.log('This current Page ' + v.url + ', clear last Total data ');
                    lastfeed[v.feeduid] = feed[v.feeduid];
                    lastfeed[v.feeduid].total = 'total' in data ? data.total : 0;
                }
                feed[v.feeduid].total = data.total;
                ajaxload--;    
            }
        });
    });
 
    var timer = setInterval(function() {
        // Ждем получения информации от Ajax запросов в API Tilda
        if(ajaxload == 0) {
            if(debug) console.log('All Feed ajax loding');
 
            if(lastfeed != null && Object.keys(lastfeed).length == Object.keys(feed).length) {
                if(debug) console.log('Save Cookie Lastfeed: ' + Object.keys(lastfeed).length);
                $.cookie('lastfeed', JSON.stringify(lastfeed), { expires: 7, path: '/'});
            } else {
                if(debug) console.log('Save Cookie Feed: ' + Object.keys(feed).length);
                $.cookie('lastfeed', JSON.stringify(feed), { expires: 7, path: '/'});
            }
            clearInterval(timer);
 
            $.each(feed, function(i, v) {
 
                if(lastfeed != null && v.feeduid in lastfeed && parseInt(lastfeed[v.feeduid].total) < parseInt(v.total)) {
 
                    if(debug) console.log('In Feed ' + v.url + ' exists new Post: ' + (parseInt(v.total) - parseInt(lastfeed[v.feeduid].total)));
 
                    $('.t396__artboard.rendered a.tn-atom[href="' + v.url + '"]').append(`
                        <div class="new-post">` + (parseInt(v.total) - parseInt(lastfeed[v.feeduid].total)) + `</div>
                    `);
 
                    $('.t450__menu a.t-menu__link-item[href="' + v.url + '"]').append(`
                        <div class="new-post">` + (parseInt(v.total) - parseInt(lastfeed[v.feeduid].total)) + `</div>
                    `);                    
                }
            });
 
        }
    }, 300);
});

Не забываем подключить jQuery:

<script
  src="https://code.jquery.com/jquery-1.12.4.min.js"
  integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
  crossorigin="anonymous"></script>

Код плагина для работы с Cookie:

jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options = $.extend({}, options); // clone object since it's unexpected behavior if the expired property were changed
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // NOTE Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

Оставить комментарий

Автор блога
Роман Чернышов
Веб-разработчик,
Full Stack
Senior, Architect
PHP, JavaScript, Node.JS, Python, HTML 5, CSS 3, MySQL, Bash, Linux Admin
Заказать работу
предложить оффер

Моя книга
Книга. Веб-разработчик. Легкий вход в профессию
Печатная книга
Веб-разработчик.
Легкий вход в профессию
Купить за 359₽
Популярные записи
Последние вопросы
Список вопросов
Последние комментарии
Меню

Archive

Мои проекты
Insurance CMS Love Crm CMS Совместные покупки Мой PHP Framework Хостинг для моих клиентов Лицензии на мой софт и поддержка