Skip to content

Commit

Permalink
Adding Page schematics
Browse files Browse the repository at this point in the history
  • Loading branch information
Hyperxq committed Mar 22, 2024
1 parent e72b824 commit eb66ab3
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<% if(layoutName) { %>---
import <%= layoutName %> from '<%= relativeLayoutPath %>';
---
<layoutName>
</layoutName><% } else { %>---
---<% }%>


Empty file.
Empty file.
121 changes: 121 additions & 0 deletions packages/astro/src/builder-generate/page/page.factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import {
MergeStrategy,
Rule,
Tree,
apply,
applyTemplates,
filter,
mergeWith,
move,
renameTemplateFiles,
url,
} from '@angular-devkit/schematics';
import { logger, parseName } from '../../utils';
import { askLayout } from './page.questions';
import { strings } from '@angular-devkit/schematics';

export function pageFactory({
name,
layout,
type,
}: {
name: string;
layout: string;
type: 'astro' | 'md' | 'mdx';
}): Rule {
return async (tree: Tree) => {
const { name: pageName, path } = parseName('./', name);

// logger.debug(parsedName);
// Read layouts
if (!layout) {
const layoutNames = readLayouts(tree);

if (layoutNames.length > 0) {
layout = await askLayout(layoutNames.map((x) => strings.classify(x)));
}

if (layout === 'none') {
layout = undefined;
}
} else {
const layouts = tree.getDir('./src/layouts').subfiles;
layout = strings.classify(layout);
if (!layouts.find((x) => x === `${layout}.astro`)) {
logger.error(`The layout ${layout} doesn't exist`);
process.exit(1);
}
}

// If choose any layout depends how deep wil the page will be needs to have the relative path from page to layout
const relativePathLayout = getRelativeLayoutPath(layout, path);

// Support Files type
// The page named can has a folders

return addPageFile(type, relativePathLayout, layout, pageName, path);
};
}

function getRelativeLayoutPath(layoutName: string, pagePath: string) {
const foldersBackCount = pagePath.split('/').filter((x) => x).length + 1;
return `${new Array(foldersBackCount).fill('..').join('/')}/layouts/${layoutName}.astro`;
}

function readLayouts(tree: Tree): string[] {
const layouts: string[] = [];
const layoutsDirectoryPath = './src/layouts';

if (tree.getDir(layoutsDirectoryPath).subfiles.length === 0) {
return layouts;
}

return tree.getDir(layoutsDirectoryPath).subfiles.map((x) => x.replaceAll('.astro', ''));

//TODO: support layouts in subfolders
// layoutFiles.forEach((file) => {
// const filePath = `${layoutsDirectoryPath}/${file}`;
// const content = tree.read(filePath);
// if (content) {
// // You can now do something with the content, like parsing it
// logger.debug(content.toString('utf-8'));
// }
// });
}

function addPageFile(
fileType: 'astro' | 'md' | 'mdx',
relativeLayoutPath: string,
layoutName: string,
pageName: string,
pagePath: string,
): Rule {
let basePath = './src/pages';

// if (!tree.getDir('/').subdirs.find((f) => f === 'src')) {
// basePath = './pages';
// } else {
// basePath = basePath + '/pages';
// }

const pageTypes = {
astro: '__name@classify__.astro.template',
md: '__pageName@classify__.md.template',
mdx: '__pageName@classify__.mdx.template',
};

const urlTemplates = [pageTypes[fileType]];

const template = apply(url('./files'), [
filter((path) => urlTemplates.some((urlTemplate) => path.includes(urlTemplate))),
applyTemplates({
name: pageName,
relativeLayoutPath,
layoutName,
...strings,
}),
renameTemplateFiles(),
move(`${basePath}${pagePath}`),
]);
return mergeWith(template, MergeStrategy.Overwrite);
}
6 changes: 6 additions & 0 deletions packages/astro/src/builder-generate/page/page.questions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { askQuestion } from '../../utils';

export async function askLayout(layouts: string[]): Promise<string> {
const message = 'Do you want to use any layout?';
return await askQuestion(message, ['none', ...layouts], layouts[0]);
}
31 changes: 31 additions & 0 deletions packages/astro/src/builder-generate/page/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"$schema": "http://json-schema.org/schema",
"$id": "EmptyFolder",
"title": "Add a page",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of the page.",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "What name would you like to use for the page?"
},
"layout": {
"type": "string",
"description": "layout to use"
},
"type": {
"type": "string",
"enum": [
"astro",
"md",
"mdx",
"html"
],
"default": "astro"
}
}
}
6 changes: 3 additions & 3 deletions packages/astro/src/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
]
},
"page": {
"description": "",
"factory": "",
"schema": "",
"description": "Allows to create astro page",
"factory": "./builder-generate/page/page.factory#pageFactory",
"schema": "./builder-generate/page/schema.json",
"aliases": [
"p"
]
Expand Down
6 changes: 1 addition & 5 deletions packages/astro/src/utils/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ export async function askConfirmation(message: string, defaultResponse: boolean)
return answers['confirmation'];
}

export async function askQuestion(
message: string,
choices: ListChoiceOptions[],
defaultResponseIndex: number,
): Promise<string | null> {
export async function askQuestion<T>(message: string, choices: T[], defaultResponseIndex: T): Promise<T | null> {
const question: ListQuestion = {
type: 'list',
name: 'answer',
Expand Down

0 comments on commit eb66ab3

Please sign in to comment.