├── .gitignore ├── Makefile ├── README.md ├── lib └── index.js ├── package.json └── test ├── fixtures ├── basic │ ├── build │ │ └── index.html │ ├── expected │ │ └── index.html │ ├── src │ │ └── index.html │ └── templates │ │ └── index.hbt ├── collection-invalid │ ├── src │ │ └── jobOffer.html │ └── templates │ │ └── jobOffer.hbt ├── collection-linkResolver │ ├── build │ │ ├── job-offer │ │ │ ├── art-director.html │ │ │ ├── community-manager.html │ │ │ ├── content-director.html │ │ │ ├── fruit-expert.html │ │ │ ├── ganache-specialist.html │ │ │ ├── oven-instrumentist.html │ │ │ ├── pastry-dresser.html │ │ │ ├── store-assistant-manager.html │ │ │ └── store-intern.html │ │ └── product │ │ │ ├── black-white-macaron │ │ │ ├── cool-coconut-macaron │ │ │ ├── dark-chocolate-macaron │ │ │ ├── pistachio-macaron │ │ │ ├── salted-caramel-macaron │ │ │ ├── speculoos-macaron │ │ │ └── vanilla-macaron │ ├── expected │ │ ├── job-offer │ │ │ ├── art-director.html │ │ │ ├── community-manager.html │ │ │ ├── content-director.html │ │ │ ├── fruit-expert.html │ │ │ ├── ganache-specialist.html │ │ │ ├── oven-instrumentist.html │ │ │ ├── pastry-dresser.html │ │ │ ├── store-assistant-manager.html │ │ │ └── store-intern.html │ │ └── product │ │ │ ├── black-white-macaron │ │ │ ├── cool-coconut-macaron │ │ │ ├── dark-chocolate-macaron │ │ │ ├── pistachio-macaron │ │ │ ├── salted-caramel-macaron │ │ │ ├── speculoos-macaron │ │ │ └── vanilla-macaron │ ├── src │ │ ├── jobOffer.html │ │ └── macaron.html │ └── templates │ │ ├── jobOffer.hbt │ │ └── macaron.hbt ├── collection │ ├── build │ │ ├── job-offer │ │ │ ├── UlfoxUnM0wkXYXbQ │ │ │ │ └── fruit-expert.html │ │ │ ├── UlfoxUnM0wkXYXbR │ │ │ │ └── store-assistant-manager.html │ │ │ ├── UlfoxUnM0wkXYXbV │ │ │ │ └── art-director.html │ │ │ ├── UlfoxUnM0wkXYXbW │ │ │ │ └── content-director.html │ │ │ ├── UlfoxUnM0wkXYXbY │ │ │ │ └── community-manager.html │ │ │ ├── UlfoxUnM0wkXYXba │ │ │ │ └── ganache-specialist.html │ │ │ ├── UlfoxUnM0wkXYXbh │ │ │ │ └── pastry-dresser.html │ │ │ ├── UlfoxUnM0wkXYXbn │ │ │ │ └── oven-instrumentist.html │ │ │ └── UlfoxUnM0wkXYXbs │ │ │ │ └── store-intern.html │ │ └── product │ │ │ ├── UlfoxUnM0wkXYXbD │ │ │ └── speculoos-macaron │ │ │ ├── UlfoxUnM0wkXYXbE │ │ │ └── dark-chocolate-macaron │ │ │ ├── UlfoxUnM0wkXYXbH │ │ │ └── vanilla-macaron │ │ │ ├── UlfoxUnM0wkXYXbJ │ │ │ └── pistachio-macaron │ │ │ ├── UlfoxUnM0wkXYXbM │ │ │ └── salted-caramel-macaron │ │ │ └── UlfoxUnM0wkXYXbg │ │ │ ├── black-white-macaron │ │ │ └── cool-coconut-macaron │ ├── expected │ │ ├── job-offer │ │ │ ├── UlfoxUnM0wkXYXbQ │ │ │ │ └── fruit-expert.html │ │ │ ├── UlfoxUnM0wkXYXbR │ │ │ │ └── store-assistant-manager.html │ │ │ ├── UlfoxUnM0wkXYXbV │ │ │ │ └── art-director.html │ │ │ ├── UlfoxUnM0wkXYXbW │ │ │ │ └── content-director.html │ │ │ ├── UlfoxUnM0wkXYXbY │ │ │ │ └── community-manager.html │ │ │ ├── UlfoxUnM0wkXYXba │ │ │ │ └── ganache-specialist.html │ │ │ ├── UlfoxUnM0wkXYXbh │ │ │ │ └── pastry-dresser.html │ │ │ ├── UlfoxUnM0wkXYXbn │ │ │ │ └── oven-instrumentist.html │ │ │ └── UlfoxUnM0wkXYXbs │ │ │ │ └── store-intern.html │ │ └── product │ │ │ ├── UlfoxUnM0wkXYXbD │ │ │ └── speculoos-macaron │ │ │ ├── UlfoxUnM0wkXYXbE │ │ │ └── dark-chocolate-macaron │ │ │ ├── UlfoxUnM0wkXYXbH │ │ │ └── vanilla-macaron │ │ │ ├── UlfoxUnM0wkXYXbJ │ │ │ └── pistachio-macaron │ │ │ ├── UlfoxUnM0wkXYXbM │ │ │ └── salted-caramel-macaron │ │ │ └── UlfoxUnM0wkXYXbg │ │ │ ├── black-white-macaron │ │ │ └── cool-coconut-macaron │ ├── src │ │ ├── jobOffer.html │ │ └── macaron.html │ └── templates │ │ ├── jobOffer.hbt │ │ └── macaron.hbt ├── linkResolver │ ├── build │ │ └── index.html │ ├── expected │ │ └── index.html │ ├── src │ │ └── index.html │ └── templates │ │ └── index.hbt └── pageSize │ ├── build │ └── index.html │ ├── expected │ └── index.html │ ├── src │ └── index.html │ └── templates │ └── index.hbt ├── index.js └── index.js.save /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | node_modules: package.json 2 | @npm install 3 | 4 | test: node_modules 5 | @./node_modules/.bin/mocha --reporter spec 6 | 7 | .PHONY: test 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # metalsmith-s3 2 | Metalsmith plugin for reading/writing/copying files on AWS S3. 3 | 4 | Example usage: [nonLinear.zone build process](https://github.com/mwishek/nonlinear.build). 5 | 6 | # Installation 7 | ``` 8 | $ npm install metalsmith-s3 9 | ``` 10 | 11 | # Usage 12 | ```node 13 | var Metalsmith = require('metalsmith'); 14 | var s3 = require('metalsmith-s3'); 15 | 16 | var metalsmith = new Metalsmith(__dirname) 17 | .use(s3({ 18 | action: 'copy', 19 | bucket: 's3-bucket-dest', 20 | from: 's3-bucket-src', 21 | prefix: ['images/', 'js/'] 22 | })); 23 | .use(s3({ 24 | action: 'read', 25 | bucket: 's3-bucket-src', 26 | ignore: ['images/', 'js/'] 27 | })); 28 | ... 29 | .use(s3({ 30 | action: 'write', 31 | bucket: 's3-bucket-dest' 32 | })); 33 | ``` 34 | ### S3 Library Pass Through 35 | You can pass through additional settings directly to the s3 library by adding an `s3` key and hash. 36 | Properties available vary based on the chosen action: 37 | - [read](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property) 38 | - [copy](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#copyObject-property) 39 | - [write](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putObject-property) 40 | 41 | Example to set the ACL for files written to s3: 42 | ```node 43 | var Metalsmith = require('metalsmith'); 44 | var s3 = require('metalsmith-s3'); 45 | 46 | var metalsmith = new Metalsmith(__dirname) 47 | ... 48 | .use(s3({ 49 | action: 'write', 50 | bucket: 's3-bucket-dest' 51 | s3: { 52 | ACL: 'public-read' 53 | } 54 | })); 55 | ``` 56 | 57 | If file metadata has an `s3` key, it is mixed in as well. 58 | That allows overriding properties on a per-file basis. 59 | 60 | Example setting ACL for specific file in front-matter: 61 | ```md 62 | --- 63 | title: My Article 64 | s3: 65 | ACL: private 66 | --- 67 | ``` 68 | 69 | ### Region Override 70 | In case you face the following error, just add the optional parameter *region* : 71 | ``` TypeError: Error: PermanentRedirect: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.``` 72 | 73 | Applicable regions are listed in [aws documentation](http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region). 74 | Usage example: 75 | ``` javascript 76 | .use(s3({ 77 | action: 'write', 78 | bucket: 's3-bucket-dest', 79 | region: 'eu-west-1' 80 | })); 81 | ``` 82 | 83 | # Actions 84 | ### Read 85 | 86 | The _read_ action will read files from an S3 bucket which can then be processed by plugins later in the chain. The _read_ action can be modified to ignore certain prefixes in the S3 bucket be setting the _ignore_ to a prefix, or an array of prefixes. 87 | 88 | #### Read Parameters: 89 | 90 | bucket: source S3 bucket 91 | ignore: a prefix or array of prefixes _not_ to be read from the source S3 bucket 92 | region: bucket's endpoint region (optional) 93 | 94 | ### Copy 95 | 96 | The _copy_ action will copy files from a source S3 bucket to a destination S3 bucket. The _copy_ action must include a _prefix_ parameter to specifiy one or more prefixes to be processed. 97 | 98 | #### Copy Parameters 99 | 100 | bucket: destination S3 bucket 101 | from: source S3 bucket 102 | prefix: a prefix or array of prefixes to be copied from the source S3 bucket 103 | region: bucket's endpoint region (optional) 104 | 105 | ### Write 106 | 107 | The _write_ action will write all files to the destination S3 bucket. 108 | 109 | #### Write Parameters 110 | 111 | bucket: destination S3 bucket 112 | region: bucket's endpoint region (optional) 113 | 114 | #### Mime Types 115 | 116 | Uploaded file's mime type will be set by: 117 | 118 | * `mimeType` property in the file's meta, if set 119 | * type determined by [mime-type](https://www.npmjs.com/package/mime-types)'s inspection of the file name 120 | * undefined (interpreted as `application/octet-stream` by S3) 121 | 122 | # Credentials configuration 123 | 124 | ### Via environment variables 125 | ``` 126 | export AWS_ACCESS_KEY_ID='your_access_key' 127 | export AWS_SECRET_ACCESS_KEY='your_secret_key' 128 | ``` 129 | 130 | ### Via configuration file 131 | 132 | Create a credentials file at `~/.aws/credentials` on Mac/Linux or `C:\Users\USERNAME\.aws\credentials` on Windows 133 | 134 | ``` 135 | [default] 136 | aws_access_key_id = your_access_key 137 | aws_secret_access_key = your_secret_key 138 | ``` 139 | 140 | # TODO 141 | 1. Test suite 142 | 143 | #License 144 | 145 | The MIT License (MIT) 146 | 147 | Copyright © 2015, Matthew Wishek <[mwishek@gmail.com](mailto:mwishek@gmail.com)> 148 | 149 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 150 | 151 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 152 | 153 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 154 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var debug = require('debug')('metalsmith-s3'); 4 | var _ = require('underscore'); 5 | var front = require('front-matter'); 6 | var AWS = require('aws-sdk'); 7 | var mime = require('mime-types'); 8 | var async = require('async'); 9 | 10 | /** 11 | * Expose `plugin`. 12 | */ 13 | 14 | module.exports = plugin; 15 | 16 | /** 17 | * Metalsmith plugin to read/write/copy content using Amazon S3. 18 | * 19 | * @param {Object} options 20 | * @property {String} bucket 21 | * @property {String} action 22 | * @return {Function} 23 | */ 24 | 25 | function plugin(config) { 26 | 27 | checkProperty(config, 'bucket'); 28 | checkProperty(config, 'action'); 29 | 30 | return function(files, metalsmith, done) { 31 | var param = {}; 32 | if (typeof config.s3 !== 'undefined'){ 33 | param = config.s3; 34 | } 35 | // initialize the API 36 | var s3; 37 | if(config.region){ 38 | s3 = new AWS.S3({ 39 | region: config.region 40 | }); 41 | }else{ 42 | s3 = new AWS.S3(); 43 | } 44 | 45 | switch(config['action']) { 46 | case 'copy' : 47 | CopyS3Objects(); 48 | break; 49 | case 'read' : 50 | ReadS3Objects(); 51 | break; 52 | case 'write' : 53 | WriteS3Objects(); 54 | break; 55 | default : 56 | throw new TypeError('Unknown action ' + config['action'] + '. Please update your configuration'); 57 | done(); 58 | } 59 | 60 | function CopyS3Objects() { 61 | 62 | checkProperty(config, 'from'); 63 | checkProperty(config, 'prefix'); 64 | 65 | var filteritems = []; 66 | var patternitems = {}; 67 | 68 | patternitems.prefix = '^'; 69 | patternitems.suffix = '.*(?=[^\/]$)'; 70 | patternitems.match = true; 71 | 72 | param.Bucket = config['bucket']; 73 | 74 | if (!Array.isArray(config['prefix'])) { 75 | filteritems = [config['prefix']]; 76 | } else { 77 | filteritems = config['prefix']; 78 | } 79 | 80 | async.waterfall([ 81 | function(next) { 82 | s3.listObjects(param, next); 83 | }, 84 | function(response, next) { 85 | filterList(response, filteritems, patternitems, next); 86 | }, 87 | function(response, next) { 88 | copyList(response, next); 89 | } 90 | ], 91 | function(err, res) { 92 | result(err, res); 93 | } 94 | ); 95 | } 96 | 97 | function ReadS3Objects() { 98 | 99 | checkProperty(config, 'ignore'); 100 | 101 | var filteritems = []; 102 | var patternitems = {}; 103 | 104 | patternitems.prefix = '(^'; 105 | patternitems.suffix = '.*|.*\/$)'; 106 | patternitems.match = false; 107 | 108 | param.Bucket = config['bucket']; 109 | 110 | if (!Array.isArray(config['ignore'])) { 111 | filteritems = [config['ignore']]; 112 | } else { 113 | filteritems = config['ignore']; 114 | } 115 | 116 | async.waterfall([ 117 | function(next) { 118 | s3.listObjects(param, next); 119 | }, 120 | function(response, next) { 121 | filterList(response, filteritems, patternitems, next); 122 | }, 123 | function(response, next) { 124 | readList(response, next); 125 | } 126 | ], 127 | function(err, res) { 128 | result(err, res); 129 | } 130 | ); 131 | } 132 | 133 | function WriteS3Objects() { 134 | 135 | param.Bucket = config['bucket']; 136 | 137 | async.waterfall([ 138 | function(next) { 139 | writeList(param, next); 140 | } 141 | ], 142 | function(err, res) { 143 | result(err, res); 144 | } 145 | ); 146 | 147 | } 148 | 149 | function filterList(response, filteritems, patternitems, next) { 150 | var contents = response.Contents; 151 | contents = _.filter(contents, function(obj) { 152 | if (filteritems.some(function(item) { 153 | var regx = new RegExp(patternitems.prefix + item + patternitems.suffix); 154 | return regx.test(obj['Key']); 155 | })) { 156 | debug("filtering: " + obj['Key']); 157 | return patternitems.match; 158 | } 159 | return !patternitems.match; 160 | }); 161 | next(null, contents); 162 | } 163 | 164 | function copyList(list, next) { 165 | async.each(list, function(obj, callback) { 166 | param.Key = obj.Key 167 | param.CopySource = config['from'] + "/" + param.Key; 168 | param.ContentType = mime.lookup(param.Key); 169 | s3.copyObject(param, function(err, res) { 170 | callback(err); 171 | }); 172 | debug("copying file: ", param.CopySource, " to ", param.Bucket); 173 | }, function(err) { 174 | next(err, 'S3 copy operation complete'); 175 | }); 176 | } 177 | 178 | function readList(list, next) { 179 | async.each(list, function(obj, callback) { 180 | param.Key = obj.Key 181 | s3.getObject(param).on('success', function(response) { 182 | var path = response.request.httpRequest.path; 183 | var spath = "/".concat(response.request.params.Bucket).concat("/"); 184 | var data = response.data; 185 | var parsed = front(data.Body.toString()); 186 | var file = {}; 187 | 188 | path = path.replace(spath, ''); 189 | 190 | file = parsed.attributes; 191 | file.contents = new Buffer(parsed.body); 192 | files[path] = file; 193 | debug("adding file: ", path); 194 | callback(); 195 | }).send(); 196 | }, function(err) { 197 | next(err, 'read from S3 done'); 198 | }); 199 | } 200 | 201 | function writeList(param, next) { 202 | async.each(Object.keys(files), function(file, callback) { 203 | var putParams = Object.assign({}, param, files[file].s3); 204 | putParams.Key = file; 205 | putParams.Body = files[file].contents; 206 | putParams.ContentType = ( 207 | files[file].mimeType || 208 | mime.lookup(file) || 209 | undefined 210 | ) 211 | debug("writing file: ", file, "with contentType = ", putParams.ContentType); 212 | s3.putObject(putParams, callback); 213 | }, function(err) { 214 | next(err, 'write to S3 done'); 215 | }); 216 | } 217 | 218 | function result(err, res) { 219 | if (err) { 220 | throw new TypeError('Error: ' + err); 221 | } 222 | debug(res); 223 | done(); 224 | } 225 | } 226 | 227 | function checkProperty(object, property) { 228 | if ((object[property]) == null) { 229 | throw new TypeError('Missing property \'' + property + '\'. Please update the configuration settings appropriately.'); 230 | } 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metalsmith-s3", 3 | "version": "0.1.0", 4 | "description": "A Metalsmith.io plugin to integrate with AWS S3", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/mwishek/metalsmith-s3" 12 | }, 13 | "keywords": [ 14 | "package", 15 | "Metalsmith.io", 16 | "S3", 17 | "Amazon", 18 | "AWS" 19 | ], 20 | "author": "Matthew Wishek", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/mwishek/metalsmith-s3/issues" 24 | }, 25 | "homepage": "https://github.com/mwishek/metalsmith-s3", 26 | "dependencies": { 27 | "async": "^0.9.0", 28 | "aws-sdk": "^2.1.7", 29 | "debug": "^1.0.4", 30 | "front-matter": "^0.2.1", 31 | "mime": "^1.2.11", 32 | "mime-types": "^2.0.7", 33 | "underscore": "^1.6.0" 34 | }, 35 | "devDependencies": { 36 | "assert-dir-equal": "0.0.1", 37 | "handlebars": "^2.0.0-alpha.4", 38 | "metalsmith": "^0.9.0", 39 | "metalsmith-templates": "^0.5.2", 40 | "mocha": "^1.21.3" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/fixtures/basic/build/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mwishek/metalsmith-s3/f3228f9aec12215ce4ef3a3de03559a14724d52f/test/fixtures/basic/build/index.html -------------------------------------------------------------------------------- /test/fixtures/basic/expected/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 33 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /test/fixtures/basic/src/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | template: index.hbt 3 | prismic: 4 | macaron: 5 | query: '[[:d = at(document.tags, ["Macaron"])] [:d = any(document.type, ["product"])]]' 6 | orderings: '[my.product.name]' 7 | jobOffers: 8 | query: '[[:d = any(document.type, ["job-offer"])]]' 9 | --- 10 | -------------------------------------------------------------------------------- /test/fixtures/basic/templates/index.hbt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /test/fixtures/collection-invalid/src/jobOffer.html: -------------------------------------------------------------------------------- 1 | --- 2 | template: jobOffer.hbt 3 | prismic: 4 | jobOffer: 5 | query: '[[:d = any(document.type, ["job-offer"])]]' 6 | collection: 7 | fileExtension: 'html' 8 | macaron: 9 | query: '[[:d = at(document.tags, ["Macaron"])] [:d = any(document.type, ["product"])]]' 10 | collection: true 11 | --- 12 | -------------------------------------------------------------------------------- /test/fixtures/collection-invalid/templates/jobOffer.hbt: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{{prismic.jobOffer.results.[0].data.name.html}}} 4 | {{{prismic.jobOffer.results.[0].data.profile.html}}} 5 | {{{prismic.jobOffer.results.[0].data.description.html}}} 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/art-director.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Art Director

