Jump to content
ryan

Map Marker Map

Recommended Posts

For some reason the only array item working here is the height....

echo $map->render($items, 'MapMarker', array('height' => '400px', 'zoom' => '15', 'lat' => '50.923813', 'lng' => '4.431493')); 

Share this post


Link to post
Share on other sites

MarkupGoogleMap is going to attempt to fit to all the markers you add to it. So the zoom, lat, lng settings you send to it are only going to matter if you only send it 0 or 1 markers in $items. For instance, if you replace "$items" with "new PageArray()" then you should see your zoom, lat and lng options working. 

Share this post


Link to post
Share on other sites

I just wanted to bring to your attention that having an apostrophe in the title creates an error.  

Whenever I tried to create a map with locations where the title had an apostrophe in it (such as God's River, Manitoba) I would get an  "Uncaught SyntaxError: Unexpected identifier" and the map wouldn't display.  

I changed line 191 in MarkupGoogleMap.module from: 

$out .= "$id.addMarker($marker->lat, $marker->lng, '$url', '$title', ''); ";

to:

$out .= "$id.addMarker($marker->lat, $marker->lng, '$url', \"$title\", ''); "; 

and that seems to have fixed it. 

Share this post


Link to post
Share on other sites

MarkupGoogleMap is going to attempt to fit to all the markers you add to it. So the zoom, lat, lng settings you send to it are only going to matter if you only send it 0 or 1 markers in $items. For instance, if you replace "$items" with "new PageArray()" then you should see your zoom, lat and lng options working. 

The options are working alright but no markers show up. Do you mean it will only work with one marker? If so then how to get the markers from a 'find' show up on the map? Basically just like in the 'skyscrapers' website. As far as I can tell you've done it totally different there.

Share this post


Link to post
Share on other sites
I just wanted to bring to your attention that having an apostrophe in the title creates an error.  

This module assumes that you have entity encoding turned on for your title field. (See Setup > Fields > title > details > Text formatters). This is something you should always have enabled when using ProcessWire for any kind of HTML-driven output. Changing the quote style in the JS would not be an alternative to entity encoding, because you'd run into the same exact problem if one of the page titles happened to have quotes in it. 

Though you could use something like Markdown or Textile too, but I'm honestly not sure if those entity encode apostrophes or not. If not, the only solution may be an str_replace(array("'", '"'), array('"', '&apos'), $page->title); ahead of time. 

The options are working alright but no markers show up. Do you mean it will only work with one marker? If so then how to get the markers from a 'find' show up on the map? Basically just like in the 'skyscrapers' website. As far as I can tell you've done it totally different there.

This module can accept a single Page or a PageArray. If given a PageArray it'll map them all and fit the map to the markers. If given a single page, it should still map the marker and use the zoom setting from that marker. However, you may need to modify the module to suit your needs. In the instances where I'm using it, I typically modify it. Though the skyscrapers profile was made long before this module, so it is using something quite a bit older and not a module at all. 

Share this post


Link to post
Share on other sites

If using the 'new PageArray()' where or how do I tell it to show the markers that I want?

echo $map->render(new PageArray($pages->find("template=bfd_places, MapMarker!=''")), 'MapMarker', array('height' => '400px', 'zoom' => '2', 'lat' => '50.923813', 'lng' => '4.431493'));

It's probably obvious for seasoned programmers but I can't find any reasonable or understandable examples or explanation. (Hints or directions towards sources are welcome)

Share this post


Link to post
Share on other sites

This is an amazing module! I've only scraped the surface but just from reading through this thread it seems very powerful.

I was wondering if there was a quick way to hide the businesses that show up on the map. I'm using this to make a restaurant site and I'm trying to avoid having other restaurants (but businesses in general) pop up on the map.

Share this post


Link to post
Share on other sites
If using the 'new PageArray()' where or how do I tell it to show the markers that I want?

You should give it a PageArray of pages that each have a 'map' field. Each of those pages (that has a 'map' field) will be considered a marker. You specify the name of your map field as the second argument. i.e. 

$places = $pages->find("template=bfd_places"); 
$options = array('width' => '100%', 'height' => '400px');  
// "map" below is the name of the FieldtypeMapMarker field in PW
echo $map->render($places, 'map', $options); 

Also wanted to mention I found a JS error in the last version that corresponds with the error you were seeing before where no marker would appear. In fact, a marker should have been appearing, but there was a small JS error in there, which has now been fixed. Grab the latest to see if it resolves the issue you were having before?

I was wondering if there was a quick way to hide the businesses that show up on the map. I'm using this to make a restaurant site and I'm trying to avoid having other restaurants (but businesses in general) pop up on the map.

I've actually not seen businesses show up on the map before? :) At least, we aren't specifying any options to make it do so. Can you post a screenshot, just in case I'm misunderstanding what you are talking about? I'm wondering if it might somehow be picking up some google-specific setting associated with your Google account. 

Share this post


Link to post
Share on other sites

Some new $options have been added to MarkupGoogleMap: 

'icon' => 'http://domain.com/path/to/icon.png', 

Full URL to icon file to use for markers. Blank=use default Google marker icon. 
 
'useHoverBox' => false
Use hover box? When true, shows a tooltip-type box when you hover the marker, that is populated with the markerTitleField. This is often more useful than the default presentation google maps uses.
 
'hoverBoxMarkup' => "<div> (see below) </div>"
When useHoverBox is true, you can specify the markup used for it. Use the following (which is the default) as your starting point:
<div 
  data-top='-10' <!-- offset from top of marker (in pixels) -->
  data-left='15' <!-- offset from left of marker (in pixels) -->
  style='        <!-- inline styles, or specify your own class attribute -->
    background: #000; 
    color: #fff; 
    padding: 0.25em 0.5em; 
    border-radius: 3px;
  '>
</div>
 
 
 
  • Like 3

Share this post


Link to post
Share on other sites

One other thing to add: if you use the 'useHoverBox' option and either don't see the hover box working, or see it showing up in the wrong place, you'll want to put your map in a container that has position=relative or position=absolute

echo "<div style='position: relative;'>" . $map->render($items, 'map', $options) . "</div>";

Share this post


Link to post
Share on other sites

You should give it a PageArray of pages that each have a 'map' field. Each of those pages (that has a 'map' field) will be considered a marker. You specify the name of your map field as the second argument. i.e. 

$places = $pages->find("template=bfd_places"); 
$options = array('width' => '100%', 'height' => '400px');  
// "map" below is the name of the FieldtypeMapMarker field in PW
echo $map->render($places, 'map', $options); 

Also wanted to mention I found a JS error in the last version that corresponds with the error you were seeing before where no marker would appear. In fact, a marker should have been appearing, but there was a small JS error in there, which has now been fixed. Grab the latest to see if it resolves the issue you were having before?

The markers now fit the map better, no more two Alaskas showing. Still, only the height option works with the solution above.

When generating three maps on the same page, the first and third are exactly the same apart from height. In the second zoom and coordinates work but no markers.

	<?php 
	$map = $modules->get('MarkupGoogleMap'); 
	$places = $pages->find("template=bfd_places, MapMarker!='', sort=title"); 
	echo $map->render($places, 'MapMarker', array('height' => '400px')); 
    ?>
    <hr>
    <?php 
	echo $map->render(new PageArray($pages->find("template=bfd_places")), 'MapMarker', array('height' => '400px', 'zoom' => '5', 'lat' => '50.923813', 'lng' => '4.431493')); 
    ?>
    <hr>
    <?php
    $places = $pages->find("template=bfd_places"); 
	$options = array('width' => '100%', 'height' => '300px',  'zoom' => '5',  'lat' => '50.923813', 'lng' => '4.431493');  
	echo $map->render($places, 'MapMarker', $options); 
	?>

See result here: http://www.birthfactdeathcalendar.net/bfd_processwire/places/

Entering an address or coordinates in the MapMarker address field doesn't keep the info yet upon publishing the page either. It still needs to be entered twice. Once in a while, when fiddling with zoom or moving the marker on the map before publishing the page it keeps the input properly.

Using the new version and will try out the new icon and hover options soon. Thank you for that.

Share this post


Link to post
Share on other sites

I've actually not seen businesses show up on the map before? :) At least, we aren't specifying any options to make it do so. Can you post a screenshot, just in case I'm misunderstanding what you are talking about? I'm wondering if it might somehow be picking up some google-specific setting associated with your Google account. 

I'm attaching a screenshot. Timeless Nails, Tango Palace, etc. I hear they're called POI (points of interest) but I am unsure how to add any settings for disabling these with the module. Thanks!

post-466-0-17219900-1384292206_thumb.png

Share this post


Link to post
Share on other sites

I'm attaching a screenshot. Timeless Nails, Tango Palace, etc. I hear they're called POI (points of interest) but I am unsure how to add any settings for disabling these with the module. Thanks!

If you set your map to satellite view these 'points of interest' don't show up. Well, only parks and some official buildings do but no business stuff. When zooming in, street names are all visible and people can even switch to street view to actually see the place you're 'marking'.

Share this post


Link to post
Share on other sites

This config option should disable the POI for you:

 [ { featureType: "poi", elementType: "labels", stylers: [ { visibility: "off" } ] } ]

Obviously this is not a module setting, but rather a setting you need to add to the javascript that loads the map on the frontend.

Hope that helps.

  • Like 1

Share this post


Link to post
Share on other sites

This config option should disable the POI for you:

 [ { featureType: "poi", elementType: "labels", stylers: [ { visibility: "off" } ] } ]

Obviously this is not a module setting, but rather a setting you need to add to the javascript that loads the map on the frontend.

Hope that helps.

Thanks but this is the code I have:

In the head:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>

And then in the body:

<?php // Render the map

				$map = $modules->get('MarkupGoogleMap');
				echo $map->render($page, 'address_map', array('type' => 'ROADMAP'));
			?>

Where would I put the code you suggest?

Share this post


Link to post
Share on other sites

Hi tina,

Sorry for the limited answer - was in a hurry.

Actually looking at this module a little more, I realize that I have never used the built-in render, but rather just used it as a way to enter addresses in the admin. I have been using Ryan's RCDmap class: http://processwire.com/talk/topic/690-map-marker-fieldtype/?p=10667

Although I actually haven't hidden the poi in any PW sites yet, so I don't have a final code snippet for you. However, this is the code that I used on a mobile site I developed that made use of: https://code.google.com/p/jquery-ui-map/

var myStyles =[
    {
        featureType: "poi",
        elementType: "labels",
        stylers: [
              { visibility: "off" }
        ]
    }
];

$('#map_canvas').gmap('option', 'styles', myStyles);
 

I wouldn't necessarily recommend jquery-ui-map - I thought it might be worth trying, but mostly just seemed to add another layer of complexity. I think I would stick with the standard gmaps api.

Here is a relevant POI link from google: https://developers.google.com/maps/documentation/javascript/reference#MapTypeStyleFeatureType

Hope that helps.

  • Like 1

Share this post


Link to post
Share on other sites

Hi tina,

Sorry for the limited answer - was in a hurry.

Actually looking at this module a little more, I realize that I have never used the built-in render, but rather just used it as a way to enter addresses in the admin. I have been using Ryan's RCDmap class: http://processwire.com/talk/topic/690-map-marker-fieldtype/?p=10667

Although I actually haven't hidden the poi in any PW sites yet, so I don't have a final code snippet for you. However, this is the code that I used on a mobile site I developed that made use of: https://code.google.com/p/jquery-ui-map/

var myStyles =[
    {
        featureType: "poi",
        elementType: "labels",
        stylers: [
              { visibility: "off" }
        ]
    }
];

$('#map_canvas').gmap('option', 'styles', myStyles);
 

I wouldn't necessarily recommend jquery-ui-map - I thought it might be worth trying, but mostly just seemed to add another layer of complexity. I think I would stick with the standard gmaps api.

Here is a relevant POI link from google: https://developers.google.com/maps/documentation/javascript/reference#MapTypeStyleFeatureType

Hope that helps.

Thanks Adrian, I decided to just use the Google Maps API and the values created by the ProcessWire module to assist in that. I used the visibility: off for the POI and that worked. Thanks.

  • Like 1

Share this post


Link to post
Share on other sites

Trying to get multiple markers on a map. All found MapMarker entries show up in the list, but only the last one from the list shows up on the map. How do I get them all to show up on the map?

$features = $pages->find("parent=/events/, bfd_day.name=$todayday, bfd_month.name=$todaymonth, sort=bfd_year");
foreach($features as $feature) {
$placepage = $feature->bfd_events_places_id_list;
echo "{$placepage->MapMarker}";
};

$map = $modules->get('MarkupGoogleMap'); 
$options = array('width' => '100%', 'height' => '400px');
echo $map->render($placepage, 'MapMarker', $options); 

Share this post


Link to post
Share on other sites

Based on your code, from what I can tell, you need to pass $features to the $map->render() rather than $placepage. 

Share this post


Link to post
Share on other sites

When passing $features there is no map at all....

The MapMarker field is called into 'events' by a matching id, 'bfd_events_places_id_list' is the page id of a 'place' page. A 'place' page can be used for more than one event. When the id matches the fields from the 'place' page (name, street, city, state, country, MapMarker) are shown on the 'event' page, with the correct map.

echo "{$placepage->MapMarker}"; shows the individual 'MapMarker' data in the foreach list but I can't find how to enter it in the $map->render(), except that it only shows the last marker.

Share this post


Link to post
Share on other sites

The $map->render() requires either a Page with a 'MapMarker' field or a PageArray with multiple pages, each containing a 'MapMarker' field. If you are giving it a PageArray of multiple pages, and it's only showing a marker for 1 of them, then chances are that only one of the pages you gave it has a 'MapMarker' field. Keep in mind the field must be named consistently with what you tell it. Meaning, if you are calling $map->render($features, 'MapMarker', $options); then every one of the pages in $features must literally have a map marker field named 'MapMarker'. If they don't, then chances are that $features is not the group of pages you really want to send to render(). But $placepage clearly isn't either, since that's just 1 page (which is only going to print 1 marker). Based on looking at your code, I'm guessing this might be what you want?

$features = $pages->find("parent=/events/, bfd_day.name=$todayday, bfd_month.name=$todaymonth, sort=bfd_year");
$markers = new PageArray();
foreach($features as $feature) {
  $markers->add($feature->bfd_events_places_id_list); 
}
$map = $modules->get('MarkupGoogleMap'); 
$options = array('width' => '100%', 'height' => '400px');
echo $map->render($markers, 'MapMarker', $options); 
  • Like 1

Share this post


Link to post
Share on other sites

YES!

Thank you very much. I would never have thought of anything like this. Any idea where/how I can pimp by low/moderate php skills to handle such situations?

Share this post


Link to post
Share on other sites
	$features = $pages->find("parent=/events/, bfd_month.name=$month, bfd_day.name=$day, sort=bfd_day, sort=bfd_year, sort=name");
	$markers = new PageArray();
	foreach($features as $feature) {
	$markers->add($feature->bfd_events_places_id_list); 
	}
	if ($markers && $feature->bfd_day) {
	$map = $modules->get('MarkupGoogleMap'); 
	$options = array('width' => '100%', 'height' => '500px', 'zoom' => '4');
	echo $map->render($markers, 'MapMarker', $options);
	}
	else {
	echo "";
	};

When there are two identical markers (two events happening on the same day in the same place in above example), the map is not rendered.

Share this post


Link to post
Share on other sites

Hello all,

I would like to add a standard Gmaps info window (the white balloon type with shadow) to my marker.

I have a single marker on the map and use standard $map->render function.

From the Gmaps API documentation about info windows I see that I somehow have to add something like

  var infowindow = new google.maps.InfoWindow({
      content: contentString
  });

How would I go about that, can I create something like a hook event to extend the standard render function from the module or can I just add a piece of JS to the page?

Any enlightenment would be much appreciated.

Cheers

gerhard

Share this post


Link to post
Share on other sites

I've installed this module for the first time locally, on PW 2.3.8 dev.

The backend looks fine - except a notice at the bottom: Geocode OFF

Anybody knows why?

In my map template, I have just this:

// head:
<script type='text/javascript' src='https://maps.googleapis.com/maps/api/js?sensor=false'></script>

// body:
<?php
echo $page->marker->address . '<hr>'; 	// outputs the address you entered
echo $page->marker->lat . '<hr>'; 	// outputs the latitude
echo $page->marker->lng . '<hr>'; 	// outputs the longitude

$map = $modules->get('MarkupGoogleMap');
echo $map->render($page, 'map');
?>

What I actually see in the rendered frontend, is just this:

<div id='mgmap1' class='MarkupGoogleMap' style='width: 100%; height: 300px;'></div><script type='text/javascript'>if(typeof google === 'undefined' || typeof google.maps === 'undefined') { alert('MarkupGoogleMap Error: Please add the maps.googleapis.com script in your document head.'); } else { var mgmap1 = new MarkupGoogleMap(); mgmap1.setOption('zoom', 18); mgmap1.setOption('mapTypeId', google.maps.MapTypeId.HYBRID); mgmap1.init('mgmap1', 0.000000, 0.000000); mgmap1.addMarker(0.000000, 0.000000, '/path/to/google-map-test/', 'Google Map Test', ''); }</script>

No map is shown, no address or lat/lng are shown either.

Is it necessary to add your own GM API key somewhere?

Is it known to simply not work from localhost / 127.0.0.1?

Or do I have to change the GM JS URL or add parameters? (v3)?

Thanks in advance for tips and pointers.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Gadgetto
      SnipWire - Snipcart integration for ProcessWire
      Snipcart is a powerful 3rd party, developer-first HTML/JavaScript shopping cart platform. SnipWire is the missing link between Snipcart and the content management framework ProcessWire.
      With SnipWire, you can quickly turn any ProcessWire site into a Snipcart online shop. The SnipWire plugin helps you to get your store up and running in no time. Detailed knowledge of the Snipcart system is not required.
      SnipWire is free and open source licensed under Mozilla Public License 2.0! A lot of work and effort has gone into development. It would be nice if you could donate an amount to support further development:

      Status update links (inside this thread) for SnipWire development
      2020-07-03 -- SnipWire 0.8.7 (beta) released! Fixes some small bugs and adds an indicator for TEST mode 2020-04-06 -- SnipWire 0.8.6 (beta) released! Adds support for Snipcart subscriptions and also fixes some problems 2020-03-21 -- SnipWire 0.8.5 (beta) released! Improves SnipWires webhooks interface and provides some other fixes and additions 2020-03-03 -- SnipWire 0.8.4 (beta) released! Improves compatibility for Windows based Systems. 2020-03-01 -- SnipWire 0.8.3 (beta) released! The installation and uninstallation process has been heavily revised. 2020-02-08 -- SnipWire 0.8.2 (beta) released! Added a feature to change the cart and catalogue currency by GET, POST or SESSION param 2020-02-03 -- SnipWire 0.8.1 (beta) released! All custom classes moved into their own namespaces. 2020-02-01 -- SnipWire is now available via ProcessWire's module directory! 2020-01-30 -- SnipWire 0.8.0 (beta) first public release! (module just submitted to the PW modules directory) 2020-01-28 -- added Custom Order Fields feature (first SnipWire release version is near!) 2020-01-21 -- Snipcart v3 - when will the new cart system be implemented? 2020-01-19 -- integrated taxes provider finished (+ very flexible shipping taxes handling) 2020-01-14 -- new date range picker, discount editor, order notifiactions, order statuses, and more ... 2019-11-15 -- orders filter, order details, download + resend invoices, refunds 2019-10-18 -- list filters, REST API improvements, new docs platform, and more ... 2019-08-08 -- dashboard interface, currency selector, managing Orders, Customers and Products, Added a WireTabs, refinded caching behavior 2019-06-15 -- taxes provider, shop templates update, multiCURL implementation, and more ... 2019-06-02 -- FieldtypeSnipWireTaxSelector 2019-05-25 -- SnipWire will be free and open source Plugin Key Features
      Fast and simple store setup Full integration of the Snipcart dashboard into the ProcessWire backend (no need to leave the ProcessWire admin area) Browse and manage orders, customers, discounts, abandoned carts, and more Multi currency support Custom order and cart fields Process refunds and send customer notifications from within the ProcessWire backend Process Abandoned Carts + sending messages to customers from within the ProcessWire backend Complete Snipcart webhooks integration (all events are hookable via ProcessWire hooks) Integrated taxes provider (which is more flexible then Snipcart own provider) Useful Links
      SnipWire in PW modules directory SnipWire Docs (please note that the documentation is a work in progress) SnipWire @GitHub (feature requests and suggestions for improvement are welcome - I also accept pull requests) Snipcart Website  

       
      ---- INITIAL POST FROM 2019-05-25 ----
       
    • By Sten
      Hello
      Till now I hacked something with the twig template but it works no more with new PW versions so I look forward to create a module. I am working on a site in multiple languages : French, English, Italian, German, Spanish, Portuguese, Hebrew, Russian. The new posts are entered in any language with a field for language. Till now, I got twig files to get the translations with constants defined for each part of the pages.
      So I'd like to create a module to include theses files added according to the url /fr/en/...
      Have you some observations to do before I begin about the direction to take ?
      Thank you
    • By ukyo
      Mystique Module for ProcessWire CMS/CMF
      Github repo : https://github.com/trk/Mystique
      Mystique module allow you to create dynamic fields and store dynamic fields data on database by using a config file.
      Requirements
      ProcessWire 3.0 or newer PHP 7.0 or newer FieldtypeMystique InputfieldMystique Installation
      Install the module from the modules directory:
      Via Composer:
      composer require trk/mystique Via git clone:
      cd your-processwire-project-folder/ cd site/modules/ git clone https://github.com/trk/Mystique.git Module in live reaction with your Mystique config file
      This mean if you remove a field from your config file, field will be removed from edit screen. As you see on youtube video.
      Using Mystique with your module or use different configs path, autoload need to be true for modules
      Default configs path is site/templates/configs/, and your config file name need to start with Mystique. and need to end with .php extension.
      Adding custom path not supporting anymore !
      // Add your custom path inside your module class`init` function, didn't tested outside public function init() { $path = __DIR__ . DIRECTORY_SEPARATOR . 'configs' . DIRECTORY_SEPARATOR; Mystique::add($path); } Mystique module will search site/modules/**/configs/Mystique.*.php and site/templates/Mystique.*.php paths for Mystique config files.
      All config files need to return a PHP ARRAY like examples.
      Usage almost same with ProcessWire Inputfield Api, only difference is set and showIf usage like on example.
      <?php namespace ProcessWire; /** * Resource : testing-mystique */ return [ 'title' => __('Testing Mystique'), 'fields' => [ 'text_field' => [ 'label' => __('You can use short named types'), 'description' => __('In file showIf working like example'), 'notes' => __('Also you can use $input->set() method'), 'type' => 'text', 'showIf' => [ 'another_text' => "=''" ], 'set' => [ 'showCount' => InputfieldText::showCountChars, 'maxlength' => 255 ], 'attr' => [ 'attr-foo' => 'bar', 'attr-bar' => 'foo' ] ], 'another_text' => [ 'label' => __('Another text field (default type is text)') ] ] ]; Example:
      site/templates/configs/Mystique.seo-fields.php <?php namespace ProcessWire; /** * Resource : seo-fields */ return [ 'title' => __('Seo fields'), 'fields' => [ 'window_title' => [ 'label' => __('Window title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'attr' => [ 'placeholder' => __('Enter a window title') ] ], 'navigation_title' => [ 'label' => __('Navigation title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'showIf' => [ 'window_title' => "!=''" ], 'attr' => [ 'placeholder' => __('Enter a navigation title') ] ], 'description' => [ 'label' => __('Description for search engines'), 'type' => Mystique::TEXTAREA, 'useLanguages' => true ], 'page_tpye' => [ 'label' => __('Type'), 'type' => Mystique::SELECT, 'options' => [ 'basic' => __('Basic page'), 'gallery' => __('Gallery'), 'blog' => __('Blog') ] ], 'show_on_nav' => [ 'label' => __('Display this page on navigation'), 'type' => Mystique::CHECKBOX ] ] ]; Searching data on Mystique field is limited. Because, Mystique saving data to database in json format. When you make search for Mystique field, operator not important. Operator will be changed with %= operator.
      Search example
      $navigationPages = pages()->find('my_mystique_field.show_on_nav=1'); $navigationPages = pages()->find('my_mystique_field.page_tpye=gallery');
    • By Robin S
      This is a module I made as an experiment a while ago and never got around to releasing publicly. At the time it was prompted by discussions around using Repeater fields for "page builder" purposes, where the depth feature could possibly be used for elements that would be nested inside other elements. I thought it would be useful to enforce some depth rules and translate the depth data into a multi-dimensional array structure.
      I'm not using this module anywhere myself but maybe it's useful to somebody.
      Repeater Depth Helper
      This module does two things relating to Repeater fields that have the "Item depth" option enabled:
      It enforces some depth rules for Repeater fields on save. Those rules are:
      The first item must have a depth of zero. Each item depth must not be more than one greater than previous item depth. It provides a RepeaterPageArray::getDepthStructure helper method that returns a nested depth structure for a Repeater field value.
      Helper method
      The module adds a RepeaterPageArray::getDepthStructure method that returns a multi-dimensional array where the key is the page ID and the value is an array of nested "child" items, or null if there are no nested children.
      Example

      The module doesn't make any assumptions about how you might want to use the depth structure array, but here is a way you might use it to output a nested unordered list.
      // Output a nested unordered list from a depth structure array function outputNestedList($depth_structure, $repeater_items) { $out = "<ul>"; foreach($depth_structure as $page_id => $nested_children) { $out .= "<li>" . $repeater_items->get("id=$page_id")->title; // Go recursive if there are nested children if(is_array($nested_children)) $out .= outputNestedList($nested_children, $repeater_items); $out .= "</li>"; } $out .= "</ul>"; return $out; } $repeater_items = $page->my_repeater; $depth_structure = $repeater_items->getDepthStructure(); echo outputNestedList($depth_structure, $repeater_items);
       
      https://github.com/Toutouwai/RepeaterDepthHelper
      https://modules.processwire.com/modules/repeater-depth-helper/
    • By MoritzLost
      Cacheable Placeholders
      This module allows you to have pieces of dynamic content inside cached output. This aims to solve the common problem of having a mostly cacheable site, but with pieces of dynamic output here and there.  Consider this simple example, where you want to output a custom greeting to the current user:
      <h1>Good morning, <?= ucfirst($user->name) ?></h1> This snippet means you can't use the template cache (at least for logged-in users), because each user has a different name. Even if 99% of your output is static, you can only cache the pieces that you know won't include this personal greeting. A more common example would be CSRF tokens for HTML forms - those need to be unique by definition, so you can't cache the form wholesale.
      This module solves this problem by introducing cacheable placeholders - small placeholder tokens that get replaced during every request. The replacement is done inside a Page::render hook so it runs during every request, even if the response is served from the template cache. So you can use something like this:
      <h1>Good morning, {{{greeting}}}</h1> Replacement tokens are defined with a callback function that produces the appropriate output and added to the module through a simple hook:
      // site/ready.php wire()->addHookAfter('CachePlaceholders::getTokens', function (HookEvent $e) { $tokens = $e->return; $tokens['greeting'] = [ 'callback' => function (array $tokenData) { return ucfirst(wire('user')->name); } ]; $e->return = $tokens; }); Tokens can also include parameters that are parsed and passed to the callback function. There are more fully annotated examples and step-by-step instructions in the README on Github!
      Features
      A simple and fast token parser that calls the appropriate callback and runs automatically. Tokens may include multiple named or positional parameters, as well as multi-value parameters. A manual mode that allows you to replace tokens in custom pieces of cached content (useful if you're using the $cache API). Some built-in tokens for common use-cases: CSRF-Tokens, replacing values from superglobals and producing random hexadecimal strings. The token format is completely customizable, all delimiters can be changed to avoid collisions with existing tag parsers or template languages. Links
      Github Repository & documentation Module directory If you are interested in learning more, the README is very extensive, with more usage examples, code samples and usage instructions!
×
×
  • Create New...