Add generate_page_content functionality for structured page content generation

- Introduced a new AI function `generate_page_content` to create structured content for website pages using JSON blocks.
- Updated `AIEngine` to handle the new function and return appropriate messages for content generation.
- Enhanced `PageGenerationService` to utilize the new AI function for generating page content based on blueprints.
- Modified `prompts.py` to include detailed content generation requirements for the new function.
- Updated site rendering logic to accommodate structured content blocks in various layouts.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-18 23:30:20 +00:00
parent 6c6133a683
commit e4e7ddfdf3
13 changed files with 1283 additions and 100 deletions

View File

@@ -7,6 +7,7 @@
import React from 'react';
import type { SiteDefinition } from '../types';
import { renderTemplate } from './templateEngine';
import { renderPageByType } from './pageTypeRenderer';
import {
DefaultLayout,
MinimalLayout,
@@ -65,28 +66,20 @@ function renderDefaultLayout(siteDefinition: SiteDefinition): React.ReactElement
const showHero = isHomePage || (homePage && siteDefinition.pages.length > 1);
const hero: React.ReactNode = (showHero && heroBlock) ? (renderTemplate(heroBlock) as React.ReactNode) : undefined;
// Render all pages as sections (excluding hero from home page if it exists)
// Render all pages using page-type-specific templates
const sections = siteDefinition.pages
.filter((page) => page.status !== 'draft' && page.status !== 'generating')
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((page) => {
// Filter out hero block if it's the home page (already rendered as hero)
// Use page-type-specific renderer if available
const blocksToRender = page.slug === 'home' && heroBlock && showHero
? page.blocks?.filter(b => b.type !== 'hero') || []
: page.blocks || [];
// Render using page-type template
return (
<div key={page.id} className="page" data-page-slug={page.slug} style={{ textAlign: 'center' }}>
{page.slug !== 'home' && <h2 style={{ textAlign: 'center', marginBottom: '1.5rem' }}>{page.title}</h2>}
{blocksToRender.length > 0 ? (
blocksToRender.map((block, index) => (
<div key={index} className="block" data-block-type={block.type} style={{ textAlign: 'center' }}>
{renderTemplate(block)}
</div>
))
) : page.slug !== 'home' ? (
<p>No content available for this page.</p>
) : null}
<div key={page.id} className="page-wrapper" data-page-slug={page.slug}>
{renderPageByType(page, blocksToRender)}
</div>
);
});
@@ -107,17 +100,11 @@ function renderMinimalLayout(siteDefinition: SiteDefinition): React.ReactElement
const mainContent = (
<>
{siteDefinition.pages
.filter((page) => page.status !== 'draft')
.filter((page) => page.status !== 'draft' && page.status !== 'generating')
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((page) => (
<div key={page.id} className="page" data-page-slug={page.slug}>
<h2>{page.title}</h2>
{page.blocks && page.blocks.length > 0 ? (
page.blocks.map((block, index) => (
<div key={index} className="block" data-block-type={block.type}>
{renderTemplate(block)}
</div>
))
) : null}
<div key={page.id} className="page-wrapper" data-page-slug={page.slug}>
{renderPageByType(page, page.blocks || [])}
</div>
))}
</>
@@ -138,16 +125,11 @@ function renderMagazineLayout(siteDefinition: SiteDefinition): React.ReactElemen
const mainContent = (
<>
{siteDefinition.pages
.filter((page) => page.status !== 'draft')
.filter((page) => page.status !== 'draft' && page.status !== 'generating')
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((page) => (
<div key={page.id} className="page" data-page-slug={page.slug}>
{page.blocks && page.blocks.length > 0 ? (
page.blocks.map((block, index) => (
<div key={index} className="block" data-block-type={block.type}>
{renderTemplate(block)}
</div>
))
) : null}
<div key={page.id} className="page-wrapper" data-page-slug={page.slug}>
{renderPageByType(page, page.blocks || [])}
</div>
))}
</>
@@ -168,16 +150,11 @@ function renderEcommerceLayout(siteDefinition: SiteDefinition): React.ReactEleme
const mainContent = (
<>
{siteDefinition.pages
.filter((page) => page.status !== 'draft')
.filter((page) => page.status !== 'draft' && page.status !== 'generating')
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((page) => (
<div key={page.id} className="page" data-page-slug={page.slug}>
{page.blocks && page.blocks.length > 0 ? (
page.blocks.map((block, index) => (
<div key={index} className="block" data-block-type={block.type}>
{renderTemplate(block)}
</div>
))
) : null}
<div key={page.id} className="page-wrapper" data-page-slug={page.slug}>
{renderPageByType(page, page.blocks || [])}
</div>
))}
</>
@@ -198,16 +175,11 @@ function renderPortfolioLayout(siteDefinition: SiteDefinition): React.ReactEleme
const mainContent = (
<>
{siteDefinition.pages
.filter((page) => page.status !== 'draft')
.filter((page) => page.status !== 'draft' && page.status !== 'generating')
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((page) => (
<div key={page.id} className="page" data-page-slug={page.slug}>
{page.blocks && page.blocks.length > 0 ? (
page.blocks.map((block, index) => (
<div key={index} className="block" data-block-type={block.type}>
{renderTemplate(block)}
</div>
))
) : null}
<div key={page.id} className="page-wrapper" data-page-slug={page.slug}>
{renderPageByType(page, page.blocks || [])}
</div>
))}
</>
@@ -228,16 +200,11 @@ function renderBlogLayout(siteDefinition: SiteDefinition): React.ReactElement {
const mainContent = (
<>
{siteDefinition.pages
.filter((page) => page.status !== 'draft')
.filter((page) => page.status !== 'draft' && page.status !== 'generating')
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((page) => (
<div key={page.id} className="page" data-page-slug={page.slug}>
{page.blocks && page.blocks.length > 0 ? (
page.blocks.map((block, index) => (
<div key={index} className="block" data-block-type={block.type}>
{renderTemplate(block)}
</div>
))
) : null}
<div key={page.id} className="page-wrapper" data-page-slug={page.slug}>
{renderPageByType(page, page.blocks || [])}
</div>
))}
</>
@@ -258,16 +225,11 @@ function renderCorporateLayout(siteDefinition: SiteDefinition): React.ReactEleme
const mainContent = (
<>
{siteDefinition.pages
.filter((page) => page.status !== 'draft')
.filter((page) => page.status !== 'draft' && page.status !== 'generating')
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((page) => (
<div key={page.id} className="page" data-page-slug={page.slug}>
{page.blocks && page.blocks.length > 0 ? (
page.blocks.map((block, index) => (
<div key={index} className="block" data-block-type={block.type}>
{renderTemplate(block)}
</div>
))
) : null}
<div key={page.id} className="page-wrapper" data-page-slug={page.slug}>
{renderPageByType(page, page.blocks || [])}
</div>
))}
</>