4 |

Brand visual identity must be vital to you, and you must have a thorough experience with working for/with great visual brands. We will ask you to present your previous work, and explain your choices, so be prepared. Previous work with luxury brands is a plus.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/community-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Community Manager

4 |

Mastering the art of direct communication is an experimented skill by itself; and mastering the ability to adapt to the ever-changing modern communication environment is another one. As our community manager, you will need to be proficient with both.

You will also need to have experience in both aspects, and it's much better if you have worked for/with luxury brands before (not necessarily food-related).

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/content-director.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Content Director

4 |

As a company whose marketing is very content-centric, we expect our Content Director to have a tremendous experience, both in content strategy, and in content writing. We expect our applicants to show off some of the content strategies they set up themselves, explaining their choices, and to provide amazing contents they personally wrote.

Our contents get flexibly powerfully shared on various supports: our site, our in-store printed magazine, our mobile apps, our mailings ... Our Content Director must have experience with all of those, and with using modern adaptive content managers such as prismic.io.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/fruit-expert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Fruit Expert

4 |

Here at Les Bonnes Choses, we acknowledge that it's a talent to know how to turn fresh material by nature, such as fruit, into something that plays well with the other pastry ingredients. Fruit are natural and temperamental, so you need to know exactly how to tame them and convice them to behave as per your will.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/ganache-specialist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Ganache Specialist

