Skip to content

Commit

Permalink
Merge pull request #14 from CloudCannon/eleventy/collections
Browse files Browse the repository at this point in the history
Better Eleventy detection
  • Loading branch information
georgephillips authored Sep 4, 2024
2 parents e6e1aba + fca4316 commit bff9ed9
Show file tree
Hide file tree
Showing 72 changed files with 9,973 additions and 264 deletions.
47 changes: 23 additions & 24 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@
},
"author": "CloudCannon <[email protected]>",
"devDependencies": {
"@cloudcannon/configuration-types": "0.0.11",
"@cloudcannon/configuration-types": "0.0.12",
"@types/he": "^1.2.3",
"@types/js-yaml": "^4.0.9",
"@types/node": "^22.5.0",
"@types/node": "^22.5.2",
"ava": "^6.1.3",
"c8": "^10.1.2",
"eslint": "^9.9.0",
"eslint": "^9.9.1",
"prettier": "^3.3.3",
"typescript": "^5.5.4"
},
Expand Down
30 changes: 15 additions & 15 deletions src/defaults.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
/** @type {import('@cloudcannon/configuration-types').MarkdownAttributeElementOptions} */
export const commonmarkAttributeElementOptions = {
inline: 'none',
block: 'space right',
img: 'right',
ul: 'below',
ol: 'below',
li: 'space right',
table: 'newline below',
blockquote: 'below',
}
inline: 'none',
block: 'space right',
img: 'right',
ul: 'below',
ol: 'below',
li: 'space right',
table: 'newline below',
blockquote: 'below',
};

/** @type {import('@cloudcannon/configuration-types').MarkdownAttributeElementOptions} */
export const kramdownAttributeElementOptions = {
inline: 'right',
block: 'below',
tr: 'none',
td: 'none',
li: 'right-of-prefix',
}
inline: 'right',
block: 'below',
tr: 'none',
td: 'none',
li: 'right-of-prefix',
};
7 changes: 5 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { guessSsg, ssgs } from './ssgs/ssgs.js';
import { findBasePath } from './collections.js';
import { normalisePath } from './utility.js';

export { ssgs } from './ssgs/ssgs.js';

