@@ -51,7 +51,7 @@ class TwingLoaderPatternLab {
5151 * @throws TwingErrorLoader When name is not found
5252 */
5353 getSourceContext ( name , from ) {
54- var pattern = this . patterns . get ( name ) ;
54+ const pattern = this . patterns . get ( name ) ;
5555 return Promise . resolve (
5656 new TwingSource ( pattern . extendedTemplate , name , pattern . relPath )
5757 ) ;
@@ -116,23 +116,23 @@ const fileSystemLoader = new TwingLoaderFilesystem();
116116const patternLabLoader = new TwingLoaderPatternLab ( ) ;
117117const chainLoader = new TwingLoaderChain ( [ fileSystemLoader , patternLabLoader ] ) ;
118118const twing = new TwingEnvironment ( chainLoader ) ;
119- var metaPath ;
119+ let metaPath ;
120+ let patternLabConfig = { } ;
120121
121- var engine_twig = {
122+ const engine_twig = {
122123 engine : twing ,
123124 engineName : 'twig' ,
124125 engineFileExtension : '.twig' ,
125126
126127 // regexes, stored here so they're only compiled once
127128 findPartialsRE :
128- / { % [ - ] ? \s * (?: e x t e n d s | i n c l u d e | e m b e d | f r o m | i m p o r t | u s e ) \s + ( ' [ ^ ' ] + ' | " [ ^ " ] + " ) .* ?% } / g,
129- findPartialKeyRE : / " ( (?: \\ .| [ ^ " \\ ] ) * ) " / ,
129+ / { [ % { ] \s * .* ?(?: e x t e n d s | i n c l u d e | e m b e d | f r o m | i m p o r t | u s e ) \( ? \s * [ ' " ] ( .+ ?) [ ' " ] [ \s \S ] * ?\) ? \s * [ % } ] } / g,
130130 findListItemsRE :
131131 / ( { { # ( ) ? ) ( l i s t ( I | i ) t e m s .) ( o n e | t w o | t h r e e | f o u r | f i v e | s i x | s e v e n | e i g h t | n i n e | t e n | e l e v e n | t w e l v e | t h i r t e e n | f o u r t e e n | f i f t e e n | s i x t e e n | s e v e n t e e n | e i g h t e e n | n i n e t e e n | t w e n t y ) ( ) ? } } / g, // TODO
132132
133133 // render it
134134 renderPattern : function renderPattern ( pattern , data , partials ) {
135- var patternPath = pattern . basePattern
135+ let patternPath = pattern . basePattern
136136 ? pattern . basePattern . relPath
137137 : pattern . relPath ;
138138 if ( patternPath . lastIndexOf ( metaPath ) === 0 ) {
@@ -150,8 +150,15 @@ var engine_twig = {
150150
151151 // find and return any {% include 'template-name' %} within pattern
152152 findPartials : function findPartials ( pattern ) {
153- var matches = pattern . template . match ( this . findPartialsRE ) ;
154- return matches ;
153+ const matches = pattern . template . match ( this . findPartialsRE ) ;
154+ const filteredMatches =
155+ matches &&
156+ matches . filter ( ( match ) => {
157+ // Filter out programmatically created includes.
158+ // i.e. {% include '@namespace/icons/assets/' ~ name ~ '.svg' % }
159+ return match . indexOf ( '~' ) === - 1 ;
160+ } ) ;
161+ return filteredMatches ;
155162 } ,
156163
157164 // returns any patterns that match {{> value(foo:"bar") }} or {{>
@@ -161,18 +168,90 @@ var engine_twig = {
161168 // being implemented here.
162169 return [ ] ;
163170 } ,
171+
164172 findListItems : function ( pattern ) {
165- var matches = pattern . template . match ( this . findListItemsRE ) ;
173+ const matches = pattern . template . match ( this . findListItemsRE ) ;
166174 return matches ;
167175 } ,
168176
169177 // given a pattern, and a partial string, tease out the "pattern key" and
170178 // return it.
171179 findPartial : function ( partialString ) {
172- var partial = partialString . match ( this . findPartialKeyRE ) [ 0 ] ;
173- partial = partial . replace ( / " / g, '' ) ;
180+ try {
181+ const partial = partialString . replace ( this . findPartialsRE , '$1' ) ;
182+
183+ // Check if namespaces is not empty.
184+ const [ selectedNamespace ] = fileSystemLoader
185+ . getNamespaces ( )
186+ . filter ( ( namespace ) => {
187+ // Check to see if this partial contains within the namespace id.
188+ return partial . indexOf ( `@${ namespace } ` ) !== - 1 ;
189+ } ) ;
190+
191+ let namespaceResolvedPartial = '' ;
192+
193+ if ( selectedNamespace . length > 0 ) {
194+ // Loop through all namespaces and try to resolve the namespace to a file path.
195+ const namespacePaths = fileSystemLoader . getPaths ( selectedNamespace ) ;
196+
197+ for ( let index = 0 ; index < namespacePaths . length ; index ++ ) {
198+ const patternPath = path . isAbsolute ( namespacePaths [ index ] )
199+ ? path . relative (
200+ patternLabConfig . paths . source . root ,
201+ namespacePaths [ index ]
202+ )
203+ : namespacePaths [ index ] ;
204+
205+ // Replace the name space with the actual path.
206+ // i.e. @atoms -> source/_patterns/atoms
207+ const tempPartial = path . join (
208+ process . cwd ( ) ,
209+ partial . replace ( `@${ selectedNamespace } ` , patternPath )
210+ ) ;
174211
175- return partial ;
212+ try {
213+ // Check to see if the file actually exists.
214+ if ( fs . existsSync ( tempPartial ) ) {
215+ // get the path to the top-level folder of this pattern
216+ // ex. /Users/bradfrost/sites/pattern-lab/packages/edition-twig/source/_patterns/atoms
217+ const fullFolderPath = `${
218+ tempPartial . split ( namespacePaths [ index ] ) [ 0 ]
219+ } ${ namespacePaths [ index ] } `;
220+
221+ // then tease out the folder name itself (including the # prefix)
222+ // ex. atoms
223+ const folderName = fullFolderPath . substring (
224+ fullFolderPath . lastIndexOf ( '/' ) + 1 ,
225+ fullFolderPath . length
226+ ) ;
227+
228+ // finally, return the Twig path we created from the full file path
229+ // ex. atoms/buttons/button.twig
230+ const fullIncludePath = tempPartial . replace (
231+ tempPartial . split (
232+ `${ folderName } ${ tempPartial . split ( folderName ) [ 1 ] } `
233+ ) [ 0 ] ,
234+ ''
235+ ) ;
236+
237+ namespaceResolvedPartial = fullIncludePath ;
238+
239+ // After it matches one time, set the resolved partial and exit the loop.
240+ break ;
241+ }
242+ } catch ( err ) {
243+ console . error ( err ) ;
244+ }
245+ }
246+ }
247+ // Return the path with the namespace resolved OR the regex'd partial.
248+ return namespaceResolvedPartial || partial ;
249+ } catch ( err ) {
250+ console . error (
251+ 'Error occurred when trying to find partial name in: ' + partialString
252+ ) ;
253+ return null ;
254+ }
176255 } ,
177256
178257 spawnFile : function ( config , fileName ) {
@@ -209,31 +288,32 @@ var engine_twig = {
209288 * @param {object } config - the global config object from core
210289 */
211290 usePatternLabConfig : function ( config ) {
291+ patternLabConfig = config ;
212292 metaPath = path . resolve ( config . paths . source . meta ) ;
213293 // Global paths
214294 fileSystemLoader . addPath ( config . paths . source . meta ) ;
215295 fileSystemLoader . addPath ( config . paths . source . patterns ) ;
216296 // Namespaced paths
217297 if (
218- config [ ' engines' ] &&
219- config [ ' engines' ] [ ' twig' ] &&
220- config [ ' engines' ] [ ' twig' ] [ ' namespaces' ]
298+ config . engines &&
299+ config . engines . twig &&
300+ config . engines . twig . namespaces
221301 ) {
222- var namespaces = config [ ' engines' ] [ ' twig' ] [ ' namespaces' ] ;
302+ const namespaces = config . engines . twig . namespaces ;
223303 Object . keys ( namespaces ) . forEach ( function ( key , index ) {
224304 fileSystemLoader . addPath ( namespaces [ key ] , key ) ;
225305 } ) ;
226306 }
227307
228308 // add twing extensions
229309 if (
230- config [ ' engines' ] &&
231- config [ ' engines' ] [ ' twig' ] &&
232- config [ ' engines' ] [ ' twig' ] [ ' loadExtensionsFile' ]
310+ config . engines &&
311+ config . engines . twig &&
312+ config . engines . twig . loadExtensionsFile
233313 ) {
234314 const extensionsFile = path . resolve (
235315 './' ,
236- config [ ' engines' ] [ ' twig' ] [ ' loadExtensionsFile' ]
316+ config . engines . twig . loadExtensionsFile
237317 ) ;
238318 if ( fs . pathExistsSync ( extensionsFile ) ) {
239319 try {
0 commit comments