4 |

It takes a solid whipping and crystalizing experience to build perfect ganaches. Ganaches can be built from the top down (building a hard material, and softening it), or from the bottom up (coming from a near-liquid state, and making it thicker), and only you know just the way to go to get the perfect output.

Experienced and highly motivated in fine pastry, you are able to come up with better techniques and formulas to make your art always better.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/oven-instrumentist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Oven Instrumentist

4 |

A musical instrument does nothing by itself; a musical instrumentalist is but a person. But together, they play an art that is bigger than the sum of the man and the instrument, and generate powerful emotions. It takes a lot of technique; but it takes a lot more than technique. We only ask you one thing: that you do have that technique, and that extra thing.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/pastry-dresser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Pastry Dresser

4 |

If you are the kind of person who gets intense, insane, almost neurotic about perfection and details, you are exactly the type we're looking for; but be aware that this job will not make your condition better! With an art background and a perfect mastery of the finest paintbrushes, you can modify every bit of an object to make it shine even brighter.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/store-assistant-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Store Assistant Manager

4 |

To be straightforward: as a Store Assistant Manager, your skills will be as strong as the Store Manager, meaning you can manage your teams, balance the books, give any kind of advice to your customers, ... simply run the store! You need to have extensive experience with pastry (or at least, fine cuisine), and to be customer-service-driven.

The Store Manager is usually a more seasoned Les Bonnes Choses leader, who already had the time to adapt his leadership style to the Les Bonnes Choses approach.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/job-offer/store-intern.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Store Intern

4 |

We expect only one skill from our store interns: an infinite thirst to learn about fine pastry. You might not know much about how to prepare them. You might not know much about how to sell them, and advise about them. You might not know how a pastry shop runs. We've got all of that covered for you.

Be sure to have the proper motivation, and your future with us will shine bright: we've been offering jobs to all of our interns at the end of their internship.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/product/black-white-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Black & White Macaron

4 |

If you feel like antique, experimented tastes are the way to go, then this macaron is perfect for you! A solid touch of dark chocolate, enveloped by a softening touch of vanilla, will take the best of both familiar world, to carry you to a brand new experience! Because you know Les Bonnes Choses always finds out just how to renew your classics for you...

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/product/cool-coconut-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Cool Coconut Macaron

4 |

If you ever met coconut taste on its bad day, you surely know that coconut, coming from bad-tempered islands, can be rough sometimes. That is why we like to soften it with a touch of caramel taste in its ganache. The result is the perfect encounter between the finest palm fruit and the most tasty of sugarcane's offspring.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/product/dark-chocolate-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Dark Chocolate Macaron

4 |

There is so much rich, decadent chocolate in this macaron that the chocolatey pleasure is just endless!

As you let the softness and the strength of our preciously selected cocoa waken your senses, you will feel a lot of pleasure and a little bit of guilt, for giving in to your dark (chocolate) side again!

There's no mistery why our Dark Chocolate Macaron is our longest-running pastry, in our whole collection, since our creation in 1992.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/product/pistachio-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Pistachio Macaron

4 |

If you are a nut-cuisine-savvy gourmet, you probably noticed that industrial pistachio flavour tastes very different than actual pistachio.

And yet, pistachio nuts shelter a pure, delicate taste, that needs preserving as much as possible, until it lands in your hands. Therefore, as you bite into our pistachio macaron, you will feel the pistachio nut bits not only delicately set on top of the macaron, but also inside the ganache itself.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/product/salted-caramel-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Salted Caramel Macaron

4 |

It's no wonder why our "Salted Caramel French Macaron" has become our best-selling macaron: on top of the authentic Parisian preparation that has been making our macarons so popular and enjoyed by gourmets, you can also feel the waves of Britanny's ocean as you bite into it. Two of the best French local gastronomies meet in your mouth, and suddenly, it's like French Revolution all over again, contained in a single macaron.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/product/speculoos-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Speculoos Macaron

4 |

Did you know that World War I warriors on the French-Belgian frontier called an unauthorized truce in December 1914, so they could celebrate Christmas together? That's because in every situation, there's much joy to create and receive, from the natural friendship between the French and the Belgian cultures! So when Belgian speculoos meets French macarons, you get to experience the natural chemistry of cultures that are meant to work perfectly together...

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/build/product/vanilla-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Vanilla Macaron

4 |

Experience the ultimate vanilla experience. Our vanilla Macarons are made with our very own (in-house) pure extract of Madagascar vanilla, and subtly dusted with our own vanilla sugar (which we make from real vanilla beans).

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/art-director.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Art Director

4 |

Brand visual identity must be vital to you, and you must have a thorough experience with working for/with great visual brands. We will ask you to present your previous work, and explain your choices, so be prepared. Previous work with luxury brands is a plus.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/community-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Community Manager

4 |

Mastering the art of direct communication is an experimented skill by itself; and mastering the ability to adapt to the ever-changing modern communication environment is another one. As our community manager, you will need to be proficient with both.

You will also need to have experience in both aspects, and it's much better if you have worked for/with luxury brands before (not necessarily food-related).

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/content-director.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Content Director

4 |

As a company whose marketing is very content-centric, we expect our Content Director to have a tremendous experience, both in content strategy, and in content writing. We expect our applicants to show off some of the content strategies they set up themselves, explaining their choices, and to provide amazing contents they personally wrote.

Our contents get flexibly powerfully shared on various supports: our site, our in-store printed magazine, our mobile apps, our mailings ... Our Content Director must have experience with all of those, and with using modern adaptive content managers such as prismic.io.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/fruit-expert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Fruit Expert

4 |

Here at Les Bonnes Choses, we acknowledge that it's a talent to know how to turn fresh material by nature, such as fruit, into something that plays well with the other pastry ingredients. Fruit are natural and temperamental, so you need to know exactly how to tame them and convice them to behave as per your will.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/ganache-specialist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Ganache Specialist

4 |

It takes a solid whipping and crystalizing experience to build perfect ganaches. Ganaches can be built from the top down (building a hard material, and softening it), or from the bottom up (coming from a near-liquid state, and making it thicker), and only you know just the way to go to get the perfect output.

Experienced and highly motivated in fine pastry, you are able to come up with better techniques and formulas to make your art always better.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/oven-instrumentist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Oven Instrumentist

4 |

A musical instrument does nothing by itself; a musical instrumentalist is but a person. But together, they play an art that is bigger than the sum of the man and the instrument, and generate powerful emotions. It takes a lot of technique; but it takes a lot more than technique. We only ask you one thing: that you do have that technique, and that extra thing.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/pastry-dresser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Pastry Dresser

4 |

If you are the kind of person who gets intense, insane, almost neurotic about perfection and details, you are exactly the type we're looking for; but be aware that this job will not make your condition better! With an art background and a perfect mastery of the finest paintbrushes, you can modify every bit of an object to make it shine even brighter.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/store-assistant-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Store Assistant Manager

4 |

To be straightforward: as a Store Assistant Manager, your skills will be as strong as the Store Manager, meaning you can manage your teams, balance the books, give any kind of advice to your customers, ... simply run the store! You need to have extensive experience with pastry (or at least, fine cuisine), and to be customer-service-driven.

The Store Manager is usually a more seasoned Les Bonnes Choses leader, who already had the time to adapt his leadership style to the Les Bonnes Choses approach.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/job-offer/store-intern.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Store Intern

4 |

We expect only one skill from our store interns: an infinite thirst to learn about fine pastry. You might not know much about how to prepare them. You might not know much about how to sell them, and advise about them. You might not know how a pastry shop runs. We've got all of that covered for you.

Be sure to have the proper motivation, and your future with us will shine bright: we've been offering jobs to all of our interns at the end of their internship.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/product/black-white-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Black & White Macaron

4 |

If you feel like antique, experimented tastes are the way to go, then this macaron is perfect for you! A solid touch of dark chocolate, enveloped by a softening touch of vanilla, will take the best of both familiar world, to carry you to a brand new experience! Because you know Les Bonnes Choses always finds out just how to renew your classics for you...

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/product/cool-coconut-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Cool Coconut Macaron

4 |

If you ever met coconut taste on its bad day, you surely know that coconut, coming from bad-tempered islands, can be rough sometimes. That is why we like to soften it with a touch of caramel taste in its ganache. The result is the perfect encounter between the finest palm fruit and the most tasty of sugarcane's offspring.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/product/dark-chocolate-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Dark Chocolate Macaron

4 |

There is so much rich, decadent chocolate in this macaron that the chocolatey pleasure is just endless!

As you let the softness and the strength of our preciously selected cocoa waken your senses, you will feel a lot of pleasure and a little bit of guilt, for giving in to your dark (chocolate) side again!

There's no mistery why our Dark Chocolate Macaron is our longest-running pastry, in our whole collection, since our creation in 1992.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/product/pistachio-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Pistachio Macaron

4 |

If you are a nut-cuisine-savvy gourmet, you probably noticed that industrial pistachio flavour tastes very different than actual pistachio.

And yet, pistachio nuts shelter a pure, delicate taste, that needs preserving as much as possible, until it lands in your hands. Therefore, as you bite into our pistachio macaron, you will feel the pistachio nut bits not only delicately set on top of the macaron, but also inside the ganache itself.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/product/salted-caramel-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Salted Caramel Macaron

4 |

It's no wonder why our "Salted Caramel French Macaron" has become our best-selling macaron: on top of the authentic Parisian preparation that has been making our macarons so popular and enjoyed by gourmets, you can also feel the waves of Britanny's ocean as you bite into it. Two of the best French local gastronomies meet in your mouth, and suddenly, it's like French Revolution all over again, contained in a single macaron.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/product/speculoos-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Speculoos Macaron

4 |

Did you know that World War I warriors on the French-Belgian frontier called an unauthorized truce in December 1914, so they could celebrate Christmas together? That's because in every situation, there's much joy to create and receive, from the natural friendship between the French and the Belgian cultures! So when Belgian speculoos meets French macarons, you get to experience the natural chemistry of cultures that are meant to work perfectly together...

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/expected/product/vanilla-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Vanilla Macaron

4 |

