Skip to content

Add Leaflet.js package #39

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ build amazing User Experiences as quickly as we can now setup
File input drag-and-drop zones for Symfony Forms
- [UX LazyImage](https://github.com/symfony/ux-lazy-image):
Improve image loading performances through lazy-loading and data-uri thumbnails
- [UX Leaflet.js](https://github.com/symfony/ux-leafletjs):
[Leaflet](https://leafletjs.com/) map library integration for Symfony
- [UX Swup](https://github.com/symfony/ux-swup):
[Swup](https://swup.js.org/) page transition library integration for Symfony

Expand Down
5 changes: 5 additions & 0 deletions src/Leafletjs/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/.gitattributes export-ignore
/.gitignore export-ignore
/phpunit.xml.dist export-ignore
/assets/test export-ignore
/tests export-ignore
4 changes: 4 additions & 0 deletions src/Leafletjs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/vendor/
.phpunit.result.cache
.php_cs.cache
composer.lock
29 changes: 29 additions & 0 deletions src/Leafletjs/Builder/LeafletBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\Leafletjs\Builder;

use Symfony\UX\Leafletjs\Model\Map;

/**
* @author Titouan Galopin <galopintitouan@gmail.com>
* @author Michael Cramer <michael@bigmichi1.de>
*
* @final
* @experimental
*/
class LeafletBuilder implements LeafletBuilderInterface
{
public function createMap(float $lon, float $lat, int $zoom = 10): Map
{
return new Map($lon, $lat, $zoom);
}
}
25 changes: 25 additions & 0 deletions src/Leafletjs/Builder/LeafletBuilderInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\Leafletjs\Builder;

use Symfony\UX\Leafletjs\Model\Map;

/**
* @author Titouan Galopin <galopintitouan@gmail.com>
* @author Michael Cramer <michael@bigmichi1.de>
*
* @experimental
*/
interface LeafletBuilderInterface
{
public function createMap(float $lon, float $lat, int $zoom = 10): Map;
}
50 changes: 50 additions & 0 deletions src/Leafletjs/DependencyInjection/LeafletjsExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\Leafletjs\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\UX\Leafletjs\Builder\LeafletBuilder;
use Symfony\UX\Leafletjs\Builder\LeafletBuilderInterface;
use Symfony\UX\Leafletjs\Twig\LeafletExtension;
use Twig\Environment;

/**
* @author Titouan Galopin <galopintitouan@gmail.com>
* @author Michael Cramer <michael@bigmichi1.de>
*
* @internal
*/
class LeafletjsExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$container
->setDefinition('leafletjs.builder', new Definition(LeafletBuilder::class))
->setPublic(false)
;

$container
->setAlias(LeafletBuilderInterface::class, 'leafletjs.builder')
->setPublic(false)
;

if (class_exists(Environment::class)) {
$container
->setDefinition('leafletjs.twig_extension', new Definition(LeafletExtension::class))
->addTag('twig.extension')
->setPublic(false)
;
}
}
}
25 changes: 25 additions & 0 deletions src/Leafletjs/LeafletjsBundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\Leafletjs;

use Symfony\Component\HttpKernel\Bundle\Bundle;

/**
* @author Titouan Galopin <galopintitouan@gmail.com>
* @author Michael Cramer <michael@bigmichi1.de>
*
* @final
* @experimental
*/
class LeafletjsBundle extends Bundle
{
}
75 changes: 75 additions & 0 deletions src/Leafletjs/Model/Map.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\Leafletjs\Model;

/**
* @author Titouan Galopin <galopintitouan@gmail.com>
* @author Michael Cramer <michael@bigmichi1.de>
*
* @final
* @experimental
*/
class Map
{
private $mapOptions = [];
private $attributes = [];
private $lon;
private $lat;
private $zoom;

public function __construct(float $lon, float $lat, int $zoom)
{
$this->lon = $lon;
$this->lat = $lat;
$this->zoom = $zoom;
}

public function setMapOptions(array $mapOptions): void
{
$this->mapOptions = $mapOptions;
}

public function setAttributes(array $attributes): void
{
$this->attributes = $attributes;
}

public function getDataController(): ?string
{
return $this->attributes['data-controller'] ?? null;
}

public function getMapOptions(): array
{
return $this->mapOptions;
}

public function getAttributes(): array
{
return $this->attributes;
}

public function getLon(): float
{
return $this->lon;
}

public function getLat(): float
{
return $this->lat;
}

public function getZoom(): int
{
return $this->zoom;
}
}
120 changes: 120 additions & 0 deletions src/Leafletjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Symfony UX Leaflet.js

Symfony UX Leaflet.js is a Symfony bundle integrating the [Leaflet](https://leafletjs.com/)
library in Symfony applications. It is part of [the Symfony UX initiative](https://symfony.com/ux).

## Installation

Symfony UX Leaflet requires PHP 7.2+ and Symfony 4.4+.

Install this bundle using Composer and Symfony Flex:

```sh
composer require symfony/ux-leafletjs

# Don't forget to install the JavaScript dependencies as well and compile
yarn install --force
yarn encore dev
```

## Usage

To use Symfony UX Leaflet.js, inject the `LeafletBuilderInterface` service and
create maps in PHP:

```php
// ...
use Symfony\UX\Leafletjs\Builder\LeafletBuilderInterface;
use Symfony\UX\Leafletjs\Model\Map;

class HomeController extends AbstractController
{
/**
* @Route("/", name="homepage")
*/
public function index(LeafletBuilderInterface $mapBuilder): Response
{
$map = $mapBuilder->createMap(51.505, -0.09, 13);
$map->setMapOptions(['minZoom' => 1, 'maxZoom' => 8]);

return $this->render('home/index.html.twig', [
'map' => $map,
]);
}
}
```

Map options are provided as-is to Leaflet. You can read
[Leaflet documentation](https://leafletjs.com/reference-1.7.1.html#map-factory) to discover them all.

Once created in PHP, a map can be displayed using Twig:

```twig
{{ render_map(map) }}

{# You can pass HTML attributes as a second argument to add them on the <div> tag #}
{{ render_map(map, {'class': 'my-map'}) }}
```

### Extend the default behavior

Symfony UX Leaflet.js allows you to extend its default behavior using a custom Stimulus controller:

```js
// mymap_controller.js

import { Controller } from 'stimulus';

export default class extends Controller {
connect() {
this.element.addEventListener('leafletjs:connect', this._onConnect);
}

disconnect() {
// You should always remove listeners when the controller is disconnected to avoid side effects
this.element.removeEventListener('leafletjs:connect', this._onConnect);
}

_onConnect(event) {
// The map was just created
console.log(event.detail.map); // You can access the map instance using the event details
console.log(event.detail.layer); // You can access the default layer instance using the event details

// For instance you can add additional markers to the map
new LLMarker([lat, lon]).addTo(event.detail.map);

// Changing the default URL for the default layer
event.detail.layer.setUrl('http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png');
}
}
```

Then in your render call, add your controller as an HTML attribute:

```twig
{{ render_map(map, {'data-controller': 'mymap'}) }}
```

## Backward Compatibility promise

This bundle aims at following the same Backward Compatibility promise as the Symfony framework:
[https://symfony.com/doc/current/contributing/code/bc.html](https://symfony.com/doc/current/contributing/code/bc.html)

However it is currently considered
[**experimental**](https://symfony.com/doc/current/contributing/code/experimental.html),
meaning it is not bound to Symfony's BC policy for the moment.

## Run tests

### PHP tests

```sh
php vendor/bin/phpunit
```

### JavaScript tests

```sh
cd Resources/assets
yarn test
```
4 changes: 4 additions & 0 deletions src/Leafletjs/Resources/assets/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": ["@babel/env"],
"plugins": ["@babel/plugin-proposal-class-properties"]
}
Loading