Add first decent cut of the Zola static site.
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
public/
|
||||
content/spaces/
|
||||
19
config.toml
Normal file
19
config.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
base_url = "https://ooru.space"
|
||||
title = "Public and Community spaces in India"
|
||||
description = "Directory of community and public spaces across India."
|
||||
compile_sass = false
|
||||
minify_html = true
|
||||
|
||||
[markdown]
|
||||
|
||||
[[taxonomies]]
|
||||
name = "states"
|
||||
feed = false
|
||||
|
||||
[[taxonomies]]
|
||||
name = "cities"
|
||||
feed = false
|
||||
|
||||
[[taxonomies]]
|
||||
name = "categories"
|
||||
feed = false
|
||||
4
content/_index.md
Normal file
4
content/_index.md
Normal file
@@ -0,0 +1,4 @@
|
||||
+++
|
||||
title = "Community & Public Spaces in India"
|
||||
sort_by = "title"
|
||||
+++
|
||||
1
static/india.geojson
Normal file
1
static/india.geojson
Normal file
File diff suppressed because one or more lines are too long
265
static/main.js
Normal file
265
static/main.js
Normal file
@@ -0,0 +1,265 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const $ = s => document.querySelector(s), $$ = s => document.querySelectorAll(s);
|
||||
const items = $$('[data-space]');
|
||||
if (!items.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const elSearch = $('#search'), elCount = $('#count');
|
||||
const elChk = $$('[data-filter]');
|
||||
const elMap = $('[data-map]'), elShowMap = $('#show-map'), elToggles = $$('[data-toggle]');
|
||||
const isMobile = matchMedia('(max-width: 900px)').matches;
|
||||
let map, isMapLoaded = false, selItem = null;
|
||||
const markers = [], markerItems = new Map();
|
||||
|
||||
// Build city+state mappings for filtering.
|
||||
const cityToState = {}, stateToCities = {};
|
||||
items.forEach(i => {
|
||||
i._text = i.textContent.toLowerCase();
|
||||
const { city, state } = i.dataset;
|
||||
if (city && state) {
|
||||
cityToState[city] = state;
|
||||
(stateToCities[state] ||= new Set()).add(city);
|
||||
}
|
||||
});
|
||||
|
||||
// Checkbox groups for bulk toggling.
|
||||
const groupBoxes = {};
|
||||
elToggles.forEach(t => {
|
||||
if (t.dataset.toggle) groupBoxes[t.dataset.toggle] = $$(`input[name="${t.dataset.toggle}"]`);
|
||||
});
|
||||
|
||||
// Map logic.
|
||||
function loadMap() {
|
||||
if (isMapLoaded || isMobile) return;
|
||||
|
||||
// Lazy-load only if it's enabled + not mobile.
|
||||
isMapLoaded = true;
|
||||
document.head.append(
|
||||
Object.assign(document.createElement('link'), { rel: 'stylesheet', href: 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' })
|
||||
);
|
||||
|
||||
const s = Object.assign(document.createElement('script'), { src: 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js' });
|
||||
s.onload = initMap;
|
||||
document.head.append(s);
|
||||
}
|
||||
|
||||
const defStyle = { radius: 7, color: '#fff', weight: 1.5, fillColor: 'blue', fillOpacity: 0.85 };
|
||||
const hiStyle = { radius: 10, color: '#fff', weight: 2, fillColor: 'blue', fillOpacity: 1 };
|
||||
|
||||
function styleMarker(m, style, open) {
|
||||
m.setStyle(style); m.setRadius(style.radius);
|
||||
if (open) { m.bringToFront(); m.openPopup(); } else m.closePopup();
|
||||
}
|
||||
|
||||
// Initialize map with LeafletJS. Dim non-India areas.
|
||||
function initMap() {
|
||||
if (!$('#map') || typeof L === 'undefined') return;
|
||||
|
||||
map = L.map('map', { maxBounds: [[5, 67], [38, 98]], maxBoundsViscosity: 1, minZoom: 4 }).setView([22, 79], 5);
|
||||
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png', {
|
||||
attribution: '© <a href="https://openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/">CARTO</a>',
|
||||
subdomains: 'abcd'
|
||||
}).addTo(map);
|
||||
|
||||
const addLabels = () => L.tileLayer(
|
||||
'https://{s}.basemaps.cartocdn.com/light_only_labels/{z}/{x}/{y}{r}.png',
|
||||
{ subdomains: 'abcd', pane: 'shadowPane' }
|
||||
).addTo(map);
|
||||
|
||||
// Fetch India's boundaries and apply to the map.
|
||||
fetch('/india.geojson').then(r => r.json()).then(india => {
|
||||
const world = [[-90, -180], [-90, 180], [90, 180], [90, -180]];
|
||||
const polys = india.geometry.type === 'Polygon' ? [india.geometry.coordinates] : india.geometry.coordinates;
|
||||
L.polygon([world, ...polys.map(p => p[0].map(c => [c[1], c[0]]))], {
|
||||
color: 'none', fillColor: '#ddd', fillOpacity: 0.6, interactive: false
|
||||
}).addTo(map);
|
||||
addLabels();
|
||||
}).catch(addLabels);
|
||||
|
||||
items.forEach(item => {
|
||||
const lat = parseFloat(item.dataset.lat), lng = parseFloat(item.dataset.lng);
|
||||
if (isNaN(lat) || isNaN(lng)) return;
|
||||
|
||||
// Build the pin-popup card.
|
||||
const q = [item.dataset.name, item.dataset.address, item.dataset.city].filter(Boolean).join(', ');
|
||||
const popup = `<strong>${item.dataset.name}</strong>`
|
||||
+ (item.dataset.address ? `<br><span class="popup-address">${item.dataset.address}</span>` : '')
|
||||
+ `<br><a href="https://www.google.com/maps/search/${encodeURIComponent(q)}" target="_blank" rel="noopener">Search on Google Maps →</a>`;
|
||||
const marker = L.circleMarker([lat, lng], defStyle).bindPopup(popup, { autoClose: false }).addTo(map);
|
||||
markers.push({ marker, item });
|
||||
markerItems.set(item, marker);
|
||||
|
||||
item.addEventListener('mouseenter', () => {
|
||||
if (selItem === item) return;
|
||||
styleMarker(marker, hiStyle, true);
|
||||
});
|
||||
item.addEventListener('mouseleave', () => {
|
||||
if (selItem === item) return;
|
||||
styleMarker(marker, defStyle, false);
|
||||
});
|
||||
item.addEventListener('click', () => {
|
||||
if (selItem) {
|
||||
selItem.setAttribute('aria-selected', 'false');
|
||||
const prev = markerItems.get(selItem);
|
||||
if (prev) {
|
||||
styleMarker(prev, defStyle, false);
|
||||
}
|
||||
}
|
||||
if (selItem === item) {
|
||||
selItem = null;
|
||||
return;
|
||||
}
|
||||
|
||||
selItem = item;
|
||||
item.setAttribute('aria-selected', 'true');
|
||||
styleMarker(marker, hiStyle, true);
|
||||
});
|
||||
marker.on('mouseover', () => {
|
||||
if (selItem !== item) styleMarker(marker, hiStyle, true);
|
||||
});
|
||||
marker.on('mouseout', () => {
|
||||
if (selItem !== item) styleMarker(marker, defStyle, false);
|
||||
});
|
||||
marker.on('click', () => {
|
||||
if (selItem) {
|
||||
selItem.setAttribute('aria-selected', 'false');
|
||||
const prev = markerItems.get(selItem);
|
||||
if (prev) styleMarker(prev, defStyle, false);
|
||||
}
|
||||
if (selItem === item) {
|
||||
selItem = null;
|
||||
return;
|
||||
}
|
||||
selItem = item;
|
||||
item.setAttribute('aria-selected', 'true');
|
||||
styleMarker(marker, hiStyle, true);
|
||||
item.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||
});
|
||||
});
|
||||
updateMap();
|
||||
}
|
||||
|
||||
function updateMap() {
|
||||
if (!map || elMap?.style.display === 'none') return;
|
||||
|
||||
const bounds = [];
|
||||
markers.forEach(({ marker, item }) => {
|
||||
item.hidden ? marker.remove() : (marker.addTo(map), bounds.push(marker.getLatLng()));
|
||||
});
|
||||
if (!bounds.length) return;
|
||||
|
||||
map.fitBounds(bounds, { padding: [30, 30], maxZoom: 12 });
|
||||
}
|
||||
|
||||
// Filtering logic.
|
||||
function cascadeFilters(changed) {
|
||||
const cb = groupBoxes.city, sb = groupBoxes.state;
|
||||
if (!cb || !sb) return;
|
||||
|
||||
if (changed.name === 'city') {
|
||||
const need = new Set();
|
||||
cb.forEach(c => {
|
||||
if (c.checked && cityToState[c.value]) {
|
||||
need.add(cityToState[c.value]);
|
||||
}
|
||||
});
|
||||
sb.forEach(c => { c.checked = need.has(c.value); });
|
||||
} else if (changed.name === 'state') {
|
||||
const need = new Set();
|
||||
sb.forEach(c => {
|
||||
if (c.checked) {
|
||||
(stateToCities[c.value] || []).forEach(v => need.add(v));
|
||||
}
|
||||
});
|
||||
cb.forEach(c => { c.checked = need.has(c.value); });
|
||||
}
|
||||
}
|
||||
|
||||
function updateToggleLabels() {
|
||||
elToggles.forEach(t => {
|
||||
const boxes = groupBoxes[t.dataset.toggle];
|
||||
if (!boxes) return;
|
||||
|
||||
t.textContent = Array.from(boxes).every(c => c.checked) ? 'Unselect all' : 'Select all';
|
||||
});
|
||||
}
|
||||
|
||||
function filter() {
|
||||
const q = (elSearch?.value || '').toLowerCase();
|
||||
const active = {};
|
||||
|
||||
elChk.forEach(cb => {
|
||||
if (cb.checked) {
|
||||
(active[cb.name] ||= []).push(cb.value);
|
||||
}
|
||||
});
|
||||
|
||||
let n = 0;
|
||||
items.forEach(item => {
|
||||
const show = (!q || item._text.includes(q)) && Object.entries(active).every(([k, v]) =>
|
||||
k === 'category' ? v.some(x => item.dataset.categories.split(',').includes(x)) : v.includes(item.dataset[k])
|
||||
);
|
||||
item.hidden = !show;
|
||||
|
||||
if (show) {
|
||||
n++;
|
||||
}
|
||||
});
|
||||
elCount.textContent = n;
|
||||
updateMap();
|
||||
}
|
||||
|
||||
// Bind various control events.
|
||||
elSearch?.addEventListener('input', filter);
|
||||
|
||||
elChk.forEach(cb => cb.addEventListener('change', e => {
|
||||
cascadeFilters(e.target); updateToggleLabels(); filter();
|
||||
}));
|
||||
|
||||
elShowMap?.addEventListener('change', () => {
|
||||
if (!elMap) return;
|
||||
if (elShowMap.checked) {
|
||||
elMap.style.display = '';
|
||||
isMapLoaded ? (map?.invalidateSize(), updateMap()) : loadMap();
|
||||
} else elMap.style.display = 'none';
|
||||
});
|
||||
|
||||
elToggles.forEach(t => t.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
const boxes = groupBoxes[t.dataset.toggle];
|
||||
if (!boxes) return;
|
||||
const all = Array.from(boxes).every(c => c.checked);
|
||||
boxes.forEach(c => c.checked = !all);
|
||||
updateToggleLabels(); filter();
|
||||
}));
|
||||
|
||||
// On mobile, just don't show the map.
|
||||
if (isMobile) {
|
||||
if (elShowMap) {
|
||||
elShowMap.closest('label').style.display = 'none';
|
||||
elShowMap.checked = false;
|
||||
}
|
||||
if (elMap) {
|
||||
elMap.style.display = 'none';
|
||||
}
|
||||
} else if (!elShowMap || elShowMap?.checked) {
|
||||
loadMap();
|
||||
}
|
||||
|
||||
// Filter toggle for mobile.
|
||||
const elFilterToggle = $('#filter-toggle');
|
||||
const elFilterGroups = $('.filter-groups');
|
||||
if (elFilterToggle && elFilterGroups) {
|
||||
elFilterToggle.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
const open = elFilterGroups.classList.toggle('open');
|
||||
elFilterToggle.textContent = open ? 'Hide filters' : 'Show filters';
|
||||
});
|
||||
}
|
||||
|
||||
// Reset all controls on boot.
|
||||
if (elSearch) elSearch.value = '';
|
||||
elChk.forEach(cb => cb.checked = true);
|
||||
updateToggleLabels(); filter();
|
||||
});
|
||||
79
static/samagata.svg
Normal file
79
static/samagata.svg
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="253.349"
|
||||
height="74.237"
|
||||
viewBox="0 0 67.032 19.642"
|
||||
version="1.1"
|
||||
id="svg11"
|
||||
sodipodi:docname="samagata.svg"
|
||||
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview11"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1"
|
||||
inkscape:cx="127"
|
||||
inkscape:cy="37"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1367"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg11" />
|
||||
<g
|
||||
fill="#a82929"
|
||||
id="g2">
|
||||
<path
|
||||
d="M11.897 19.642H7.416l2.241-2.241zm0-4.514H7.416l2.241 2.241zm3.651-4.746l-2.576 3.664 3.12-.544zm-8.132-5.79h4.481l-2.24-2.241zm8.95 12.493l-3.895 2.221.837-3.058zm2.814-4.416l-2.254 3.876-.811-3.065zM2.856 17.056l3.892 2.218-.837-3.055zM.042 12.639l2.254 3.872.808-3.065zM2.387 2.96L.166 6.852l3.058-.837z"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M6.182 5.149L3.87 8.989l-.765-3.074zm-2.287 5.269l2.283 3.856-3.071-.785zm11.53-1.296l-2.43-3.765 3.097.668zM6.804.146L2.928 2.4l3.065.808zm9.66 2.306L12.62.146l.769 3.074zm2.716 4.475l-2.169-3.921-.876 3.045zM11.897 0H7.416l2.241 2.24zM0 7.523v4.481l2.241-2.241zm19.346 0v4.481l-2.241-2.241z"
|
||||
id="path2" />
|
||||
</g>
|
||||
<g
|
||||
fill="#333333"
|
||||
id="g6"
|
||||
transform="translate(0,3.096)">
|
||||
<path
|
||||
d="M 28.021,4.258 Q 27.973,3.764 27.769,3.367 27.566,2.97 27.207,2.737 26.848,2.495 26.316,2.504 q -0.543,0 -0.862,0.3 -0.32,0.3 -0.32,0.727 0,0.378 0.213,0.64 0.213,0.252 0.572,0.455 0.368,0.203 0.824,0.407 0.368,0.155 0.746,0.349 0.378,0.194 0.688,0.446 0.31,0.242 0.494,0.591 0.184,0.339 0.184,0.804 0,0.543 -0.281,0.969 -0.281,0.426 -0.804,0.669 -0.514,0.242 -1.25,0.242 -0.417,0 -0.882,-0.126 -0.455,-0.126 -0.833,-0.359 l 0.048,0.407 H 24.262 L 24.223,6.893 h 0.465 q 0.078,0.843 0.601,1.279 0.533,0.426 1.269,0.426 0.368,0 0.669,-0.136 0.3,-0.136 0.475,-0.388 0.174,-0.252 0.174,-0.591 0,-0.397 -0.242,-0.669 Q 27.401,6.543 27.033,6.349 26.674,6.155 26.277,5.981 25.88,5.807 25.502,5.613 25.134,5.419 24.833,5.167 24.533,4.915 24.358,4.576 24.184,4.227 24.184,3.762 q 0,-0.271 0.097,-0.572 0.097,-0.3 0.329,-0.572 0.233,-0.271 0.63,-0.436 0.407,-0.174 1.017,-0.174 0.368,0 0.824,0.107 0.465,0.107 0.843,0.378 L 27.885,2.086 h 0.581 v 2.17 z"
|
||||
id="path3" />
|
||||
<use
|
||||
xlink:href="#B"
|
||||
id="use3" />
|
||||
<path
|
||||
d="M 34.697,8.948 V 8.541 q 0.291,0 0.407,-0.136 Q 35.22,8.269 35.24,8.027 35.269,7.785 35.269,7.465 V 5.45 q 0,-0.155 0,-0.329 0.01,-0.184 0.039,-0.359 -0.165,0.01 -0.349,0.019 -0.184,0 -0.339,0.01 V 4.277 q 0.436,0 0.678,-0.039 0.252,-0.048 0.378,-0.107 0.136,-0.058 0.203,-0.126 h 0.349 q 0.019,0.097 0.019,0.233 0.01,0.126 0.019,0.271 0.3,-0.252 0.678,-0.407 0.388,-0.155 0.746,-0.155 0.475,0 0.785,0.174 0.32,0.165 0.504,0.475 0.339,-0.281 0.765,-0.465 0.426,-0.184 0.833,-0.184 0.824,0 1.221,0.494 0.397,0.484 0.388,1.628 l -0.01,1.676 q 0,0.174 -0.01,0.359 0,0.174 -0.029,0.359 0.155,-0.01 0.32,-0.01 0.165,-0.01 0.3,-0.019 V 8.948 H 40.625 V 8.541 q 0.271,0 0.378,-0.136 0.116,-0.136 0.136,-0.378 0.029,-0.242 0.029,-0.562 V 6.07 Q 41.158,5.305 40.916,4.946 40.674,4.587 40.18,4.587 q -0.281,0 -0.552,0.126 -0.271,0.116 -0.484,0.3 0.049,0.165 0.068,0.368 0.029,0.194 0.029,0.407 -0.01,0.484 -0.01,0.979 0,0.484 0,0.979 0,0.174 -0.01,0.359 -0.01,0.174 -0.029,0.359 0.155,-0.01 0.31,-0.01 0.165,-0.01 0.3,-0.019 V 8.949 H 37.651 V 8.542 q 0.291,0 0.397,-0.136 0.116,-0.136 0.136,-0.378 0.029,-0.242 0.029,-0.562 V 6.06 Q 38.223,5.295 37.99,4.936 37.767,4.568 37.273,4.577 q -0.281,0 -0.543,0.126 -0.262,0.116 -0.455,0.3 0,0.116 0,0.242 0.01,0.126 0.01,0.271 v 2.229 q 0,0.174 -0.01,0.359 -0.01,0.174 -0.029,0.359 0.155,-0.01 0.31,-0.01 0.155,-0.01 0.291,-0.019 v 0.514 z m 11.609,0 Q 46.287,8.793 46.277,8.677 46.267,8.561 46.248,8.435 45.919,8.764 45.541,8.939 45.163,9.104 44.756,9.104 44.058,9.104 43.7,8.765 43.351,8.416 43.351,7.903 q 0,-0.446 0.262,-0.775 0.262,-0.329 0.688,-0.533 0.426,-0.213 0.93,-0.31 0.504,-0.107 0.988,-0.107 V 5.606 q 0,-0.31 -0.058,-0.572 Q 46.103,4.763 45.919,4.598 45.745,4.424 45.367,4.424 45.115,4.414 44.863,4.521 44.611,4.618 44.475,4.85 q 0.078,0.077 0.097,0.184 0.029,0.097 0.029,0.184 0,0.136 -0.116,0.31 -0.116,0.165 -0.397,0.155 -0.233,0 -0.359,-0.155 -0.116,-0.165 -0.116,-0.378 0,-0.349 0.252,-0.62 0.262,-0.271 0.707,-0.426 0.446,-0.155 0.998,-0.155 0.833,0 1.24,0.436 0.417,0.436 0.417,1.376 0,0.349 0,0.669 0,0.32 -0.01,0.64 0,0.32 0,0.678 0,0.145 -0.01,0.329 -0.01,0.184 -0.029,0.388 0.165,-0.01 0.339,-0.019 0.174,-0.01 0.329,-0.01 V 8.95 Z M 46.219,6.622 q -0.31,0.019 -0.64,0.087 -0.32,0.068 -0.581,0.203 -0.262,0.136 -0.426,0.349 -0.155,0.213 -0.155,0.514 0.019,0.329 0.213,0.484 0.203,0.155 0.475,0.155 0.339,0 0.601,-0.126 0.262,-0.136 0.514,-0.368 -0.01,-0.107 -0.01,-0.213 0,-0.116 0,-0.242 0,-0.087 0,-0.32 0.01,-0.242 0.01,-0.523 z M 44.145,2.572 V 1.874 h 2.626 v 0.659 z m 6.579,9.002 q -0.853,0 -1.376,-0.194 -0.514,-0.184 -0.746,-0.484 -0.223,-0.291 -0.223,-0.62 0,-0.262 0.116,-0.484 Q 48.621,9.569 48.824,9.395 49.027,9.23 49.279,9.133 48.94,9.026 48.765,8.833 48.591,8.63 48.591,8.339 q 0,-0.31 0.242,-0.61 0.252,-0.3 0.717,-0.407 Q 49.114,7.128 48.852,6.76 48.59,6.392 48.581,5.888 q -0.01,-0.581 0.291,-1.017 0.31,-0.436 0.785,-0.678 0.484,-0.242 1.008,-0.242 0.3,0 0.62,0.087 0.32,0.077 0.581,0.252 0.107,-0.281 0.281,-0.514 0.174,-0.233 0.407,-0.368 0.242,-0.136 0.504,-0.136 0.281,0 0.426,0.145 0.145,0.145 0.145,0.388 0,0.077 -0.049,0.194 -0.039,0.107 -0.145,0.184 -0.107,0.077 -0.291,0.077 -0.155,0 -0.281,-0.097 -0.116,-0.107 -0.145,-0.252 -0.203,0.039 -0.339,0.242 -0.126,0.194 -0.165,0.397 0.252,0.223 0.388,0.533 0.145,0.3 0.145,0.649 0,0.552 -0.3,0.979 -0.291,0.426 -0.765,0.669 -0.475,0.242 -1.027,0.242 -0.165,0 -0.31,-0.019 -0.145,-0.029 -0.32,-0.029 -0.31,0 -0.514,0.145 -0.194,0.145 -0.145,0.349 0.049,0.213 0.407,0.281 0.359,0.068 1.037,0.097 0.746,0.029 1.279,0.184 0.543,0.145 0.833,0.455 0.3,0.31 0.3,0.843 0,0.397 -0.223,0.707 -0.213,0.31 -0.581,0.514 -0.359,0.213 -0.804,0.32 -0.446,0.107 -0.891,0.107 z m 0.087,-0.475 q 0.785,0 1.211,-0.291 0.436,-0.291 0.436,-0.659 0,-0.31 -0.213,-0.484 Q 52.032,9.5 51.644,9.423 51.266,9.355 50.753,9.346 50.501,9.327 50.239,9.317 49.977,9.307 49.755,9.269 49.532,9.424 49.406,9.647 49.29,9.87 49.28,10.112 q 0,0.446 0.417,0.717 0.417,0.271 1.114,0.271 z M 50.685,7.165 q 0.329,0 0.543,-0.165 0.223,-0.174 0.329,-0.455 0.116,-0.291 0.116,-0.63 0,-0.397 -0.116,-0.746 Q 51.441,4.82 51.218,4.607 50.995,4.394 50.646,4.394 q -0.475,0 -0.736,0.378 -0.262,0.378 -0.262,0.911 0,0.426 0.116,0.765 0.126,0.329 0.359,0.523 0.233,0.194 0.562,0.194 z"
|
||||
id="path4" />
|
||||
<use
|
||||
xlink:href="#B"
|
||||
x="24.156"
|
||||
id="use4" />
|
||||
<path
|
||||
d="m 60.646,9.103 q -0.242,0 -0.494,-0.068 Q 59.91,8.977 59.706,8.793 59.503,8.599 59.386,8.241 59.27,7.882 59.27,7.291 L 59.289,4.646 H 58.572 V 4.103 q 0.262,-0.01 0.533,-0.194 0.271,-0.184 0.475,-0.494 0.203,-0.31 0.281,-0.669 h 0.455 v 1.357 h 1.492 v 0.504 l -1.492,0.019 -0.019,2.587 q 0,0.368 0.058,0.649 0.068,0.271 0.213,0.426 0.155,0.145 0.417,0.145 0.223,0 0.455,-0.136 0.242,-0.136 0.455,-0.446 l 0.329,0.291 Q 61.991,8.481 61.759,8.675 61.526,8.869 61.313,8.956 61.1,9.053 60.925,9.072 60.751,9.101 60.644,9.101 Z"
|
||||
id="path5" />
|
||||
<path
|
||||
d="M 65.491,8.948 Q 65.472,8.793 65.462,8.677 65.452,8.561 65.433,8.435 q -0.329,0.329 -0.707,0.504 -0.378,0.165 -0.785,0.165 -0.698,0 -1.056,-0.339 -0.349,-0.349 -0.349,-0.862 0,-0.446 0.262,-0.775 0.262,-0.329 0.688,-0.533 0.426,-0.213 0.93,-0.31 0.504,-0.107 0.988,-0.107 V 5.606 q 0,-0.31 -0.058,-0.572 Q 65.288,4.763 65.104,4.598 64.93,4.424 64.552,4.424 64.3,4.414 64.048,4.521 63.796,4.618 63.66,4.85 q 0.077,0.077 0.097,0.184 0.029,0.097 0.029,0.184 0,0.136 -0.116,0.31 -0.116,0.165 -0.397,0.155 -0.233,0 -0.359,-0.155 -0.116,-0.165 -0.116,-0.378 0,-0.349 0.252,-0.62 0.262,-0.271 0.707,-0.426 0.446,-0.155 0.998,-0.155 0.833,0 1.24,0.436 0.417,0.436 0.417,1.376 0,0.349 0,0.669 0,0.32 -0.01,0.64 0,0.32 0,0.678 0,0.145 -0.01,0.329 -0.01,0.184 -0.029,0.388 0.165,-0.01 0.339,-0.019 0.174,-0.01 0.329,-0.01 V 8.95 Z M 65.404,6.622 q -0.31,0.019 -0.64,0.087 -0.32,0.068 -0.581,0.203 -0.262,0.136 -0.426,0.349 -0.155,0.213 -0.155,0.514 0.019,0.329 0.213,0.484 0.203,0.155 0.475,0.155 0.339,0 0.601,-0.126 0.262,-0.136 0.514,-0.368 -0.01,-0.107 -0.01,-0.213 0,-0.116 0,-0.242 0,-0.087 0,-0.32 0.01,-0.242 0.01,-0.523 z"
|
||||
id="path6" />
|
||||
</g>
|
||||
<defs
|
||||
id="defs11">
|
||||
<path
|
||||
id="B"
|
||||
d="M32.527 8.948q-.019-.155-.029-.271-.01-.116-.029-.242-.329.329-.707.504-.378.165-.785.165-.698 0-1.056-.339-.349-.349-.349-.862 0-.446.262-.775.262-.329.688-.533.426-.213.93-.31.504-.107.988-.107v-.572q0-.31-.058-.572-.058-.271-.242-.436-.174-.174-.552-.174-.252-.01-.504.097-.252.097-.388.329.078.077.097.184.029.097.029.184 0 .136-.116.31-.116.165-.397.155-.233 0-.359-.155-.116-.165-.116-.378 0-.349.252-.62.262-.271.707-.426.446-.155.998-.155.833 0 1.24.436.417.436.417 1.376 0 .349 0 .669 0 .32-.01.64 0 .32 0 .678 0 .145-.01.329-.01.184-.029.388.165-.01.339-.019.174-.01.329-.01v.514zm-.087-2.326q-.31.019-.64.087-.32.068-.581.203-.262.136-.426.349-.155.213-.155.514.019.329.213.484.203.155.475.155.339 0 .601-.126.262-.136.514-.368-.01-.107-.01-.213 0-.116 0-.242 0-.087 0-.32.01-.242.01-.523z" />
|
||||
<path
|
||||
id="C"
|
||||
d="M28.724 17.767q-.43 0-.779-.196-.35-.203-.558-.552-.203-.356-.203-.81 0-.485.203-.871.203-.387.552-.608.35-.227.786-.227.43 0 .779.209.35.203.558.552.209.35.209.798 0 .473-.209.865-.203.387-.552.614-.35.227-.786.227zm.049-.245q.325 0 .515-.184.19-.184.27-.479.086-.295.086-.62 0-.276-.055-.54-.049-.27-.16-.485-.11-.221-.288-.35-.172-.129-.417-.129-.319 0-.522.184-.203.184-.301.479-.092.295-.092.632 0 .38.104.724.104.338.319.552.215.215.54.215z" />
|
||||
<path
|
||||
id="D"
|
||||
d="M34.456 17.669v-.184q.19 0 .264-.092.074-.098.086-.264.012-.172.012-.393l.006-1.399q0-.098 0-.196.006-.098.025-.203-.11.006-.221.012-.104.006-.215.012v-.258q.27 0 .405-.025.141-.024.209-.061.067-.037.11-.08h.178q.006.043.006.098.006.055.012.123.006.067.006.153.135-.117.295-.209.166-.092.344-.147.184-.055.362-.055.534 0 .779.338.245.331.245 1.037v1.141q0 .123-.006.221 0 .092-.018.196.098-.006.19-.006.098-.006.196-.012v.252h-1.252v-.184q.19 0 .264-.092.074-.098.086-.264.012-.172.012-.393v-.859q-.006-.528-.178-.798-.166-.27-.528-.264-.221.006-.436.117-.209.11-.35.282.006.049.006.11 0 .061 0 .129l-.006 1.565q0 .123-.006.221 0 .092-.018.196.098-.006.19-.006.098-.006.196-.012v.252z" />
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
274
static/style.css
Normal file
274
static/style.css
Normal file
@@ -0,0 +1,274 @@
|
||||
:root {
|
||||
--text-heading: 1.1rem;
|
||||
--text-regular: 0.9rem;
|
||||
--text-small: 0.8rem;
|
||||
--text-xsmall: 0.7rem;
|
||||
--color-primary: blue;
|
||||
--color-muted: #888;
|
||||
--color-border: #ddd;
|
||||
--color-hover: #f5f5f5;
|
||||
}
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: system-ui, sans-serif;
|
||||
line-height: 1.5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--color-primary);
|
||||
&:visited { color: purple; }
|
||||
&:hover { color: inherit; }
|
||||
|
||||
&.light {
|
||||
color: var(--color-muted);
|
||||
&:hover { color: var(--color-primary); }
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
appearance: none;
|
||||
width: 0.9em;
|
||||
height: 0.9em;
|
||||
border: 1.5px solid #999;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
|
||||
&:checked {
|
||||
background: var(--color-primary);
|
||||
border-color: var(--color-primary);
|
||||
}
|
||||
|
||||
&:checked::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 12 12' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2 6L5 9.5L10 2.5' stroke='white' stroke-width='2.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/80% no-repeat;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 1.5px solid var(--color-primary);
|
||||
outline-offset: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Header */
|
||||
header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
|
||||
& h1 { font-size: var(--text-heading); }
|
||||
& p { font-size: var(--text-small); }
|
||||
}
|
||||
|
||||
.header-mail {
|
||||
margin-left: auto;
|
||||
font-size: var(--text-xsmall);
|
||||
color: var(--color-muted);
|
||||
}
|
||||
|
||||
/* Three-column layout */
|
||||
.layout {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* Filters sidebar */
|
||||
.filters {
|
||||
width: 230px;
|
||||
flex-shrink: 0;
|
||||
overflow-y: auto;
|
||||
padding: 0.75rem;
|
||||
border-right: 1px solid var(--color-border);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: var(--text-small);
|
||||
}
|
||||
|
||||
.filter-toggle { display: none; }
|
||||
|
||||
.show-map-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
margin-top: 0.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
font-size: var(--text-xsmall);
|
||||
color: var(--color-muted);
|
||||
margin-top: auto;
|
||||
padding-top: 1rem;
|
||||
|
||||
& p + p { margin-top: 0.5rem; }
|
||||
}
|
||||
|
||||
.search input {
|
||||
width: 100%;
|
||||
padding: 0.3rem 0.4rem;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 1rem 0 0;
|
||||
|
||||
& legend {
|
||||
font-weight: 700;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
& [data-toggle] {
|
||||
font-size: var(--text-xsmall);
|
||||
font-weight: normal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
& label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
padding: 0.05rem 0;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
& .filter-link {
|
||||
display: none;
|
||||
margin-left: auto;
|
||||
font-size: var(--text-xsmall);
|
||||
}
|
||||
|
||||
&:hover .filter-link { display: inline; }
|
||||
}
|
||||
}
|
||||
|
||||
/* Results */
|
||||
.results {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0.5rem;
|
||||
border-right: 1px solid var(--color-border);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.count { padding: 0.25rem; }
|
||||
|
||||
[data-space] {
|
||||
padding: 0.75rem 0.5rem;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
|
||||
& h3 { font-size: var(--text-regular); }
|
||||
|
||||
& .meta, & .address {
|
||||
color: var(--color-muted);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
font-size: var(--text-xsmall);
|
||||
}
|
||||
|
||||
& p { margin-top: 0.15rem; }
|
||||
}
|
||||
|
||||
[data-space]:hover,
|
||||
[data-space][aria-selected="true"] {
|
||||
background: var(--color-hover);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Map */
|
||||
.map-aside {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.leaflet-container a {
|
||||
color: var(--color-primary) !important;
|
||||
}
|
||||
|
||||
.popup-address {
|
||||
color: var(--color-muted);
|
||||
font-size: var(--text-xsmall);
|
||||
}
|
||||
|
||||
/* Taxonomy listing pages */
|
||||
.taxonomy-list {
|
||||
list-style: none;
|
||||
padding: 1rem;
|
||||
columns: 3;
|
||||
|
||||
& li { padding: 0.2rem 0; }
|
||||
}
|
||||
|
||||
/* Detail pages */
|
||||
main.detail {
|
||||
max-width: 700px;
|
||||
padding: 1rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 750px) {
|
||||
html, body { height: auto; overflow: auto; }
|
||||
body { display: block; }
|
||||
|
||||
header { flex-direction: column; align-items: flex-start; }
|
||||
.header-mail { margin-left: 0; }
|
||||
|
||||
.layout { flex-direction: column; flex: none; }
|
||||
|
||||
.filters {
|
||||
width: auto;
|
||||
overflow-y: visible;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
gap: 0.5rem;
|
||||
|
||||
& fieldset { max-height: 200px; overflow-y: auto; }
|
||||
}
|
||||
|
||||
.results { border-right: none; overflow-y: visible; }
|
||||
.map-aside { height: 300px; }
|
||||
.taxonomy-list { columns: 2; }
|
||||
|
||||
.filter-toggle { display: block; text-align: center; }
|
||||
.filters .filter-groups { display: none; }
|
||||
.filters .filter-groups.open { display: contents; }
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
.taxonomy-list { columns: 1; }
|
||||
}
|
||||
21
templates/base.html
Normal file
21
templates/base.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{% block title %}{{ config.title }}{% endblock %}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta property="og:image" content="/thumb.png">
|
||||
<link rel="shortcut icon" href="/favicon.svg" />
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
{% block meta %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1><a href="/">ooru.space</a></h1>
|
||||
{% block subtitle %}{% endblock %}
|
||||
<span class="header-mail">Add or correct something? Send an <a href="mailto:ooru@samagata.org">e-mail</a></span>
|
||||
</header>
|
||||
{% block content %}{% endblock %}
|
||||
{% block scripts %}<script src="/main.js" defer></script>{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
16
templates/index.html
Normal file
16
templates/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
{% extends "layout.html" %}
|
||||
{% import "macros.html" as m %}
|
||||
|
||||
{% block meta %}<meta name="description" content="{{ config.description }}">{% endblock %}
|
||||
|
||||
{% block subtitle %}<p>{{ config.description }}</p>{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% set spaces = section.pages %}
|
||||
{{ m::sidebar(pages=spaces, current_taxonomy="none") }}
|
||||
{% endblock %}
|
||||
|
||||
{% block results %}
|
||||
{% set spaces = section.pages %}
|
||||
{{ m::results(pages=spaces) }}
|
||||
{% endblock %}
|
||||
16
templates/layout.html
Normal file
16
templates/layout.html
Normal file
@@ -0,0 +1,16 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="layout">
|
||||
<aside class="filters" {% block filters_attrs %}data-filters{% endblock %}>
|
||||
{% block sidebar %}{% endblock %}
|
||||
</aside>
|
||||
|
||||
<div class="results" id="results">
|
||||
{% block results %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<aside class="map-aside" data-map>
|
||||
<div id="map"></div>
|
||||
</aside>
|
||||
</div>
|
||||
{% endblock %}
|
||||
84
templates/macros.html
Normal file
84
templates/macros.html
Normal file
@@ -0,0 +1,84 @@
|
||||
{% macro filter_group(name, label, values, taxonomy) %}
|
||||
<fieldset>
|
||||
<legend>{{ label }} <a class="light" data-toggle="{{ name }}">Unselect all</a></legend>
|
||||
{% for v in values | sort %}
|
||||
<label><input type="checkbox" name="{{ name }}" value="{{ v }}" data-filter checked> {{ v }}<a class="filter-link light" href="/{{ taxonomy }}/{{ v | slugify }}/">View</a></label>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro filters(pages, current_taxonomy) %}
|
||||
{% if current_taxonomy != "categories" %}
|
||||
{% set_global cat_set = [] %}
|
||||
{% for page in pages %}
|
||||
{% for c in page.taxonomies.categories %}
|
||||
{% if c not in cat_set %}
|
||||
{% set_global cat_set = cat_set | concat(with=c) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{{ self::filter_group(name="category", label="Categories", values=cat_set, taxonomy="categories") }}
|
||||
{% endif %}
|
||||
|
||||
{% if current_taxonomy != "states" %}
|
||||
{% set_global state_set = [] %}
|
||||
{% for page in pages %}
|
||||
{% for s in page.taxonomies.states %}
|
||||
{% if s not in state_set %}
|
||||
{% set_global state_set = state_set | concat(with=s) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{{ self::filter_group(name="state", label="States", values=state_set, taxonomy="states") }}
|
||||
{% endif %}
|
||||
|
||||
{% if current_taxonomy != "cities" %}
|
||||
{% set_global city_set = [] %}
|
||||
{% for page in pages %}
|
||||
{% for c in page.taxonomies.cities %}
|
||||
{% if c not in city_set %}
|
||||
{% set_global city_set = city_set | concat(with=c) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{{ self::filter_group(name="city", label="Cities", values=city_set, taxonomy="cities") }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro sidebar(pages, current_taxonomy) %}
|
||||
<a href="#" class="filter-toggle" id="filter-toggle">Show filters</a>
|
||||
<div class="filter-groups">
|
||||
<div class="search">
|
||||
<input type="search" id="search" placeholder="Search spaces..." aria-label="Search spaces">
|
||||
</div>
|
||||
<label class="show-map-toggle"><input type="checkbox" id="show-map" checked> Show map</label>
|
||||
{{ self::filters(pages=pages, current_taxonomy=current_taxonomy) }}
|
||||
<footer class="sidebar-footer">
|
||||
<p><a href="/spaces.csv">Download data (CSV)</a><br /><a class="light" href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">CC BY-SA 4.0</a> License</p>
|
||||
<p>Maintained by <a class="light" href="https://samagata.org">Samagata Foundation</a></p>
|
||||
<p><a href="https://gitea.samagata.org/ooru.space/ooru.space">git source</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro results(pages) %}
|
||||
<h3 class="count"><span id="count">{{ pages | length }}</span> space(s)</h3>
|
||||
{% for page in pages %}
|
||||
<article data-space
|
||||
data-state="{{ page.taxonomies.states | first }}"
|
||||
data-city="{{ page.taxonomies.cities | first }}"
|
||||
data-categories="{{ page.taxonomies.categories | join(sep=',') }}"
|
||||
data-lat="{{ page.extra.lat }}"
|
||||
data-lng="{{ page.extra.lng }}"
|
||||
data-name="{{ page.title }}"
|
||||
data-address="{{ page.extra.address | default(value='') }}{% if page.extra.pincode %}, {{ page.extra.pincode }}{% endif %}"
|
||||
>
|
||||
<h3><a href="{{ page.permalink }}">{{ page.title }}</a></h3>
|
||||
<p class="meta">
|
||||
<span class="meta-categories">{% for cat in page.taxonomies.categories %}<a class="light" href="/categories/{{ cat | slugify }}/">{{ cat }}</a>{% if not loop.last %}, {% endif %}{% endfor %}</span>
|
||||
</p>
|
||||
{{ page.content | safe }}
|
||||
{% if page.extra.address %}<p class="address">{{ page.extra.address }}{% if page.extra.pincode %}, {{ page.extra.pincode }}{% endif %}<span class="meta-location"><a class="light" href="/cities/{{ page.taxonomies.cities | first | slugify }}/">{{ page.taxonomies.cities | first }}</a>, <a class="light" href="/states/{{ page.taxonomies.states | first | slugify }}/">{{ page.taxonomies.states | first }}</a></span></p>{% endif %}
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
43
templates/page.html
Normal file
43
templates/page.html
Normal file
@@ -0,0 +1,43 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block title %}{{ page.title }} / {{ config.title }}{% endblock %}
|
||||
|
||||
{% block meta %}<meta name="description" content="{{ page.description }}">{% endblock %}
|
||||
|
||||
{% block subtitle %}<p>{{ page.title }}, {{ page.taxonomies.cities | join(sep=", ") }}</p>{% endblock %}
|
||||
|
||||
{% block filters_attrs %}{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<p>View public community spaces across
|
||||
{% for cat in page.taxonomies.categories %}<a href="/categories/{{ cat | slugify }}/">{{ cat }}</a>{% if not loop.last %}, {% endif %}{% endfor %}
|
||||
|
||||
or spaces in <a href="/cities/{{ page.taxonomies.cities | first | slugify }}/">{{ page.taxonomies.cities | first }}</a>, <a href="/states/{{ page.taxonomies.states | first | slugify }}/">{{ page.taxonomies.states | first }}</a>.</p>
|
||||
<br />
|
||||
<p><a href="/">← All spaces</a></p>
|
||||
{% endblock %}
|
||||
|
||||
{% block results %}
|
||||
<article data-space
|
||||
data-state="{{ page.taxonomies.states | first }}"
|
||||
data-city="{{ page.taxonomies.cities | first }}"
|
||||
data-categories="{{ page.taxonomies.categories | join(sep=',') }}"
|
||||
data-lat="{{ page.extra.lat }}"
|
||||
data-lng="{{ page.extra.lng }}"
|
||||
data-name="{{ page.title }}"
|
||||
data-address="{{ page.extra.address | default(value='') }}{% if page.extra.pincode %}, {{ page.extra.pincode }}{% endif %}"
|
||||
>
|
||||
<h3>{{ page.title }}</h3>
|
||||
<p class="meta">
|
||||
<span class="meta-categories">{% for cat in page.taxonomies.categories %}<a class="light" href="/categories/{{ cat | slugify }}/">{{ cat }}</a>{% if not loop.last %}, {% endif %}{% endfor %}</span>
|
||||
</p>
|
||||
{{ page.content | safe }}
|
||||
{% if page.extra.address %}<p class="address">{{ page.extra.address }}{% if page.extra.pincode %}, {{ page.extra.pincode }}{% endif %}<span class="meta-location"><a class="light" href="/cities/{{ page.taxonomies.cities | first | slugify }}/">{{ page.taxonomies.cities | first }}</a>, <a class="light" href="/states/{{ page.taxonomies.states | first | slugify }}/">{{ page.taxonomies.states | first }}</a></span></p>{% endif %}
|
||||
|
||||
<br />
|
||||
|
||||
{% if page.extra.url %}
|
||||
<p>Visit <a href="{{ page.extra.url }}" rel="noopener">{{ page.extra.url | replace(from="https://", to="") | replace(from="http://", to="") | trim_end_matches(pat="/") }}</a></p>
|
||||
{% endif %}
|
||||
</article>
|
||||
{% endblock %}
|
||||
16
templates/section.html
Normal file
16
templates/section.html
Normal file
@@ -0,0 +1,16 @@
|
||||
{% extends "layout.html" %}
|
||||
{% import "macros.html" as m %}
|
||||
|
||||
{% block title %}{{ section.title }} / {{ config.title }}{% endblock %}
|
||||
|
||||
{% block meta %}<meta name="description" content="{{ section.description | default(value=config.description) }}">{% endblock %}
|
||||
|
||||
{% block subtitle %}<p>{{ section.title }}</p>{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ m::sidebar(pages=section.pages, current_taxonomy="none") }}
|
||||
{% endblock %}
|
||||
|
||||
{% block results %}
|
||||
{{ m::results(pages=section.pages) }}
|
||||
{% endblock %}
|
||||
23
templates/taxonomy_list.html
Normal file
23
templates/taxonomy_list.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ taxonomy.name | title }} / {{ config.title }}{% endblock %}
|
||||
|
||||
{% block meta %}<meta name="description" content="Browse by {{ taxonomy.name }} - {{ config.description }}">{% endblock %}
|
||||
|
||||
{% block subtitle %}
|
||||
<p>Browse by
|
||||
{% if taxonomy.name == "categories" %}category
|
||||
{% elif taxonomy.name == "cities" %}city
|
||||
{% else %}state{% endif %}
|
||||
</p>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<main>
|
||||
<ul class="taxonomy-list">
|
||||
{% for term in terms %}
|
||||
<li><a href="{{ term.permalink }}">{{ term.name }}</a> ({{ term.pages | length }})</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</main>
|
||||
{% endblock %}
|
||||
22
templates/taxonomy_single.html
Normal file
22
templates/taxonomy_single.html
Normal file
@@ -0,0 +1,22 @@
|
||||
{% extends "layout.html" %}
|
||||
{% import "macros.html" as m %}
|
||||
|
||||
{% block title %}{{ term.name }} / {{ config.title }}{% endblock %}
|
||||
|
||||
{% block meta %}<meta name="description" content="{{ term.name }} - {{ config.description }}">{% endblock %}
|
||||
|
||||
{% block subtitle %}
|
||||
{% if taxonomy.name == "categories" %}
|
||||
<p><strong>{{ term.name }}</strong> spaces</p>
|
||||
{% else %}
|
||||
<p>Spaces in <strong>{{ term.name }}</strong></p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ m::sidebar(pages=term.pages, current_taxonomy=taxonomy.name) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block results %}
|
||||
{{ m::results(pages=term.pages) }}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user