Experience the ultimate vanilla experience. Our vanilla Macarons are made with our very own (in-house) pure extract of Madagascar vanilla, and subtly dusted with our own vanilla sugar (which we make from real vanilla beans).

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/src/jobOffer.html: -------------------------------------------------------------------------------- 1 | --- 2 | template: jobOffer.hbt 3 | prismic: 4 | jobOffer: 5 | query: '[[:d = any(document.type, ["job-offer"])]]' 6 | collection: 7 | fileExtension: 'html' 8 | macaron: 9 | query: '[[:d = at(document.tags, ["Macaron"])] [:d = any(document.type, ["product"])]]' 10 | --- 11 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/src/macaron.html: -------------------------------------------------------------------------------- 1 | --- 2 | template: macaron.hbt 3 | prismic: 4 | macaron: 5 | query: '[[:d = at(document.tags, ["Macaron"])] [:d = any(document.type, ["product"])]]' 6 | collection: true 7 | --- 8 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/templates/jobOffer.hbt: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{{prismic.jobOffer.results.[0].data.name.html}}} 4 | {{{prismic.jobOffer.results.[0].data.profile.html}}} 5 | {{{prismic.jobOffer.results.[0].data.description.html}}} 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/fixtures/collection-linkResolver/templates/macaron.hbt: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{{prismic.macaron.results.[0].data.name.html}}} 4 | {{{prismic.macaron.results.[0].data.description.html}}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXbQ/fruit-expert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Fruit Expert

4 |

Here at Les Bonnes Choses, we acknowledge that it's a talent to know how to turn fresh material by nature, such as fruit, into something that plays well with the other pastry ingredients. Fruit are natural and temperamental, so you need to know exactly how to tame them and convice them to behave as per your will.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXbR/store-assistant-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Store Assistant Manager

4 |

To be straightforward: as a Store Assistant Manager, your skills will be as strong as the Store Manager, meaning you can manage your teams, balance the books, give any kind of advice to your customers, ... simply run the store! You need to have extensive experience with pastry (or at least, fine cuisine), and to be customer-service-driven.

The Store Manager is usually a more seasoned Les Bonnes Choses leader, who already had the time to adapt his leadership style to the Les Bonnes Choses approach.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXbV/art-director.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Art Director

4 |

Brand visual identity must be vital to you, and you must have a thorough experience with working for/with great visual brands. We will ask you to present your previous work, and explain your choices, so be prepared. Previous work with luxury brands is a plus.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXbW/content-director.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Content Director

4 |

As a company whose marketing is very content-centric, we expect our Content Director to have a tremendous experience, both in content strategy, and in content writing. We expect our applicants to show off some of the content strategies they set up themselves, explaining their choices, and to provide amazing contents they personally wrote.

Our contents get flexibly powerfully shared on various supports: our site, our in-store printed magazine, our mobile apps, our mailings ... Our Content Director must have experience with all of those, and with using modern adaptive content managers such as prismic.io.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXbY/community-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Community Manager

4 |

Mastering the art of direct communication is an experimented skill by itself; and mastering the ability to adapt to the ever-changing modern communication environment is another one. As our community manager, you will need to be proficient with both.

You will also need to have experience in both aspects, and it's much better if you have worked for/with luxury brands before (not necessarily food-related).

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXba/ganache-specialist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Ganache Specialist

4 |

It takes a solid whipping and crystalizing experience to build perfect ganaches. Ganaches can be built from the top down (building a hard material, and softening it), or from the bottom up (coming from a near-liquid state, and making it thicker), and only you know just the way to go to get the perfect output.

Experienced and highly motivated in fine pastry, you are able to come up with better techniques and formulas to make your art always better.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXbh/pastry-dresser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Pastry Dresser

4 |

If you are the kind of person who gets intense, insane, almost neurotic about perfection and details, you are exactly the type we're looking for; but be aware that this job will not make your condition better! With an art background and a perfect mastery of the finest paintbrushes, you can modify every bit of an object to make it shine even brighter.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXbn/oven-instrumentist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Oven Instrumentist

4 |

A musical instrument does nothing by itself; a musical instrumentalist is but a person. But together, they play an art that is bigger than the sum of the man and the instrument, and generate powerful emotions. It takes a lot of technique; but it takes a lot more than technique. We only ask you one thing: that you do have that technique, and that extra thing.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/job-offer/UlfoxUnM0wkXYXbs/store-intern.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Store Intern

4 |

We expect only one skill from our store interns: an infinite thirst to learn about fine pastry. You might not know much about how to prepare them. You might not know much about how to sell them, and advise about them. You might not know how a pastry shop runs. We've got all of that covered for you.

Be sure to have the proper motivation, and your future with us will shine bright: we've been offering jobs to all of our interns at the end of their internship.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/product/UlfoxUnM0wkXYXbD/speculoos-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Speculoos Macaron

4 |

Did you know that World War I warriors on the French-Belgian frontier called an unauthorized truce in December 1914, so they could celebrate Christmas together? That's because in every situation, there's much joy to create and receive, from the natural friendship between the French and the Belgian cultures! So when Belgian speculoos meets French macarons, you get to experience the natural chemistry of cultures that are meant to work perfectly together...

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/product/UlfoxUnM0wkXYXbE/dark-chocolate-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Dark Chocolate Macaron

4 |

There is so much rich, decadent chocolate in this macaron that the chocolatey pleasure is just endless!

As you let the softness and the strength of our preciously selected cocoa waken your senses, you will feel a lot of pleasure and a little bit of guilt, for giving in to your dark (chocolate) side again!

There's no mistery why our Dark Chocolate Macaron is our longest-running pastry, in our whole collection, since our creation in 1992.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/product/UlfoxUnM0wkXYXbH/vanilla-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Vanilla Macaron

4 |

Experience the ultimate vanilla experience. Our vanilla Macarons are made with our very own (in-house) pure extract of Madagascar vanilla, and subtly dusted with our own vanilla sugar (which we make from real vanilla beans).

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/product/UlfoxUnM0wkXYXbJ/pistachio-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Pistachio Macaron

4 |

If you are a nut-cuisine-savvy gourmet, you probably noticed that industrial pistachio flavour tastes very different than actual pistachio.

And yet, pistachio nuts shelter a pure, delicate taste, that needs preserving as much as possible, until it lands in your hands. Therefore, as you bite into our pistachio macaron, you will feel the pistachio nut bits not only delicately set on top of the macaron, but also inside the ganache itself.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/product/UlfoxUnM0wkXYXbM/salted-caramel-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Salted Caramel Macaron

4 |

It's no wonder why our "Salted Caramel French Macaron" has become our best-selling macaron: on top of the authentic Parisian preparation that has been making our macarons so popular and enjoyed by gourmets, you can also feel the waves of Britanny's ocean as you bite into it. Two of the best French local gastronomies meet in your mouth, and suddenly, it's like French Revolution all over again, contained in a single macaron.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/product/UlfoxUnM0wkXYXbg/black-white-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Black & White Macaron

4 |

If you feel like antique, experimented tastes are the way to go, then this macaron is perfect for you! A solid touch of dark chocolate, enveloped by a softening touch of vanilla, will take the best of both familiar world, to carry you to a brand new experience! Because you know Les Bonnes Choses always finds out just how to renew your classics for you...

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/build/product/UlfoxUnM0wkXYXbg/cool-coconut-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Cool Coconut Macaron

4 |

If you ever met coconut taste on its bad day, you surely know that coconut, coming from bad-tempered islands, can be rough sometimes. That is why we like to soften it with a touch of caramel taste in its ganache. The result is the perfect encounter between the finest palm fruit and the most tasty of sugarcane's offspring.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXbQ/fruit-expert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Fruit Expert

4 |

Here at Les Bonnes Choses, we acknowledge that it's a talent to know how to turn fresh material by nature, such as fruit, into something that plays well with the other pastry ingredients. Fruit are natural and temperamental, so you need to know exactly how to tame them and convice them to behave as per your will.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXbR/store-assistant-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Store Assistant Manager

4 |

To be straightforward: as a Store Assistant Manager, your skills will be as strong as the Store Manager, meaning you can manage your teams, balance the books, give any kind of advice to your customers, ... simply run the store! You need to have extensive experience with pastry (or at least, fine cuisine), and to be customer-service-driven.

The Store Manager is usually a more seasoned Les Bonnes Choses leader, who already had the time to adapt his leadership style to the Les Bonnes Choses approach.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXbV/art-director.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Art Director

4 |

Brand visual identity must be vital to you, and you must have a thorough experience with working for/with great visual brands. We will ask you to present your previous work, and explain your choices, so be prepared. Previous work with luxury brands is a plus.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXbW/content-director.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Content Director

4 |

As a company whose marketing is very content-centric, we expect our Content Director to have a tremendous experience, both in content strategy, and in content writing. We expect our applicants to show off some of the content strategies they set up themselves, explaining their choices, and to provide amazing contents they personally wrote.

Our contents get flexibly powerfully shared on various supports: our site, our in-store printed magazine, our mobile apps, our mailings ... Our Content Director must have experience with all of those, and with using modern adaptive content managers such as prismic.io.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXbY/community-manager.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Community Manager

4 |

Mastering the art of direct communication is an experimented skill by itself; and mastering the ability to adapt to the ever-changing modern communication environment is another one. As our community manager, you will need to be proficient with both.

You will also need to have experience in both aspects, and it's much better if you have worked for/with luxury brands before (not necessarily food-related).

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXba/ganache-specialist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Ganache Specialist

4 |

It takes a solid whipping and crystalizing experience to build perfect ganaches. Ganaches can be built from the top down (building a hard material, and softening it), or from the bottom up (coming from a near-liquid state, and making it thicker), and only you know just the way to go to get the perfect output.

Experienced and highly motivated in fine pastry, you are able to come up with better techniques and formulas to make your art always better.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXbh/pastry-dresser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Pastry Dresser

4 |

If you are the kind of person who gets intense, insane, almost neurotic about perfection and details, you are exactly the type we're looking for; but be aware that this job will not make your condition better! With an art background and a perfect mastery of the finest paintbrushes, you can modify every bit of an object to make it shine even brighter.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXbn/oven-instrumentist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Oven Instrumentist

4 |

A musical instrument does nothing by itself; a musical instrumentalist is but a person. But together, they play an art that is bigger than the sum of the man and the instrument, and generate powerful emotions. It takes a lot of technique; but it takes a lot more than technique. We only ask you one thing: that you do have that technique, and that extra thing.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/job-offer/UlfoxUnM0wkXYXbs/store-intern.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Store Intern

4 |

We expect only one skill from our store interns: an infinite thirst to learn about fine pastry. You might not know much about how to prepare them. You might not know much about how to sell them, and advise about them. You might not know how a pastry shop runs. We've got all of that covered for you.

Be sure to have the proper motivation, and your future with us will shine bright: we've been offering jobs to all of our interns at the end of their internship.

5 | 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/product/UlfoxUnM0wkXYXbD/speculoos-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Speculoos Macaron

4 |

Did you know that World War I warriors on the French-Belgian frontier called an unauthorized truce in December 1914, so they could celebrate Christmas together? That's because in every situation, there's much joy to create and receive, from the natural friendship between the French and the Belgian cultures! So when Belgian speculoos meets French macarons, you get to experience the natural chemistry of cultures that are meant to work perfectly together...

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/product/UlfoxUnM0wkXYXbE/dark-chocolate-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Dark Chocolate Macaron

4 |

There is so much rich, decadent chocolate in this macaron that the chocolatey pleasure is just endless!

As you let the softness and the strength of our preciously selected cocoa waken your senses, you will feel a lot of pleasure and a little bit of guilt, for giving in to your dark (chocolate) side again!

There's no mistery why our Dark Chocolate Macaron is our longest-running pastry, in our whole collection, since our creation in 1992.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/product/UlfoxUnM0wkXYXbH/vanilla-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Vanilla Macaron

4 |

Experience the ultimate vanilla experience. Our vanilla Macarons are made with our very own (in-house) pure extract of Madagascar vanilla, and subtly dusted with our own vanilla sugar (which we make from real vanilla beans).

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/product/UlfoxUnM0wkXYXbJ/pistachio-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Pistachio Macaron

4 |

If you are a nut-cuisine-savvy gourmet, you probably noticed that industrial pistachio flavour tastes very different than actual pistachio.

And yet, pistachio nuts shelter a pure, delicate taste, that needs preserving as much as possible, until it lands in your hands. Therefore, as you bite into our pistachio macaron, you will feel the pistachio nut bits not only delicately set on top of the macaron, but also inside the ganache itself.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/product/UlfoxUnM0wkXYXbM/salted-caramel-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Salted Caramel Macaron

4 |

It's no wonder why our "Salted Caramel French Macaron" has become our best-selling macaron: on top of the authentic Parisian preparation that has been making our macarons so popular and enjoyed by gourmets, you can also feel the waves of Britanny's ocean as you bite into it. Two of the best French local gastronomies meet in your mouth, and suddenly, it's like French Revolution all over again, contained in a single macaron.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/product/UlfoxUnM0wkXYXbg/black-white-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Black & White Macaron

4 |

If you feel like antique, experimented tastes are the way to go, then this macaron is perfect for you! A solid touch of dark chocolate, enveloped by a softening touch of vanilla, will take the best of both familiar world, to carry you to a brand new experience! Because you know Les Bonnes Choses always finds out just how to renew your classics for you...

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/expected/product/UlfoxUnM0wkXYXbg/cool-coconut-macaron: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Cool Coconut Macaron

4 |

If you ever met coconut taste on its bad day, you surely know that coconut, coming from bad-tempered islands, can be rough sometimes. That is why we like to soften it with a touch of caramel taste in its ganache. The result is the perfect encounter between the finest palm fruit and the most tasty of sugarcane's offspring.

5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/collection/src/jobOffer.html: -------------------------------------------------------------------------------- 1 | --- 2 | template: jobOffer.hbt 3 | prismic: 4 | jobOffer: 5 | query: '[[:d = any(document.type, ["job-offer"])]]' 6 | collection: 7 | fileExtension: 'html' 8 | macaron: 9 | query: '[[:d = at(document.tags, ["Macaron"])] [:d = any(document.type, ["product"])]]' 10 | --- 11 | -------------------------------------------------------------------------------- /test/fixtures/collection/src/macaron.html: -------------------------------------------------------------------------------- 1 | --- 2 | template: macaron.hbt 3 | prismic: 4 | macaron: 5 | query: '[[:d = at(document.tags, ["Macaron"])] [:d = any(document.type, ["product"])]]' 6 | collection: true 7 | --- 8 | -------------------------------------------------------------------------------- /test/fixtures/collection/templates/jobOffer.hbt: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{{prismic.jobOffer.results.[0].data.name.html}}} 4 | {{{prismic.jobOffer.results.[0].data.profile.html}}} 5 | {{{prismic.jobOffer.results.[0].data.description.html}}} 6 | 7 | And here are all the Macarons you can eat when you join our company: 8 | 9 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/fixtures/collection/templates/macaron.hbt: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{{prismic.macaron.results.[0].data.name.html}}} 4 | {{{prismic.macaron.results.[0].data.description.html}}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/fixtures/linkResolver/build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /test/fixtures/linkResolver/expected/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /test/fixtures/linkResolver/src/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | template: index.hbt 3 | prismic: 4 | jobOffers: 5 | query: '[[:d = any(document.type, ["job-offer"])]]' 6 | --- 7 | -------------------------------------------------------------------------------- /test/fixtures/linkResolver/templates/index.hbt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/fixtures/pageSize/build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |