Open goodyis opened 4 months ago
You're looking for something like a full template engine for the geojson? Like having an if statement to conditionally show the assistant info?
@bozdoz Not really a full templating system, just a way to check if a json key/pair is empty before showing it.
so something like::
[leaflet-map fitbounds scrollwheel zoomcontrol !detect-retina show_scale draggable height="500"]
[leaflet-geojson src="xxxx" fitbounds="1" iconUrl="xxxx" iconSize="80,50" iconAnchor="40,60"]
<b>{location-name}</b></br><span class="map-link">{loc-address}</span>
</br>Manager: {loc-manager}
<a href="tel:{loc-number}"/>{loc-number}</a> Direct
<a href="tel:{manager-cell}"/>{manager-cell}</a> Cell</br>
</hr>
if ({loc-assistant} & {assist-cell}) {
Assistant Manager: {loc-assistant}
<a href="tel:{assist-cell}"/>{assist-cell}</a> Cell</br>
}
if ({popup-text}) {
</hr>
More Info: {popup-text}
}
[/leaflet-geojson]
The goal being this popup below would not show the "More Info: {popup-text}" Because the json for that element is "popup-text": "", While the same thing happens if the element doesn't have popup-text listed as a parameter.
@bozdoz So a weird work around, if I could get the javascript to actually run after the elements are loaded is to change someof the 'class.geojson-shortcode.php' code to the following:
function checkProperties(obj) {
for (var key in obj) {
if (obj[key] !== null && obj[key] !== "") {
return false;
}
}
return true;
}
function removeEmpty(obj) {
return Object.entries(obj)
.filter(([_, v]) => v !== null && v !== "")
.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {});
}
function onEachFeature (feature, layer) {
var props = feature.properties || {};
//console.log(props);
var text;
//console.log(text);
if (<?php echo $table_view; ?>) {
text = window.WPLeafletMapPlugin.propsToTable(props);
} else {
var text = ""; // Initialize text variable
// Assuming window.WPLeafletMapPlugin.template(feature.properties) returns an object
var templateProperties = window.WPLeafletMapPlugin.template(feature.properties);
Object.keys(templateProperties).forEach(function (key) {
var value = templateProperties[key];
if (checkProperties(value)) {
// Given key does not exist or it has "" or NULL value
//console.log("other: " + value);
// If you want to remove empty properties, use removeEmpty function
//templateProperties[key] = removeEmpty(value);
templateProperties[key] = "<span class='removeMe'>n\/a</span>";
} else {
//console.log("happy: " + value);
// Add the non-empty value to the text variable
//text += value;
}
});
text = popup_property
? props[ popup_property ]
: window.WPLeafletMapPlugin.template(
popup_text,
feature.properties
);
}
if (text) {
layer.bindPopup( text );
}
}
Then change the shortcode to have the section wrapped in a span with class like:
<span class="parent"><hr/>More Info: {popup-text}</span>[/leaflet-geojson]
Then have the following js added:
<script>
jQuery( document ).ready(function($) {
console.log( "ready!" );
$('.removeMe').closest('.parent').remove();
});
</script>
This seems like non-scalable workaround.
I'm hoping you have a cleaner idea.
@bozdoz I've get it working. I don't think you would call this a 'template engine'
Could you add a hook where I/others could override this file or functions?
add checkProperties function to class.geojson-shortcode.php
function checkProperties(obj) {
for (var key in obj) {
if (obj[key] !== null && obj[key] !== "") {
return false;
}
}
return true;
}
modify the onEachFeature function to include a call to the checkProperties function created
modify output of a property that doesn't have contain a value to be wrapped in a span with a class
optional include the text N/A in that span for new default text
function onEachFeature (feature, layer) {
var props = feature.properties || {};
var text;
if (<?php echo $table_view; ?>) {
text = window.WPLeafletMapPlugin.propsToTable(props);
} else {
var text = ""; // Initialize text variable
// Assuming window.WPLeafletMapPlugin.template(feature.properties) returns an object
var templateProperties = window.WPLeafletMapPlugin.template(feature.properties);
Object.keys(templateProperties).forEach(function (key) {
var value = templateProperties[key];
if (checkProperties(value)) {
// Given key does not exist or it has "" or NULL value
// Replaces empty values with N/a and class name so it can be removed
templateProperties[key] = "<span class='removeMe'>n\/a</span>";
}
});
// the following is unchanged
text = popup_property
? props[ popup_property ]
: window.WPLeafletMapPlugin.template(
popup_text,
feature.properties
);
}
if (text) {
layer.bindPopup( text );
}
}
then when shortcode used in wordpress, wrap each section with a .parent span
[leaflet-geojson src="XXX.map.geojson" fitbounds="1" iconUrl="pathToImage.png" iconSize="80,50" iconAnchor="40,60"]
<span class="parent"><b>{location-name}</b></span>
<span class="parent"></br><span class="map-link">{loc-address}</span></span>
<span class="parent"></br>Manager: {loc-manager}</span>
<span class="parent"><a href="tel:{loc-number}"/>{loc-number}</a> Direct</span>
<span class="parent"><a href="tel:{manager-cell}"/>{manager-cell}</a> Cell</br></span>
<span class="parent"><hr/>Assistant Manager: {loc-assistant}
<a href="tel:{assist-cell}"/>{assist-cell}</a> Cell</br></span>
<span class="parent"><hr/>More Info: {popup-text}</span>[/leaflet-geojson]
then very simple CSS; could be placed in theme, or in the wordpress block where shortcode is called
.parent:has(.removeMe) {
display: none;
}
I think all you may need is a hook in the onEachFeature function
What do you think of this? https://github.com/bozdoz/wp-plugin-leaflet-map/pull/249
@bozdoz That did the trick; thank you sir. Since that passed tests on the pull request, will you be pushing that on your next update?
actually on second thought, it should just be a javascript implementation, instead of php
On third thought, it may be way less maintainable to move it to javascript. I'll reconsider
Using the Wordpress plugin, and the geojson mapping is working. So long as all the fields I call are either populated and/or present. Meaning I'll locations that might have all 8 data-properties, but some locations will only have 5 data-points. The shortcode template is calling all data points. But I can't have locations showing the empty 'key/value' pair for data that is not assigned to the property.
I'm hoping I'm over thinking this; maybe there is a way to tell the shortcode to check for empty values and to not display that section, or there is a better way then editing the 'GeoJSON Shortcode Class' file. Because I've been able to check that value/key pairs and remove any that are empty, but then 'feeding' them back into the text var isn't allowing the shortcode to function properly.
So with no filtering/edits, the shortcode works and pulls the geojson and displays as I would like, expect it displays values that are empty. With the edits, the geojson value is still pushed through and without empty values, but then ignores the shortcode 'instructions.'
Here is wordpress shortcode entry:
Here is the json sample data:
Here is the js I've been editing: