Skip to content

Interactive Archives Widget #616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 46 additions & 5 deletions fp-plugins/archives/plugin.archives.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Author: FlatPress
* Author URI: https://www.flatpress.org
* Description: Adds an Archive widget element. Part of the standard distribution.
* Version: 1.0
* Version: 1.1.0
*/
class plugin_archives_monthlist extends fs_filelister {

Expand All @@ -29,7 +29,7 @@ function _checkFile($directory, $file) {
// we may have nested elements)
$this->_year = $file;
$lnk = get_year_link($file);
$this->_htmllist[$this->_year] = "<li class=\"archive-year archive-y20" . $file . "\"> <a href=\"" . $lnk . "\">20" . $file . "</a>";
$this->_htmllist[$this->_year] = "<li class=\"archive-year archive-y20" . $file . "\"> <span role=\"button\" class=\"togglelink toggleplus\" aria-expanded=\"false\" title=\"Expand\">▸ </span> <a href=\"" . $lnk . "\">20" . $file . "</a>";
return 1;
} elseif (is_dir($f)) {
$this->_months [] = $file;
Expand Down Expand Up @@ -74,20 +74,61 @@ function getHtmlList() {
}

function plugin_archives_head() {
$random_hex = RANDOM_HEX;
$pdir = plugin_geturl('archives');
global $PLUGIN_ARCHIVES_MONTHLIST;
$PLUGIN_ARCHIVES_MONTHLIST = new plugin_archives_monthlist();

echo "\n<!-- archives -->\n";
echo '
<!-- archives -->
<script nonce="' . $random_hex . '" src="' . $pdir . 'res/togglearchive.js" defer></script>
<link rel="stylesheet" type="text/css" href="' . $pdir . 'res/togglearchive.css">
';

foreach ($PLUGIN_ARCHIVES_MONTHLIST->getList() as $y => $months) {
foreach ($months as $ttl => $link) {
echo "<link rel=\"archives\" title=\"" . $ttl . "\" href=\"" . $link . "\">\n";
echo "
<link rel=\"archives\" title=\"" . $ttl . "\" href=\"" . $link . "\">";
}
}

echo "\n<!-- end of archives -->\n";
echo '
<!-- end of archives -->' . "\n";
}
add_filter('wp_head', 'plugin_archives_head');

function plugin_archives_footer() {
$random_hex = RANDOM_HEX;

echo '
<!-- archives -->
<script nonce="' . $random_hex . '">
/**
* Making the archive widget interactive
*/
var pluginArchive = \'\';
function toggleArchive(pdir) {
pluginArchive = pdir;
$(document).ready(function () {
$(\'#widget-archives ul > li.archive-year\').each(function (index) {
const uniqueId = \'archive-\' + index;
$(this).find(\'.togglelink\').attr(\'aria-controls\', uniqueId);
$(this).children(\'ul\').attr(\'id\', uniqueId);
const toggleEl = $(this).children(\'.togglelink\')[0];
toggle(toggleEl);
$(toggleEl).click(function () {
toggle(this);
return false;
});
});
});
}
</script>
<!-- end of archives -->
';
}
add_filter('end_footer', 'plugin_archives_footer');

function plugin_archives_widget() {
lang_load('plugin:archives');
global $lang, $PLUGIN_ARCHIVES_MONTHLIST;
Expand Down
8 changes: 8 additions & 0 deletions fp-plugins/archives/res/togglearchive.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.togglelink {
cursor: pointer;
line-height: 1.35em
}

#widget-archives ul ul {
display: none
}
106 changes: 106 additions & 0 deletions fp-plugins/archives/res/togglearchive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
function toggle(obj) {
let parentElement = obj.parentNode;
for (let i = 0; i < parentElement.childNodes.length; i++) {
if (parentElement.childNodes[i].nodeName === "UL") {
const ul = parentElement.childNodes[i];
const yearMatch = parentElement.className.match(/archive-y(\d{4})/);
const year = yearMatch ? yearMatch[1] : null;

if (ul.style.display === "none" || ul.style.display === "") {
showMth(parentElement);
obj.className = 'togglelink toggleminus';
obj.textContent = '▾ ';
obj.title = 'Reduce';
obj.setAttribute('aria-expanded', 'true');
parentElement.classList.add('open');
if (year) saveOpenYear(year);
} else {
hideMth(parentElement);
obj.className = 'togglelink toggleplus';
obj.textContent = '▸ ';
obj.title = 'Expand';
obj.setAttribute('aria-expanded', 'false');
parentElement.classList.remove('open');
if (year) removeOpenYear(year);
}
break;
}
}
}

function hideMth(obj) {
for (let i = 0; i < obj.childNodes.length; i++) {
if (obj.childNodes[i].nodeName === "UL") {
obj.childNodes[i].style.display = "none";
}
}
}

function showMth(obj) {
for (let i = 0; i < obj.childNodes.length; i++) {
if (obj.childNodes[i].nodeName === "UL") {
obj.childNodes[i].style.display = "block";
}
}
}

function saveOpenYear(year) {
let openYears = JSON.parse(localStorage.getItem('fp_open_years') || '[]');
if (!openYears.includes(year)) {
openYears.push(year);
localStorage.setItem('fp_open_years', JSON.stringify(openYears));
}
}

function removeOpenYear(year) {
let openYears = JSON.parse(localStorage.getItem('fp_open_years') || '[]');
openYears = openYears.filter(y => y !== year);
localStorage.setItem('fp_open_years', JSON.stringify(openYears));
}

/**
* Initialize toggle buttons for the Archive widget
*/
document.addEventListener('DOMContentLoaded', function () {
const archiveYears = document.querySelectorAll('#widget-archives ul > li.archive-year');
if (!archiveYears.length) return;

let openYears = JSON.parse(localStorage.getItem('fp_open_years') || '[]');

archiveYears.forEach((li, index) => {
const toggleEl = li.querySelector('.togglelink');
const nestedUl = li.querySelector('ul');
const uniqueId = 'archive-' + index;
const yearMatch = li.className.match(/archive-y(\d{4})/);
const year = yearMatch ? yearMatch[1] : null;

if (toggleEl && nestedUl) {
toggleEl.setAttribute('aria-controls', uniqueId);
nestedUl.setAttribute('id', uniqueId);

hideMth(li);
toggleEl.className = 'togglelink toggleplus';
toggleEl.textContent = '▸ ';
toggleEl.setAttribute('aria-expanded', 'false');
li.classList.remove('open');

toggleEl.addEventListener('click', function (e) {
e.preventDefault();
toggle(this);
});

if (year && openYears.includes(year)) {
toggle(toggleEl);
}
}
});

// If no years are saved: open current year
if (openYears.length === 0) {
const currentYear = new Date().getFullYear().toString();
const currentToggle = document.querySelector('.archive-y' + currentYear + ' .togglelink');
if (currentToggle) {
// toggle(currentToggle);
}
}
});