Expand Down Expand Up @@ -70,11 +71,13 @@ export async function generateConfiguration(filePaths, options) {
* @returns {Promise<import('./types').BuildCommands>}
*/
export async function generateBuildCommands(filePaths, options) {
let source = options?.config?.source ? normalisePath(options.config.source) : undefined;

const ssg = options?.buildConfig?.ssg
? ssgs[options.buildConfig.ssg]
: guessSsg(filterPaths(filePaths, options?.config?.source));
: guessSsg(filterPaths(filePaths, source));

const source = options?.config?.source ?? ssg.getSource(filePaths);
source = source ?? ssg.getSource(filePaths);
filePaths = filterPaths(filePaths, source);

const files = ssg.groupFiles(filePaths);
Expand Down
59 changes: 59 additions & 0 deletions src/ssgs/eleventy.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { joinPaths, stripBottomPath } from '../utility.js';
import Ssg from './ssg.js';

export default class Eleventy extends Ssg {
Expand Down Expand Up @@ -28,6 +29,64 @@ export default class Eleventy extends Ssg {
return super.contentExtensions().concat(['.html']);
}

partialFolders() {
return super.partialFolders().concat(['_includes/']);
}

ignoredFolders() {
return super.ignoredFolders().concat([
'_site/', // build output
]);
}

conventionalPathsInSource = ['_includes/', '_data/'];

/**
* Attempts to find the most likely source folder.
*
* @param filePaths {string[]} List of input file paths.
* @returns {string | undefined}
*/
getSource(filePaths) {
const source = super.getSource(filePaths);
if (source !== undefined) {
return source;
}

const configFilePath = filePaths.find(this.isConfigPath.bind(this));
if (configFilePath) {
return stripBottomPath(configFilePath) || undefined;
}
}

/**
* Generates a collection config entry.
*
* @param key {string}
* @param path {string}
* @param options {{ basePath?: string; }=}
* @returns {import('@cloudcannon/configuration-types').CollectionConfig}
*/
generateCollectionConfig(key, path, options) {
const collectionConfig = super.generateCollectionConfig(key, path, options);
collectionConfig.output = !(path === '_data' || path.endsWith('/_data'));
return collectionConfig;
}

/**
* Filters out collection paths that are collections, but exist in isolated locations.
* Used when a data folder (or similar) is causing all collections to group under one
* `collections_config` entry.
*
* @param collectionPaths {string[]}
* @param basePath {string}
* @returns {string[]}
*/
filterContentCollectionPaths(collectionPaths, basePath) {
const dataPath = joinPaths([basePath, '_data']);
return collectionPaths.filter((path) => path !== dataPath && !path.startsWith(`${dataPath}/`));
}

/**
* @param _config {Record<string, any>}
* @returns {import('@cloudcannon/configuration-types').MarkdownSettings}
Expand Down
73 changes: 24 additions & 49 deletions src/ssgs/hugo.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { findBasePath } from '../collections.js';
import { decodeEntity, joinPaths, stripTopPath } from '../utility.js';
import { decodeEntity, joinPaths } from '../utility.js';
import Ssg from './ssg.js';

export default class Hugo extends Ssg {
Expand Down Expand Up @@ -83,6 +83,20 @@ export default class Hugo extends Ssg {
return collectionConfig;
}

/**
* Filters out collection paths that are collections, but exist in isolated locations.
* Used when a data folder (or similar) is causing all collections to group under one
* `collections_config` entry.
*
* @param collectionPaths {string[]}
* @param basePath {string}
* @returns {string[]}
*/
filterContentCollectionPaths(collectionPaths, basePath) {
const dataPath = joinPaths([basePath, 'data']);
return collectionPaths.filter((path) => path !== dataPath && !path.startsWith(`${dataPath}/`));
}

/**
* Generates collections config from a set of paths.
*
Expand All @@ -91,10 +105,6 @@ export default class Hugo extends Ssg {
* @returns {import('../types').CollectionsConfig}
*/
generateCollectionsConfig(collectionPaths, options) {
/** @type {import('../types').CollectionsConfig} */
const collectionsConfig = {};
let basePath = options.basePath;

const collectionPathsOutsideExampleSite = collectionPaths.filter(
(path) => !path.includes('exampleSite/'),
);
Expand All @@ -103,51 +113,15 @@ export default class Hugo extends Ssg {
collectionPathsOutsideExampleSite.length &&
collectionPathsOutsideExampleSite.length !== collectionPaths.length;

// Exclude collections found inside the exampleSite folder, unless they are the only collections
if (hasNonExampleSiteCollections) {
basePath = findBasePath(collectionPathsOutsideExampleSite);
collectionPaths = collectionPathsOutsideExampleSite;
}

const dataPath = joinPaths([basePath, 'data']);
const collectionPathsOutsideData = collectionPaths.filter((path) => !path.startsWith(dataPath));
const hasDataCollection =
collectionPathsOutsideData.length &&
collectionPathsOutsideData.length !== collectionPaths.length;

// Reprocess basePath to exclude the data folder
if (hasDataCollection) {
basePath = findBasePath(collectionPathsOutsideData);
}

basePath = stripTopPath(basePath, options.source);

const sortedPaths = collectionPaths.sort((a, b) => a.length - b.length);
/** @type {string[]} */
const seenPaths = [];

for (const fullPath of sortedPaths) {
const path = stripTopPath(fullPath, options.source);
const pathInBasePath = stripTopPath(path, basePath);

if (
!path.startsWith(dataPath) &&
seenPaths.some((seenPath) => pathInBasePath.startsWith(seenPath))
) {
// Skip collection if not data, or a top-level content collection (i.e. seen before)
continue;
}

if (pathInBasePath) {
seenPaths.push(pathInBasePath + '/');
}

const key = this.generateCollectionsConfigKey(pathInBasePath, collectionsConfig);

collectionsConfig[key] = this.generateCollectionConfig(key, path, { basePath });
// Exclude collections found inside the exampleSite folder, unless they are the only collections
return super.generateCollectionsConfig(collectionPathsOutsideExampleSite, {
...options,
basePath: findBasePath(collectionPathsOutsideExampleSite),
});
}

return collectionsConfig;
return super.generateCollectionsConfig(collectionPaths, options);
}

/**
Expand Down Expand Up @@ -196,14 +170,15 @@ export default class Hugo extends Ssg {
headingTags.forEach((tag) => {
attribute_elements[tag] = !!parser?.attribute?.title ? 'space right' : 'none';
});

/** @type {(keyof HTMLElementTagNameMap)[]} */
const otherTags = ['blockquote', 'hr', 'ol', 'ul', 'p', 'table'];
otherTags.forEach((tag) => {
attribute_elements[tag] = !!parser?.attribute?.block ? 'below' : 'none';
});

const imgAttrsAllowed = !!parser?.attribute?.block && parser?.wrapStandAloneImageWithinParagraph === false;
const imgAttrsAllowed =
!!parser?.attribute?.block && parser?.wrapStandAloneImageWithinParagraph === false;
attribute_elements.img = imgAttrsAllowed ? 'below' : 'none';

options.attribute_elements = attribute_elements;
Expand Down
1 change: 0 additions & 1 deletion src/ssgs/jekyll.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,6 @@ export default class Jekyll extends Ssg {

options.attributes = true;
options.attribute_elements = kramdownAttributeElementOptions;

} else if (config) {
const commonmarkConfig = config?.['commonmark'] || {};

Expand Down
Loading

0 comments on commit bff9ed9

Please sign in to comment.