Skip to content

Commit

Permalink
Added several options to Twig/PHP tag method
Browse files Browse the repository at this point in the history
  • Loading branch information
lindseydiloreto committed Mar 1, 2021
1 parent 4d8e0d8 commit 4463d01
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 73 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 4.0.2 - UNRELEASED

### Added
- Added [`api`](https://plugins.doublesecretagency.com/google-maps/dynamic-maps/twig-php-methods/#tag-options) option to Twig/PHP `tag` method.
- Added [`assets`](https://plugins.doublesecretagency.com/google-maps/dynamic-maps/twig-php-methods/#tag-options) option to Twig/PHP `tag` method.
- Added [`callback`](https://plugins.doublesecretagency.com/google-maps/dynamic-maps/twig-php-methods/#tag-options) option to Twig/PHP `tag` method.

## 4.0.1 - 2021-02-26

### Added
Expand Down
2 changes: 0 additions & 2 deletions docs/dynamic-maps/map-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ Most (though not all) of these options are available across JavaScript, Twig, an
| `infoWindowOptions` | JS/Twig/PHP | Accepts any [`google.maps.InfoWindowOptions`](https://developers.google.com/maps/documentation/javascript/reference/info-window#InfoWindowOptions) properties.
| `infoWindowTemplate` | Twig/PHP | Template path to use for creating [info windows](/dynamic-maps/info-windows/). |
| `field` | Twig/PHP | Address field(s) to be included on the map. (includes all by default)
| `js` | Twig/PHP | Whether to preload the necessary external JavaScript.
| `callback` | Twig/PHP | JavaScript function to run after the map has loaded.

:::warning Additional Details
For more info, please consult either the [JavaScript method](/javascript/googlemaps.js/#map-locations-options) or the [Twig/PHP constructor](/models/dynamic-map-model/#construct-locations-options).
Expand Down
13 changes: 8 additions & 5 deletions docs/dynamic-maps/twig-php-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ The `tag` method also exists in [JavaScript](/dynamic-maps/javascript-methods/#t

Regardless of whether you are using Twig or PHP, this will create a new `Twig\Markup` object.

If you are working in Twig, you can use curly braces to output the map directly.
If you are working in Twig, you can use curly braces to output the map directly. This produces a `<div>` element with a carefully constructed `data-dna` property.

#### Arguments

- `options` (_array_) - Configuration options for the rendered `<div>`.
- `options` (_array_) - Configuration options for the map container and its related JavaScript.

| Option | Type | Default | Description
|:-------|:------:|:-------:|-------------
| `init` | _bool_ | `true` | Whether to automatically initialize the map via JavaScript.
| Option | Type | Default | Description
|:-----------|:--------:|:-------:|:------------
| `api` | _object_ | `{}` | Optional parameters for the Google Maps API.
| `assets` | _bool_ | `true` | Whether to preload the necessary JavaScript assets.
| `init` | _bool_ | `true` | Whether to automatically initialize the map via JavaScript.
| `callback` | _string_ | `null` | JavaScript function to run after the map has loaded.

The `init` option allows the map to be automatically rendered via JavaScript, after the `<div>` element has first been loaded onto the page via Twig.

Expand Down
48 changes: 26 additions & 22 deletions docs/guides/clustering-markers.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,58 @@
# Clustering Markers

To implement [marker clustering](https://developers.google.com/maps/documentation/javascript/marker-clustering), an additional JavaScript library is required.

## Example

Before any further explanation, here is the general snippet from which you can copy & paste to add marker clustering to your [dynamic map](/dynamic-maps/). It will likely require some minor adjustments for your site.

```twig
{# Load the marker clustering library #}
{# 1. Load the marker clustering library #}
{% js 'https://unpkg.com/@googlemaps/markerclustererplus/dist/index.min.js' %}
{# Create the JS callback function #}
{# 2. Create the JS callback function #}
{% js %}
// Add marker clustering
function addClustering() {
// Get the map object
var mapObject = googleMaps.getMap('my-map');
var myMap = googleMaps.getMap('my-map');
// Get map & markers
var map = mapObject._map;
var markers = Object.values(mapObject._markers);
var map = myMap._map;
var markers = Object.values(myMap._markers);
// Cluster markers
new MarkerClusterer(map, markers, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
}
{% endjs %}
{# Specify callback function in map options #}
{% set options = {
id: 'my-map',
callback: 'addClustering',
{# 3. Get all locations to appear on the map #}
{% set locations = craft.entries.section('locations').all() %}
{# 4. Specify the map ID #}
{% set mapOptions = {
'id': 'my-map'
} %}
{# Get locations #}
{% set locations = craft.entries.section('locations').all() %}
{# 5. Specify the JS callback function #}
{% set tagOptions = {
'callback': 'addClustering'
} %}
{# Display the map #}
{{ googleMaps.map(locations, options).tag() }}
{# 6. Display the map #}
{{ googleMaps.map(locations, mapOptions).tag(tagOptions) }}
```

## Instructions

1. First, you must **load the marker clustering library**. The example above points to a CDN, but you could alternatively store a local copy of the library.

2. You then need to **create the JS callback function**. If desired, this function could be stored in a separate `.js` file. Be sure it gets loaded _after_ the plugin loads [the `googlemaps.js` file](/javascript/googlemaps.js/).
2. You then need to **create the JS callback function**. If desired, this function could be stored in a separate `.js` file. Be sure it gets loaded _after_ the plugin loads the [`googlemaps.js` file](/javascript/googlemaps.js/).

3. **Get the locations**, just as you normally would. It's very likely that you already have this part worked out. If not, check out the documentation for [creating a dynamic map...](/dynamic-maps/)

4. **Specify the map's `id`** in the [`map` options](/dynamic-maps/map-management/#map-locations-options). This makes it easy to reference the map in JavaScript.

3. **Specify the `callback` function in the map's [options](/models/dynamic-map-model/#construct-locations-options)**. If you are referencing a named function, simply pass the name of the function. It's also possible to pass an anonymous function (as a string).
5. **Specify the `callback` function** in the [`tag` options](/dynamic-maps/twig-php-methods/#tag-options). If you are referencing a named function, specify the name of the function. Or you can pass an anonymous function (as a _string_ in Twig/PHP).

4. Lastly, you'll want to **get the locations** and **display the map**. It's very likely that you already have this part worked out. If not, check out the documentation for [creating a dynamic map...](/dynamic-maps/)
6. Lastly, **display the map** by providing the `locations`, `mapOptions`, and `tagOptions`.
15 changes: 3 additions & 12 deletions docs/guides/required-js-assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,13 @@ In addition to the Google Maps API reference, there are two [JavaScript files](/

## Disable Automatic Loading

To prevent the required assets from being automatically loaded, simply set the `js` option to `false` when creating a map.
If necessary, you can prevent the required assets from being loaded automatically. When the `tag` method is appended, simply set the `assets` value to `false`.

:::code
```twig
{% set map = googleMaps.map(locations, {
'js': false
}) %}
```
```php
$map = GoogleMaps::map($locations, [
'js' => false
]);
{{ googleMaps.map(locations).tag({'assets': false}) }}
```
:::

For more info, see the complete [list of options...](/dynamic-maps/map-management/#map-locations-options)
For more info, see the complete [list of options...](/dynamic-maps/twig-php-methods/#tag-options)

## Loaded Manually

Expand Down
11 changes: 6 additions & 5 deletions docs/models/dynamic-map-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ Once you have the map object in hand, you can then chain other methods to furthe
| `infoWindowOptions` | _object_ | _null_ | Accepts any [`google.maps.InfoWindowOptions`](https://developers.google.com/maps/documentation/javascript/reference/info-window#InfoWindowOptions) properties.
| `infoWindowTemplate` | _string_ | _null_ | Template path to use for creating [info windows](/dynamic-maps/info-windows/).
| `field` | _string_\|_array_ | _null_ | Address field(s) to be included on the map. (includes all by default)
| `js` | _bool_ | _true_ | Whether to preload the necessary external JavaScript.
| `callback` | _string_ | _null_ | JavaScript function to run after the map has finished loading.

#### Returns

Expand Down Expand Up @@ -352,9 +350,12 @@ Renders the necessary `<div>` container to hold the map. The final `<div>` will

- `$options` (_array_) - Configuration options for the rendered `<div>`.

| Option | Type | Default | Description
|:-------|:------:|:-------:|-------------
| `init` | _bool_ | `true` | Whether to automatically initialize the map via JavaScript.
| Option | Type | Default | Description
|:-----------|:--------:|:-------:|:------------
| `api` | _object_ | `{}` | Optional parameters for the Google Maps API.
| `assets` | _bool_ | `true` | Whether to preload the necessary JavaScript assets.
| `init` | _bool_ | `true` | Whether to automatically initialize the map via JavaScript.
| `callback` | _string_ | `null` | JavaScript function to run after the map has loaded.

By setting the `init` option to `false`, the map will not be automatically initialized in JavaScript. It must therefore be [manually initialized in JavaScript](/dynamic-maps/javascript-methods/#init-mapid-null-callback-null) when the page has completely rendered.

Expand Down
4 changes: 1 addition & 3 deletions docs/updating-from-smart-map/customizing-the-map-in-twig.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ Please take a closer look to see which items will need to be updated, added, or

| Option | | What Changed
|:---------------------|----|:-------------
| `mapOptions` | ⭐ | **ADDED!** (new in the Google Maps plugin)
| `styles` | ⭐ | **ADDED!** (new in the Google Maps plugin)
| `js` | ⭐ | **ADDED!** (new in the Google Maps plugin)
| `callback` | ⭐ | **ADDED!** (new in the Google Maps plugin)
| `mapOptions` | ⭐ | **ADDED!** (new in the Google Maps plugin)
| `maptype` | ❌ | REMOVED (configure via `mapOptions` instead)
| `scale` | ❌ | REMOVED (configure via `mapOptions` instead)
| `scrollwheel` | ❌ | REMOVED (configure via `mapOptions` instead)
Expand Down
54 changes: 30 additions & 24 deletions src/models/DynamicMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use craft\web\View;
use doublesecretagency\googlemaps\fields\AddressField;
use doublesecretagency\googlemaps\GoogleMapsPlugin;
use doublesecretagency\googlemaps\helpers\GoogleMaps;
use doublesecretagency\googlemaps\helpers\MapHelper;
use doublesecretagency\googlemaps\web\assets\JsApiAsset;
use Twig\Error\LoaderError;
Expand Down Expand Up @@ -84,19 +85,9 @@ public function __construct($locations = [], array $options = [], array $config
// Set internal map ID
$this->id = $options['id'];

// Unless otherwise specified, preload the necessary JavaScript
if (!isset($options['js']) || !is_bool($options['js'])) {
$options['js'] = true;
}

// Get view service
$view = Craft::$app->getView();

// Load assets
if ($options['js']) {
$view->registerAssetBundle(JsApiAsset::class);
}

// Whether devMode is enabled
$inDevMode = Craft::$app->getConfig()->general->devMode;

Expand All @@ -119,7 +110,7 @@ public function __construct($locations = [], array $options = [], array $config
];

// Prevent conflict between map ID and marker IDs
unset($options['id'], $options['js']);
unset($options['id']);

// Create markers along with their corresponding info windows
$this->_initInfoWindows($locations, $options);
Expand Down Expand Up @@ -384,33 +375,48 @@ public function tag(array $options = []): Markup
throw new Exception('Model misconfigured. The map DNA is empty.');
}

// Alias map from DNA
$map =& $this->_dna[0];

// If the first item is not a map, throw an error
if ('map' != $map['type']) {
// If the first DNA item is not a map, throw an error
if ('map' != ($this->_dna[0]['type'] ?? false)) {
throw new Exception('Map model misconfigured. The chain must begin with a `map()` segment.');
}

// Compile map container
$html = Html::modifyTagAttributes('<div>Loading map...</div>', [
'id' => $this->id,
'class' => 'gm-map',
'data-dna' => Json::encode($this->_dna),
]);
// Get view service
$view = Craft::$app->getView();

// Unless otherwise specified, preload the necessary JavaScript assets
if (!isset($options['assets']) || !is_bool($options['assets'])) {
$options['assets'] = true;
}

// If no additional API parameters were specified, default to empty array
if (!isset($options['api']) || !is_array($options['api'])) {
$options['api'] = [];
}

// If we're permitted to load JS assets
if ($options['assets']) {
// Load assets with optional API parameters
GoogleMaps::loadAssets($options['api']);
}

// Initialize the map (unless intentionally suppressed)
if ($options['init'] ?? true) {
// Get optional callback
$callback = ($map['options']['callback'] ?? 'null');
$callback = ($options['callback'] ?? 'null');
// Initialize Google Maps after page has loaded
$googleMapsInit = "googleMaps.init('{$this->id}', {$callback})";
$js = "addEventListener('load', function () {{$googleMapsInit}});";
// Register JS at the end of the page
$view = Craft::$app->getView();
$view->registerJs($js, $view::POS_END);
}

// Compile map container
$html = Html::modifyTagAttributes('<div>Loading map...</div>', [
'id' => $this->id,
'class' => 'gm-map',
'data-dna' => Json::encode($this->_dna),
]);

// Return Markup
return Template::raw($html);
}
Expand Down

0 comments on commit 4463d01

Please sign in to comment.