├── .editorconfig ├── .gitignore ├── LICENSE.md ├── README.md ├── composer.json ├── composer.lock ├── config └── config.php ├── lib └── app.php ├── public ├── index.php └── static │ └── main.css └── views ├── index.twig ├── layout.twig ├── movie.twig ├── people.twig └── person.twig /.editorconfig: -------------------------------------------------------------------------------- 1 | ; editorconfig.org 2 | root = true 3 | charset= utf8 4 | 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | indent_style = space 10 | indent_size = 4 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Sanity 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sanity + Silex + Twig example 2 | === 3 | 4 | This is an example [Sanity](https://www.sanity.io/docs) powered frontend for the movies database dataset using [Silex](https://silex.symfony.com) and [Twig](https://twig.symfony.com). 5 | 6 | ## Prerequisites 7 | 8 | You will need [PHP](http://php.net) version 5.6 or later as well as [Composer](https://getcomposer.org) installed on your system 9 | 10 | ## Setup 11 | 12 | Get the code by either cloning this repository using git 13 | 14 | > git clone https://github.com/sanity-io/example-frontend-silex-twig.git 15 | 16 | ... or [downloading source code](https://github.com/sanity-io/example-frontend-silex-twig/archive/master.zip) code as a zip archive. 17 | 18 | Once downloaded, open the terminal in the project directory, and install dependencies with: 19 | 20 | > composer install 21 | 22 | Then start the example app with 23 | 24 | > composer run dev --timeout=0 25 | 26 | The app should now be up and running at http://localhost:3000 27 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "dev": "php -S localhost:3000 -t public/" 4 | }, 5 | "config": { 6 | "platform": { 7 | "php": "5.6.0" 8 | } 9 | }, 10 | "require": { 11 | "twig/twig": "^1.35", 12 | "silex/silex": "^2.2", 13 | "sanity/silex-service-provider": "^1.0", 14 | "symfony/twig-bridge": "^3.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "b9ebdff3fb9a405d110508f4940e84b2", 8 | "packages": [ 9 | { 10 | "name": "guzzlehttp/guzzle", 11 | "version": "6.3.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/guzzle/guzzle.git", 15 | "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", 20 | "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "guzzlehttp/promises": "^1.0", 25 | "guzzlehttp/psr7": "^1.4", 26 | "php": ">=5.5" 27 | }, 28 | "require-dev": { 29 | "ext-curl": "*", 30 | "phpunit/phpunit": "^4.0 || ^5.0", 31 | "psr/log": "^1.0" 32 | }, 33 | "suggest": { 34 | "psr/log": "Required for using the Log middleware" 35 | }, 36 | "type": "library", 37 | "extra": { 38 | "branch-alias": { 39 | "dev-master": "6.2-dev" 40 | } 41 | }, 42 | "autoload": { 43 | "files": [ 44 | "src/functions_include.php" 45 | ], 46 | "psr-4": { 47 | "GuzzleHttp\\": "src/" 48 | } 49 | }, 50 | "notification-url": "https://packagist.org/downloads/", 51 | "license": [ 52 | "MIT" 53 | ], 54 | "authors": [ 55 | { 56 | "name": "Michael Dowling", 57 | "email": "mtdowling@gmail.com", 58 | "homepage": "https://github.com/mtdowling" 59 | } 60 | ], 61 | "description": "Guzzle is a PHP HTTP client library", 62 | "homepage": "http://guzzlephp.org/", 63 | "keywords": [ 64 | "client", 65 | "curl", 66 | "framework", 67 | "http", 68 | "http client", 69 | "rest", 70 | "web service" 71 | ], 72 | "time": "2017-06-22T18:50:49+00:00" 73 | }, 74 | { 75 | "name": "guzzlehttp/promises", 76 | "version": "v1.3.1", 77 | "source": { 78 | "type": "git", 79 | "url": "https://github.com/guzzle/promises.git", 80 | "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" 81 | }, 82 | "dist": { 83 | "type": "zip", 84 | "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", 85 | "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", 86 | "shasum": "" 87 | }, 88 | "require": { 89 | "php": ">=5.5.0" 90 | }, 91 | "require-dev": { 92 | "phpunit/phpunit": "^4.0" 93 | }, 94 | "type": "library", 95 | "extra": { 96 | "branch-alias": { 97 | "dev-master": "1.4-dev" 98 | } 99 | }, 100 | "autoload": { 101 | "psr-4": { 102 | "GuzzleHttp\\Promise\\": "src/" 103 | }, 104 | "files": [ 105 | "src/functions_include.php" 106 | ] 107 | }, 108 | "notification-url": "https://packagist.org/downloads/", 109 | "license": [ 110 | "MIT" 111 | ], 112 | "authors": [ 113 | { 114 | "name": "Michael Dowling", 115 | "email": "mtdowling@gmail.com", 116 | "homepage": "https://github.com/mtdowling" 117 | } 118 | ], 119 | "description": "Guzzle promises library", 120 | "keywords": [ 121 | "promise" 122 | ], 123 | "time": "2016-12-20T10:07:11+00:00" 124 | }, 125 | { 126 | "name": "guzzlehttp/psr7", 127 | "version": "1.4.2", 128 | "source": { 129 | "type": "git", 130 | "url": "https://github.com/guzzle/psr7.git", 131 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" 132 | }, 133 | "dist": { 134 | "type": "zip", 135 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", 136 | "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", 137 | "shasum": "" 138 | }, 139 | "require": { 140 | "php": ">=5.4.0", 141 | "psr/http-message": "~1.0" 142 | }, 143 | "provide": { 144 | "psr/http-message-implementation": "1.0" 145 | }, 146 | "require-dev": { 147 | "phpunit/phpunit": "~4.0" 148 | }, 149 | "type": "library", 150 | "extra": { 151 | "branch-alias": { 152 | "dev-master": "1.4-dev" 153 | } 154 | }, 155 | "autoload": { 156 | "psr-4": { 157 | "GuzzleHttp\\Psr7\\": "src/" 158 | }, 159 | "files": [ 160 | "src/functions_include.php" 161 | ] 162 | }, 163 | "notification-url": "https://packagist.org/downloads/", 164 | "license": [ 165 | "MIT" 166 | ], 167 | "authors": [ 168 | { 169 | "name": "Michael Dowling", 170 | "email": "mtdowling@gmail.com", 171 | "homepage": "https://github.com/mtdowling" 172 | }, 173 | { 174 | "name": "Tobias Schultze", 175 | "homepage": "https://github.com/Tobion" 176 | } 177 | ], 178 | "description": "PSR-7 message implementation that also provides common utility methods", 179 | "keywords": [ 180 | "http", 181 | "message", 182 | "request", 183 | "response", 184 | "stream", 185 | "uri", 186 | "url" 187 | ], 188 | "time": "2017-03-20T17:10:46+00:00" 189 | }, 190 | { 191 | "name": "pimple/pimple", 192 | "version": "v3.2.2", 193 | "source": { 194 | "type": "git", 195 | "url": "https://github.com/silexphp/Pimple.git", 196 | "reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a" 197 | }, 198 | "dist": { 199 | "type": "zip", 200 | "url": "https://api.github.com/repos/silexphp/Pimple/zipball/4d45fb62d96418396ec58ba76e6f065bca16e10a", 201 | "reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a", 202 | "shasum": "" 203 | }, 204 | "require": { 205 | "php": ">=5.3.0", 206 | "psr/container": "^1.0" 207 | }, 208 | "require-dev": { 209 | "symfony/phpunit-bridge": "^3.2" 210 | }, 211 | "type": "library", 212 | "extra": { 213 | "branch-alias": { 214 | "dev-master": "3.2.x-dev" 215 | } 216 | }, 217 | "autoload": { 218 | "psr-0": { 219 | "Pimple": "src/" 220 | } 221 | }, 222 | "notification-url": "https://packagist.org/downloads/", 223 | "license": [ 224 | "MIT" 225 | ], 226 | "authors": [ 227 | { 228 | "name": "Fabien Potencier", 229 | "email": "fabien@symfony.com" 230 | } 231 | ], 232 | "description": "Pimple, a simple Dependency Injection Container", 233 | "homepage": "http://pimple.sensiolabs.org", 234 | "keywords": [ 235 | "container", 236 | "dependency injection" 237 | ], 238 | "time": "2017-07-23T07:32:15+00:00" 239 | }, 240 | { 241 | "name": "psr/container", 242 | "version": "1.0.0", 243 | "source": { 244 | "type": "git", 245 | "url": "https://github.com/php-fig/container.git", 246 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" 247 | }, 248 | "dist": { 249 | "type": "zip", 250 | "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 251 | "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", 252 | "shasum": "" 253 | }, 254 | "require": { 255 | "php": ">=5.3.0" 256 | }, 257 | "type": "library", 258 | "extra": { 259 | "branch-alias": { 260 | "dev-master": "1.0.x-dev" 261 | } 262 | }, 263 | "autoload": { 264 | "psr-4": { 265 | "Psr\\Container\\": "src/" 266 | } 267 | }, 268 | "notification-url": "https://packagist.org/downloads/", 269 | "license": [ 270 | "MIT" 271 | ], 272 | "authors": [ 273 | { 274 | "name": "PHP-FIG", 275 | "homepage": "http://www.php-fig.org/" 276 | } 277 | ], 278 | "description": "Common Container Interface (PHP FIG PSR-11)", 279 | "homepage": "https://github.com/php-fig/container", 280 | "keywords": [ 281 | "PSR-11", 282 | "container", 283 | "container-interface", 284 | "container-interop", 285 | "psr" 286 | ], 287 | "time": "2017-02-14T16:28:37+00:00" 288 | }, 289 | { 290 | "name": "psr/http-message", 291 | "version": "1.0.1", 292 | "source": { 293 | "type": "git", 294 | "url": "https://github.com/php-fig/http-message.git", 295 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 296 | }, 297 | "dist": { 298 | "type": "zip", 299 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 300 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 301 | "shasum": "" 302 | }, 303 | "require": { 304 | "php": ">=5.3.0" 305 | }, 306 | "type": "library", 307 | "extra": { 308 | "branch-alias": { 309 | "dev-master": "1.0.x-dev" 310 | } 311 | }, 312 | "autoload": { 313 | "psr-4": { 314 | "Psr\\Http\\Message\\": "src/" 315 | } 316 | }, 317 | "notification-url": "https://packagist.org/downloads/", 318 | "license": [ 319 | "MIT" 320 | ], 321 | "authors": [ 322 | { 323 | "name": "PHP-FIG", 324 | "homepage": "http://www.php-fig.org/" 325 | } 326 | ], 327 | "description": "Common interface for HTTP messages", 328 | "homepage": "https://github.com/php-fig/http-message", 329 | "keywords": [ 330 | "http", 331 | "http-message", 332 | "psr", 333 | "psr-7", 334 | "request", 335 | "response" 336 | ], 337 | "time": "2016-08-06T14:39:51+00:00" 338 | }, 339 | { 340 | "name": "psr/log", 341 | "version": "1.0.2", 342 | "source": { 343 | "type": "git", 344 | "url": "https://github.com/php-fig/log.git", 345 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 346 | }, 347 | "dist": { 348 | "type": "zip", 349 | "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 350 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 351 | "shasum": "" 352 | }, 353 | "require": { 354 | "php": ">=5.3.0" 355 | }, 356 | "type": "library", 357 | "extra": { 358 | "branch-alias": { 359 | "dev-master": "1.0.x-dev" 360 | } 361 | }, 362 | "autoload": { 363 | "psr-4": { 364 | "Psr\\Log\\": "Psr/Log/" 365 | } 366 | }, 367 | "notification-url": "https://packagist.org/downloads/", 368 | "license": [ 369 | "MIT" 370 | ], 371 | "authors": [ 372 | { 373 | "name": "PHP-FIG", 374 | "homepage": "http://www.php-fig.org/" 375 | } 376 | ], 377 | "description": "Common interface for logging libraries", 378 | "homepage": "https://github.com/php-fig/log", 379 | "keywords": [ 380 | "log", 381 | "psr", 382 | "psr-3" 383 | ], 384 | "time": "2016-10-10T12:19:37+00:00" 385 | }, 386 | { 387 | "name": "sanity/sanity-php", 388 | "version": "v1.1.0", 389 | "source": { 390 | "type": "git", 391 | "url": "https://github.com/sanity-io/sanity-php.git", 392 | "reference": "13237b92d7f4daea08e6bb04bf0f16f1978d2f57" 393 | }, 394 | "dist": { 395 | "type": "zip", 396 | "url": "https://api.github.com/repos/sanity-io/sanity-php/zipball/13237b92d7f4daea08e6bb04bf0f16f1978d2f57", 397 | "reference": "13237b92d7f4daea08e6bb04bf0f16f1978d2f57", 398 | "shasum": "" 399 | }, 400 | "require": { 401 | "guzzlehttp/guzzle": "^6.2" 402 | }, 403 | "require-dev": { 404 | "phpunit/phpunit": "^5.7", 405 | "squizlabs/php_codesniffer": "^2.8" 406 | }, 407 | "type": "library", 408 | "autoload": { 409 | "psr-4": { 410 | "Sanity\\": "lib/", 411 | "SanityTest\\": "test/" 412 | } 413 | }, 414 | "notification-url": "https://packagist.org/downloads/", 415 | "license": [ 416 | "MIT" 417 | ], 418 | "authors": [ 419 | { 420 | "name": "Sanity.io", 421 | "email": "hello@sanity.io" 422 | } 423 | ], 424 | "description": "PHP library for the Sanity API", 425 | "time": "2017-09-11T15:00:17+00:00" 426 | }, 427 | { 428 | "name": "sanity/silex-service-provider", 429 | "version": "v1.0.1", 430 | "source": { 431 | "type": "git", 432 | "url": "https://github.com/sanity-io/silex-service-provider.git", 433 | "reference": "4868db728da4c1cbd3e292bf9fab364aa5faf3c8" 434 | }, 435 | "dist": { 436 | "type": "zip", 437 | "url": "https://api.github.com/repos/sanity-io/silex-service-provider/zipball/4868db728da4c1cbd3e292bf9fab364aa5faf3c8", 438 | "reference": "4868db728da4c1cbd3e292bf9fab364aa5faf3c8", 439 | "shasum": "" 440 | }, 441 | "require": { 442 | "sanity/sanity-php": "^1.0" 443 | }, 444 | "require-dev": { 445 | "phpunit/phpunit": "^5.7", 446 | "silex/silex": "^2.0", 447 | "squizlabs/php_codesniffer": "^2.8" 448 | }, 449 | "type": "library", 450 | "autoload": { 451 | "psr-4": { 452 | "Sanity\\Silex\\": "src/" 453 | } 454 | }, 455 | "notification-url": "https://packagist.org/downloads/", 456 | "license": [ 457 | "MIT" 458 | ], 459 | "authors": [ 460 | { 461 | "name": "Sanity.io", 462 | "email": "hello@sanity.io" 463 | } 464 | ], 465 | "description": "Sanity service provider for Silex", 466 | "time": "2017-11-20T20:33:52+00:00" 467 | }, 468 | { 469 | "name": "silex/silex", 470 | "version": "v2.2.0", 471 | "source": { 472 | "type": "git", 473 | "url": "https://github.com/silexphp/Silex.git", 474 | "reference": "ec7d5b5334465414952d4b2e935e73bd085dbbbb" 475 | }, 476 | "dist": { 477 | "type": "zip", 478 | "url": "https://api.github.com/repos/silexphp/Silex/zipball/ec7d5b5334465414952d4b2e935e73bd085dbbbb", 479 | "reference": "ec7d5b5334465414952d4b2e935e73bd085dbbbb", 480 | "shasum": "" 481 | }, 482 | "require": { 483 | "php": ">=5.5.9", 484 | "pimple/pimple": "~3.0", 485 | "symfony/event-dispatcher": "~2.8|^3.0", 486 | "symfony/http-foundation": "~2.8|^3.0", 487 | "symfony/http-kernel": "~2.8|^3.0", 488 | "symfony/routing": "~2.8|^3.0" 489 | }, 490 | "conflict": { 491 | "phpunit/phpunit": "<4.8.35 || >= 5.0, <5.4.3" 492 | }, 493 | "replace": { 494 | "silex/api": "self.version", 495 | "silex/providers": "self.version" 496 | }, 497 | "require-dev": { 498 | "doctrine/dbal": "~2.2", 499 | "monolog/monolog": "^1.4.1", 500 | "swiftmailer/swiftmailer": "~5", 501 | "symfony/asset": "~2.8|^3.0", 502 | "symfony/browser-kit": "~2.8|^3.0", 503 | "symfony/config": "~2.8|^3.0", 504 | "symfony/css-selector": "~2.8|^3.0", 505 | "symfony/debug": "~2.8|^3.0", 506 | "symfony/doctrine-bridge": "~2.8|^3.0", 507 | "symfony/dom-crawler": "~2.8|^3.0", 508 | "symfony/expression-language": "~2.8|^3.0", 509 | "symfony/finder": "~2.8|^3.0", 510 | "symfony/form": "~2.8|^3.0", 511 | "symfony/intl": "~2.8|^3.0", 512 | "symfony/monolog-bridge": "~2.8|^3.0", 513 | "symfony/options-resolver": "~2.8|^3.0", 514 | "symfony/phpunit-bridge": "^3.2", 515 | "symfony/process": "~2.8|^3.0", 516 | "symfony/security": "~2.8|^3.0", 517 | "symfony/serializer": "~2.8|^3.0", 518 | "symfony/translation": "~2.8|^3.0", 519 | "symfony/twig-bridge": "~2.8|^3.0", 520 | "symfony/validator": "~2.8|^3.0", 521 | "symfony/var-dumper": "~2.8|^3.0", 522 | "symfony/web-link": "^3.3", 523 | "twig/twig": "~1.28|~2.0" 524 | }, 525 | "type": "library", 526 | "extra": { 527 | "branch-alias": { 528 | "dev-master": "2.2.x-dev" 529 | } 530 | }, 531 | "autoload": { 532 | "psr-4": { 533 | "Silex\\": "src/Silex" 534 | } 535 | }, 536 | "notification-url": "https://packagist.org/downloads/", 537 | "license": [ 538 | "MIT" 539 | ], 540 | "authors": [ 541 | { 542 | "name": "Fabien Potencier", 543 | "email": "fabien@symfony.com" 544 | }, 545 | { 546 | "name": "Igor Wiedler", 547 | "email": "igor@wiedler.ch" 548 | } 549 | ], 550 | "description": "The PHP micro-framework based on the Symfony Components", 551 | "homepage": "http://silex.sensiolabs.org", 552 | "keywords": [ 553 | "microframework" 554 | ], 555 | "time": "2017-07-23T07:40:14+00:00" 556 | }, 557 | { 558 | "name": "symfony/debug", 559 | "version": "v3.3.13", 560 | "source": { 561 | "type": "git", 562 | "url": "https://github.com/symfony/debug.git", 563 | "reference": "74557880e2846b5c84029faa96b834da37e29810" 564 | }, 565 | "dist": { 566 | "type": "zip", 567 | "url": "https://api.github.com/repos/symfony/debug/zipball/74557880e2846b5c84029faa96b834da37e29810", 568 | "reference": "74557880e2846b5c84029faa96b834da37e29810", 569 | "shasum": "" 570 | }, 571 | "require": { 572 | "php": "^5.5.9|>=7.0.8", 573 | "psr/log": "~1.0" 574 | }, 575 | "conflict": { 576 | "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" 577 | }, 578 | "require-dev": { 579 | "symfony/http-kernel": "~2.8|~3.0" 580 | }, 581 | "type": "library", 582 | "extra": { 583 | "branch-alias": { 584 | "dev-master": "3.3-dev" 585 | } 586 | }, 587 | "autoload": { 588 | "psr-4": { 589 | "Symfony\\Component\\Debug\\": "" 590 | }, 591 | "exclude-from-classmap": [ 592 | "/Tests/" 593 | ] 594 | }, 595 | "notification-url": "https://packagist.org/downloads/", 596 | "license": [ 597 | "MIT" 598 | ], 599 | "authors": [ 600 | { 601 | "name": "Fabien Potencier", 602 | "email": "fabien@symfony.com" 603 | }, 604 | { 605 | "name": "Symfony Community", 606 | "homepage": "https://symfony.com/contributors" 607 | } 608 | ], 609 | "description": "Symfony Debug Component", 610 | "homepage": "https://symfony.com", 611 | "time": "2017-11-10T16:38:39+00:00" 612 | }, 613 | { 614 | "name": "symfony/event-dispatcher", 615 | "version": "v3.3.13", 616 | "source": { 617 | "type": "git", 618 | "url": "https://github.com/symfony/event-dispatcher.git", 619 | "reference": "271d8c27c3ec5ecee6e2ac06016232e249d638d9" 620 | }, 621 | "dist": { 622 | "type": "zip", 623 | "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/271d8c27c3ec5ecee6e2ac06016232e249d638d9", 624 | "reference": "271d8c27c3ec5ecee6e2ac06016232e249d638d9", 625 | "shasum": "" 626 | }, 627 | "require": { 628 | "php": "^5.5.9|>=7.0.8" 629 | }, 630 | "conflict": { 631 | "symfony/dependency-injection": "<3.3" 632 | }, 633 | "require-dev": { 634 | "psr/log": "~1.0", 635 | "symfony/config": "~2.8|~3.0", 636 | "symfony/dependency-injection": "~3.3", 637 | "symfony/expression-language": "~2.8|~3.0", 638 | "symfony/stopwatch": "~2.8|~3.0" 639 | }, 640 | "suggest": { 641 | "symfony/dependency-injection": "", 642 | "symfony/http-kernel": "" 643 | }, 644 | "type": "library", 645 | "extra": { 646 | "branch-alias": { 647 | "dev-master": "3.3-dev" 648 | } 649 | }, 650 | "autoload": { 651 | "psr-4": { 652 | "Symfony\\Component\\EventDispatcher\\": "" 653 | }, 654 | "exclude-from-classmap": [ 655 | "/Tests/" 656 | ] 657 | }, 658 | "notification-url": "https://packagist.org/downloads/", 659 | "license": [ 660 | "MIT" 661 | ], 662 | "authors": [ 663 | { 664 | "name": "Fabien Potencier", 665 | "email": "fabien@symfony.com" 666 | }, 667 | { 668 | "name": "Symfony Community", 669 | "homepage": "https://symfony.com/contributors" 670 | } 671 | ], 672 | "description": "Symfony EventDispatcher Component", 673 | "homepage": "https://symfony.com", 674 | "time": "2017-11-05T15:47:03+00:00" 675 | }, 676 | { 677 | "name": "symfony/http-foundation", 678 | "version": "v3.3.13", 679 | "source": { 680 | "type": "git", 681 | "url": "https://github.com/symfony/http-foundation.git", 682 | "reference": "5943f0f19817a7e05992d20a90729b0dc93faf36" 683 | }, 684 | "dist": { 685 | "type": "zip", 686 | "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5943f0f19817a7e05992d20a90729b0dc93faf36", 687 | "reference": "5943f0f19817a7e05992d20a90729b0dc93faf36", 688 | "shasum": "" 689 | }, 690 | "require": { 691 | "php": "^5.5.9|>=7.0.8", 692 | "symfony/polyfill-mbstring": "~1.1" 693 | }, 694 | "require-dev": { 695 | "symfony/expression-language": "~2.8|~3.0" 696 | }, 697 | "type": "library", 698 | "extra": { 699 | "branch-alias": { 700 | "dev-master": "3.3-dev" 701 | } 702 | }, 703 | "autoload": { 704 | "psr-4": { 705 | "Symfony\\Component\\HttpFoundation\\": "" 706 | }, 707 | "exclude-from-classmap": [ 708 | "/Tests/" 709 | ] 710 | }, 711 | "notification-url": "https://packagist.org/downloads/", 712 | "license": [ 713 | "MIT" 714 | ], 715 | "authors": [ 716 | { 717 | "name": "Fabien Potencier", 718 | "email": "fabien@symfony.com" 719 | }, 720 | { 721 | "name": "Symfony Community", 722 | "homepage": "https://symfony.com/contributors" 723 | } 724 | ], 725 | "description": "Symfony HttpFoundation Component", 726 | "homepage": "https://symfony.com", 727 | "time": "2017-11-13T18:13:16+00:00" 728 | }, 729 | { 730 | "name": "symfony/http-kernel", 731 | "version": "v3.3.13", 732 | "source": { 733 | "type": "git", 734 | "url": "https://github.com/symfony/http-kernel.git", 735 | "reference": "a2a942172b742217ab2ccd9399494af2aa17c766" 736 | }, 737 | "dist": { 738 | "type": "zip", 739 | "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a2a942172b742217ab2ccd9399494af2aa17c766", 740 | "reference": "a2a942172b742217ab2ccd9399494af2aa17c766", 741 | "shasum": "" 742 | }, 743 | "require": { 744 | "php": "^5.5.9|>=7.0.8", 745 | "psr/log": "~1.0", 746 | "symfony/debug": "~2.8|~3.0", 747 | "symfony/event-dispatcher": "~2.8|~3.0", 748 | "symfony/http-foundation": "^3.3.11" 749 | }, 750 | "conflict": { 751 | "symfony/config": "<2.8", 752 | "symfony/dependency-injection": "<3.3", 753 | "symfony/var-dumper": "<3.3", 754 | "twig/twig": "<1.34|<2.4,>=2" 755 | }, 756 | "require-dev": { 757 | "psr/cache": "~1.0", 758 | "symfony/browser-kit": "~2.8|~3.0", 759 | "symfony/class-loader": "~2.8|~3.0", 760 | "symfony/config": "~2.8|~3.0", 761 | "symfony/console": "~2.8|~3.0", 762 | "symfony/css-selector": "~2.8|~3.0", 763 | "symfony/dependency-injection": "~3.3", 764 | "symfony/dom-crawler": "~2.8|~3.0", 765 | "symfony/expression-language": "~2.8|~3.0", 766 | "symfony/finder": "~2.8|~3.0", 767 | "symfony/process": "~2.8|~3.0", 768 | "symfony/routing": "~2.8|~3.0", 769 | "symfony/stopwatch": "~2.8|~3.0", 770 | "symfony/templating": "~2.8|~3.0", 771 | "symfony/translation": "~2.8|~3.0", 772 | "symfony/var-dumper": "~3.3" 773 | }, 774 | "suggest": { 775 | "symfony/browser-kit": "", 776 | "symfony/class-loader": "", 777 | "symfony/config": "", 778 | "symfony/console": "", 779 | "symfony/dependency-injection": "", 780 | "symfony/finder": "", 781 | "symfony/var-dumper": "" 782 | }, 783 | "type": "library", 784 | "extra": { 785 | "branch-alias": { 786 | "dev-master": "3.3-dev" 787 | } 788 | }, 789 | "autoload": { 790 | "psr-4": { 791 | "Symfony\\Component\\HttpKernel\\": "" 792 | }, 793 | "exclude-from-classmap": [ 794 | "/Tests/" 795 | ] 796 | }, 797 | "notification-url": "https://packagist.org/downloads/", 798 | "license": [ 799 | "MIT" 800 | ], 801 | "authors": [ 802 | { 803 | "name": "Fabien Potencier", 804 | "email": "fabien@symfony.com" 805 | }, 806 | { 807 | "name": "Symfony Community", 808 | "homepage": "https://symfony.com/contributors" 809 | } 810 | ], 811 | "description": "Symfony HttpKernel Component", 812 | "homepage": "https://symfony.com", 813 | "time": "2017-11-16T18:14:43+00:00" 814 | }, 815 | { 816 | "name": "symfony/polyfill-mbstring", 817 | "version": "v1.6.0", 818 | "source": { 819 | "type": "git", 820 | "url": "https://github.com/symfony/polyfill-mbstring.git", 821 | "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296" 822 | }, 823 | "dist": { 824 | "type": "zip", 825 | "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296", 826 | "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296", 827 | "shasum": "" 828 | }, 829 | "require": { 830 | "php": ">=5.3.3" 831 | }, 832 | "suggest": { 833 | "ext-mbstring": "For best performance" 834 | }, 835 | "type": "library", 836 | "extra": { 837 | "branch-alias": { 838 | "dev-master": "1.6-dev" 839 | } 840 | }, 841 | "autoload": { 842 | "psr-4": { 843 | "Symfony\\Polyfill\\Mbstring\\": "" 844 | }, 845 | "files": [ 846 | "bootstrap.php" 847 | ] 848 | }, 849 | "notification-url": "https://packagist.org/downloads/", 850 | "license": [ 851 | "MIT" 852 | ], 853 | "authors": [ 854 | { 855 | "name": "Nicolas Grekas", 856 | "email": "p@tchwork.com" 857 | }, 858 | { 859 | "name": "Symfony Community", 860 | "homepage": "https://symfony.com/contributors" 861 | } 862 | ], 863 | "description": "Symfony polyfill for the Mbstring extension", 864 | "homepage": "https://symfony.com", 865 | "keywords": [ 866 | "compatibility", 867 | "mbstring", 868 | "polyfill", 869 | "portable", 870 | "shim" 871 | ], 872 | "time": "2017-10-11T12:05:26+00:00" 873 | }, 874 | { 875 | "name": "symfony/routing", 876 | "version": "v3.3.13", 877 | "source": { 878 | "type": "git", 879 | "url": "https://github.com/symfony/routing.git", 880 | "reference": "cf7fa1dfcfee2c96969bfa1c0341e5627ecb1e95" 881 | }, 882 | "dist": { 883 | "type": "zip", 884 | "url": "https://api.github.com/repos/symfony/routing/zipball/cf7fa1dfcfee2c96969bfa1c0341e5627ecb1e95", 885 | "reference": "cf7fa1dfcfee2c96969bfa1c0341e5627ecb1e95", 886 | "shasum": "" 887 | }, 888 | "require": { 889 | "php": "^5.5.9|>=7.0.8" 890 | }, 891 | "conflict": { 892 | "symfony/config": "<2.8", 893 | "symfony/dependency-injection": "<3.3", 894 | "symfony/yaml": "<3.3" 895 | }, 896 | "require-dev": { 897 | "doctrine/annotations": "~1.0", 898 | "doctrine/common": "~2.2", 899 | "psr/log": "~1.0", 900 | "symfony/config": "~2.8|~3.0", 901 | "symfony/dependency-injection": "~3.3", 902 | "symfony/expression-language": "~2.8|~3.0", 903 | "symfony/http-foundation": "~2.8|~3.0", 904 | "symfony/yaml": "~3.3" 905 | }, 906 | "suggest": { 907 | "doctrine/annotations": "For using the annotation loader", 908 | "symfony/config": "For using the all-in-one router or any loader", 909 | "symfony/dependency-injection": "For loading routes from a service", 910 | "symfony/expression-language": "For using expression matching", 911 | "symfony/http-foundation": "For using a Symfony Request object", 912 | "symfony/yaml": "For using the YAML loader" 913 | }, 914 | "type": "library", 915 | "extra": { 916 | "branch-alias": { 917 | "dev-master": "3.3-dev" 918 | } 919 | }, 920 | "autoload": { 921 | "psr-4": { 922 | "Symfony\\Component\\Routing\\": "" 923 | }, 924 | "exclude-from-classmap": [ 925 | "/Tests/" 926 | ] 927 | }, 928 | "notification-url": "https://packagist.org/downloads/", 929 | "license": [ 930 | "MIT" 931 | ], 932 | "authors": [ 933 | { 934 | "name": "Fabien Potencier", 935 | "email": "fabien@symfony.com" 936 | }, 937 | { 938 | "name": "Symfony Community", 939 | "homepage": "https://symfony.com/contributors" 940 | } 941 | ], 942 | "description": "Symfony Routing Component", 943 | "homepage": "https://symfony.com", 944 | "keywords": [ 945 | "router", 946 | "routing", 947 | "uri", 948 | "url" 949 | ], 950 | "time": "2017-11-07T14:16:22+00:00" 951 | }, 952 | { 953 | "name": "symfony/twig-bridge", 954 | "version": "v3.3.13", 955 | "source": { 956 | "type": "git", 957 | "url": "https://github.com/symfony/twig-bridge.git", 958 | "reference": "87305530dee22d66c92756df2d4aec576d882fb9" 959 | }, 960 | "dist": { 961 | "type": "zip", 962 | "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/87305530dee22d66c92756df2d4aec576d882fb9", 963 | "reference": "87305530dee22d66c92756df2d4aec576d882fb9", 964 | "shasum": "" 965 | }, 966 | "require": { 967 | "php": "^5.5.9|>=7.0.8", 968 | "twig/twig": "~1.34|~2.4" 969 | }, 970 | "conflict": { 971 | "symfony/form": "<3.2.10|~3.3,<3.3.3" 972 | }, 973 | "require-dev": { 974 | "fig/link-util": "^1.0", 975 | "symfony/asset": "~2.8|~3.0", 976 | "symfony/console": "~2.8|~3.0", 977 | "symfony/expression-language": "~2.8|~3.0", 978 | "symfony/finder": "~2.8|~3.0", 979 | "symfony/form": "^3.2.10|^3.3.3", 980 | "symfony/http-foundation": "^3.3.11", 981 | "symfony/http-kernel": "~3.2", 982 | "symfony/polyfill-intl-icu": "~1.0", 983 | "symfony/routing": "~2.8|~3.0", 984 | "symfony/security": "~2.8|~3.0", 985 | "symfony/security-acl": "~2.8|~3.0", 986 | "symfony/stopwatch": "~2.8|~3.0", 987 | "symfony/templating": "~2.8|~3.0", 988 | "symfony/translation": "~2.8|~3.0", 989 | "symfony/var-dumper": "~2.8.10|~3.1.4|~3.2", 990 | "symfony/web-link": "~3.3", 991 | "symfony/yaml": "~2.8|~3.0" 992 | }, 993 | "suggest": { 994 | "symfony/asset": "For using the AssetExtension", 995 | "symfony/expression-language": "For using the ExpressionExtension", 996 | "symfony/finder": "", 997 | "symfony/form": "For using the FormExtension", 998 | "symfony/http-kernel": "For using the HttpKernelExtension", 999 | "symfony/routing": "For using the RoutingExtension", 1000 | "symfony/security": "For using the SecurityExtension", 1001 | "symfony/stopwatch": "For using the StopwatchExtension", 1002 | "symfony/templating": "For using the TwigEngine", 1003 | "symfony/translation": "For using the TranslationExtension", 1004 | "symfony/var-dumper": "For using the DumpExtension", 1005 | "symfony/web-link": "For using the WebLinkExtension", 1006 | "symfony/yaml": "For using the YamlExtension" 1007 | }, 1008 | "type": "symfony-bridge", 1009 | "extra": { 1010 | "branch-alias": { 1011 | "dev-master": "3.3-dev" 1012 | } 1013 | }, 1014 | "autoload": { 1015 | "psr-4": { 1016 | "Symfony\\Bridge\\Twig\\": "" 1017 | }, 1018 | "exclude-from-classmap": [ 1019 | "/Tests/" 1020 | ] 1021 | }, 1022 | "notification-url": "https://packagist.org/downloads/", 1023 | "license": [ 1024 | "MIT" 1025 | ], 1026 | "authors": [ 1027 | { 1028 | "name": "Fabien Potencier", 1029 | "email": "fabien@symfony.com" 1030 | }, 1031 | { 1032 | "name": "Symfony Community", 1033 | "homepage": "https://symfony.com/contributors" 1034 | } 1035 | ], 1036 | "description": "Symfony Twig Bridge", 1037 | "homepage": "https://symfony.com", 1038 | "time": "2017-11-07T11:58:40+00:00" 1039 | }, 1040 | { 1041 | "name": "twig/twig", 1042 | "version": "v1.35.0", 1043 | "source": { 1044 | "type": "git", 1045 | "url": "https://github.com/twigphp/Twig.git", 1046 | "reference": "daa657073e55b0a78cce8fdd22682fddecc6385f" 1047 | }, 1048 | "dist": { 1049 | "type": "zip", 1050 | "url": "https://api.github.com/repos/twigphp/Twig/zipball/daa657073e55b0a78cce8fdd22682fddecc6385f", 1051 | "reference": "daa657073e55b0a78cce8fdd22682fddecc6385f", 1052 | "shasum": "" 1053 | }, 1054 | "require": { 1055 | "php": ">=5.3.3" 1056 | }, 1057 | "require-dev": { 1058 | "psr/container": "^1.0", 1059 | "symfony/debug": "~2.7", 1060 | "symfony/phpunit-bridge": "~3.3@dev" 1061 | }, 1062 | "type": "library", 1063 | "extra": { 1064 | "branch-alias": { 1065 | "dev-master": "1.35-dev" 1066 | } 1067 | }, 1068 | "autoload": { 1069 | "psr-0": { 1070 | "Twig_": "lib/" 1071 | }, 1072 | "psr-4": { 1073 | "Twig\\": "src/" 1074 | } 1075 | }, 1076 | "notification-url": "https://packagist.org/downloads/", 1077 | "license": [ 1078 | "BSD-3-Clause" 1079 | ], 1080 | "authors": [ 1081 | { 1082 | "name": "Fabien Potencier", 1083 | "email": "fabien@symfony.com", 1084 | "homepage": "http://fabien.potencier.org", 1085 | "role": "Lead Developer" 1086 | }, 1087 | { 1088 | "name": "Armin Ronacher", 1089 | "email": "armin.ronacher@active-4.com", 1090 | "role": "Project Founder" 1091 | }, 1092 | { 1093 | "name": "Twig Team", 1094 | "homepage": "http://twig.sensiolabs.org/contributors", 1095 | "role": "Contributors" 1096 | } 1097 | ], 1098 | "description": "Twig, the flexible, fast, and secure template language for PHP", 1099 | "homepage": "http://twig.sensiolabs.org", 1100 | "keywords": [ 1101 | "templating" 1102 | ], 1103 | "time": "2017-09-27T18:06:46+00:00" 1104 | } 1105 | ], 1106 | "packages-dev": [], 1107 | "aliases": [], 1108 | "minimum-stability": "stable", 1109 | "stability-flags": [], 1110 | "prefer-stable": false, 1111 | "prefer-lowest": false, 1112 | "platform": [], 1113 | "platform-dev": [], 1114 | "platform-overrides": { 1115 | "php": "5.6.0" 1116 | } 1117 | } 1118 | -------------------------------------------------------------------------------- /config/config.php: -------------------------------------------------------------------------------- 1 | [ 4 | 'projectId' => 'zp7mbokg', 5 | 'dataset' => 'production', 6 | 'useCdn' => true 7 | // useCdn == true gives fast, cheap responses using a globally distributed cache. 8 | // Set this to false if your application require the freshest possible data always 9 | // (potentially slightly slower and a bit more expensive). 10 | ], 11 | ]; 12 | -------------------------------------------------------------------------------- /lib/app.php: -------------------------------------------------------------------------------- 1 | register(new Silex\Provider\TwigServiceProvider(), [ 9 | 'twig.path' => __DIR__ . '/../views', 10 | ]); 11 | $app->register(new Sanity\Silex\ServiceProvider(), [ 12 | 'sanity.client.options' => $app['config']['sanity'] 13 | ]); 14 | 15 | // Front page (movies list) 16 | $app->get('/', function (Silex\Application $app) { 17 | $query = ' 18 | *[_type == "movie"] { 19 | _id, 20 | title, 21 | releaseDate, 22 | 23 | "director": crewMembers[job == "Director"][0].person->name, 24 | "posterUrl": poster.asset->url 25 | }[0...50]'; 26 | 27 | $movies = $app['sanity.client']->fetch($query); 28 | return $app['twig']->render('index.twig', ['movies' => $movies]); 29 | })->bind('movies'); 30 | 31 | // Movie page 32 | $app->get('/movie/{id}', function (Silex\Application $app, $id) { 33 | $query = ' 34 | *[_type == "movie" && _id == $id] { 35 | _id, 36 | title, 37 | releaseDate, 38 | "posterUrl": poster.asset->url, 39 | "cast": castMembers[] { 40 | characterName, 41 | "person": person-> { 42 | _id, 43 | name, 44 | "imageUrl": image.asset->url 45 | } 46 | } 47 | }[0]'; 48 | 49 | $movie = $app['sanity.client']->fetch($query, ['id' => $id]); 50 | return $app['twig']->render('movie.twig', $movie); 51 | })->bind('movie'); 52 | 53 | // People page 54 | $app->get('/people', function (Silex\Application $app) { 55 | $query = ' 56 | *[_type == "person"] { 57 | _id, 58 | name, 59 | "imageUrl": image.asset->url 60 | }[0...50]'; 61 | 62 | $people = $app['sanity.client']->fetch($query); 63 | return $app['twig']->render('people.twig', ['people' => $people]); 64 | })->bind('people'); 65 | 66 | // Person page 67 | $app->get('/person/{id}', function (Silex\Application $app, $id) { 68 | $query = ' 69 | *[_type == "person" && _id == $id] { 70 | _id, 71 | name, 72 | "imageUrl": image.asset->url, 73 | "actedIn": *[_type == "movie" && references(^._id)] { 74 | _id, 75 | title, 76 | releaseDate, 77 | "posterUrl": post.asset->url 78 | } 79 | }[0] 80 | '; 81 | 82 | $person = $app['sanity.client']->fetch($query, ['id' => $id]); 83 | return $app['twig']->render('person.twig', $person); 84 | })->bind('person'); 85 | 86 | $app->run(); 87 | -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | li { 44 | display: block; 45 | margin: 0; 46 | padding: 0; 47 | border-bottom: 1px solid #ccc; 48 | display: flex; 49 | align-items: stretch; 50 | } 51 | 52 | .list a { 53 | text-decoration: none; 54 | display: block; 55 | flex-grow: 1; 56 | color: #333; 57 | padding: 0.5rem; 58 | } 59 | 60 | .list a:hover { 61 | background-color: #eee; 62 | } 63 | 64 | .list a:active { 65 | color: white; 66 | background-color: black; 67 | } 68 | 69 | .list h3 { 70 | margin: 0; 71 | padding: 0; 72 | } 73 | 74 | .list img { 75 | display: block; 76 | height: auto; 77 | width: 3em; 78 | margin-right: 0.5rem; 79 | float: left; 80 | } 81 | 82 | .movies-list__directed-by { 83 | display: block; 84 | font-size: 1rem; 85 | } 86 | 87 | .movie > h2 { 88 | margin: 2rem 0 0 0; 89 | padding: 0 0.5rem; 90 | border-bottom: 1px solid #ccc; 91 | } 92 | 93 | .movie .list img { 94 | width: 2rem; 95 | height: 2rem; 96 | margin-right: 0.5rem; 97 | object-fit: cover; 98 | } 99 | 100 | .movie__header { 101 | clear: both; 102 | overflow: hidden; 103 | padding: 0.5rem; 104 | } 105 | 106 | .movie__header > h1 { 107 | font-size: 3rem; 108 | line-height: 1em; 109 | margin: 1rem 0 0 0; 110 | padding: 0; 111 | } 112 | 113 | .movie__header > img { 114 | display: block; 115 | width: 33vw; 116 | max-width: 20rem; 117 | height: auto; 118 | float: left; 119 | margin-right: 0.5rem; 120 | } 121 | 122 | .movie .list { 123 | line-height: 2rem; 124 | } 125 | 126 | .person > h2 { 127 | margin: 2rem 0 0 0; 128 | padding: 0 0.5rem; 129 | border-bottom: 1px solid #ccc; 130 | } 131 | 132 | .person .list img { 133 | width: 2rem; 134 | height: 2rem; 135 | margin-right: 0.5rem; 136 | object-fit: cover; 137 | } 138 | 139 | .person .list { 140 | line-height: 2rem; 141 | } 142 | 143 | .person__header { 144 | clear: both; 145 | overflow: hidden; 146 | padding: 0.5rem; 147 | } 148 | 149 | .person__header > h1 { 150 | font-size: 3rem; 151 | line-height: 1em; 152 | margin: 1rem 0 0 0; 153 | padding: 0; 154 | } 155 | 156 | .person__header > img { 157 | display: block; 158 | width: 33vw; 159 | max-width: 20rem; 160 | height: auto; 161 | float: left; 162 | margin-right: 0.5rem; 163 | } 164 | -------------------------------------------------------------------------------- /views/index.twig: -------------------------------------------------------------------------------- 1 | {% extends 'layout.twig' %} 2 | 3 | {% block content %} 4 |
Directed by {{ movie.director ?? '