devfolio-page 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -220,6 +220,16 @@ const layoutSchema = z.object({
220
220
  show_experiments: z.boolean().optional(),
221
221
  show_timeline: z.boolean().optional(),
222
222
  });
223
+ const pageContentSchema = z.object({
224
+ title: z.string().optional().nullable(),
225
+ description: z.string().optional().nullable(),
226
+ });
227
+ const pagesSchema = z.object({
228
+ projects: pageContentSchema.optional().nullable(),
229
+ about: pageContentSchema.optional().nullable(),
230
+ experiments: pageContentSchema.optional().nullable(),
231
+ writing: pageContentSchema.optional().nullable(),
232
+ });
223
233
  // =============================================================================
224
234
  // Main Portfolio Schema
225
235
  // =============================================================================
@@ -271,6 +281,8 @@ export const portfolioSchema = z.object({
271
281
  layout: layoutSchema.optional().nullable(),
272
282
  // Settings
273
283
  settings: settingsSchema.optional().nullable(),
284
+ // Page content customization
285
+ pages: pagesSchema.optional().nullable(),
274
286
  });
275
287
  // =============================================================================
276
288
  // Helper Functions
@@ -177,6 +177,8 @@ async function generateHomepage(portfolio, themePath, outputDir, theme) {
177
177
  hasProjects: (portfolio.projects?.length ?? 0) > 0,
178
178
  hasExperiments: (portfolio.experiments?.length ?? 0) > 0,
179
179
  hasWriting: (portfolio.sections.writing?.length ?? 0) > 0,
180
+ // Navigation links
181
+ nav_links: generateNavLinks(portfolio, false, 'home'),
180
182
  };
181
183
  const html = Mustache.render(template, data);
182
184
  await fs.writeFile(path.join(outputDir, 'index.html'), html);
@@ -233,6 +235,8 @@ async function generateProjectsIndex(portfolio, themePath, outputDir, theme) {
233
235
  projects: portfolio.projects || [],
234
236
  colorScheme: settings.color_scheme || defaultColorScheme,
235
237
  nav_links: generateNavLinks(portfolio, true, 'projects'),
238
+ page_title: portfolio.pages?.projects?.title,
239
+ page_description: portfolio.pages?.projects?.description,
236
240
  };
237
241
  const html = Mustache.render(template, data);
238
242
  await fs.writeFile(path.join(outputDir, 'projects/index.html'), html);
@@ -271,6 +275,8 @@ async function generateAboutPage(portfolio, themePath, outputDir, theme) {
271
275
  hasEducation: (portfolio.sections?.education?.length ?? 0) > 0,
272
276
  colorScheme: settings.color_scheme || defaultColorScheme,
273
277
  nav_links: generateNavLinks(portfolio, true, 'about'),
278
+ page_title: portfolio.pages?.about?.title,
279
+ page_description: portfolio.pages?.about?.description,
274
280
  };
275
281
  const html = Mustache.render(template, data);
276
282
  await fs.writeFile(path.join(outputDir, 'about/index.html'), html);
@@ -294,6 +300,8 @@ async function generateExperimentsIndex(portfolio, themePath, outputDir, theme)
294
300
  experiments: portfolio.experiments || [],
295
301
  colorScheme: settings.color_scheme || defaultColorScheme,
296
302
  nav_links: generateNavLinks(portfolio, true, 'experiments'),
303
+ page_title: portfolio.pages?.experiments?.title,
304
+ page_description: portfolio.pages?.experiments?.description,
297
305
  };
298
306
  const html = Mustache.render(template, data);
299
307
  await fs.writeFile(path.join(outputDir, 'experiments/index.html'), html);
@@ -317,6 +325,8 @@ async function generateWritingIndex(portfolio, themePath, outputDir, theme) {
317
325
  writing: portfolio.sections.writing || [],
318
326
  colorScheme: settings.color_scheme || defaultColorScheme,
319
327
  nav_links: generateNavLinks(portfolio, true, 'writing'),
328
+ page_title: portfolio.pages?.writing?.title,
329
+ page_description: portfolio.pages?.writing?.description,
320
330
  };
321
331
  const html = Mustache.render(template, data);
322
332
  await fs.writeFile(path.join(outputDir, 'writing/index.html'), html);
@@ -770,6 +780,7 @@ async function generateHomepageInMemory(portfolio, themePath, theme, files) {
770
780
  hasProjects: (portfolio.projects?.length ?? 0) > 0,
771
781
  hasExperiments: (portfolio.experiments?.length ?? 0) > 0,
772
782
  hasWriting: (portfolio.sections.writing?.length ?? 0) > 0,
783
+ nav_links: generateNavLinks(portfolio, false, 'home'),
773
784
  };
774
785
  const html = Mustache.render(template, data);
775
786
  files.set('index.html', Buffer.from(html, 'utf-8'));
@@ -821,6 +832,8 @@ async function generateProjectsIndexInMemory(portfolio, themePath, theme, files)
821
832
  projects: portfolio.projects || [],
822
833
  colorScheme: settings.color_scheme || defaultColorScheme,
823
834
  nav_links: generateNavLinks(portfolio, true, 'projects'),
835
+ page_title: portfolio.pages?.projects?.title,
836
+ page_description: portfolio.pages?.projects?.description,
824
837
  };
825
838
  const html = Mustache.render(template, data);
826
839
  files.set('projects/index.html', Buffer.from(html, 'utf-8'));
@@ -857,6 +870,8 @@ async function generateAboutPageInMemory(portfolio, themePath, theme, files) {
857
870
  hasEducation: (portfolio.sections?.education?.length ?? 0) > 0,
858
871
  colorScheme: settings.color_scheme || defaultColorScheme,
859
872
  nav_links: generateNavLinks(portfolio, true, 'about'),
873
+ page_title: portfolio.pages?.about?.title,
874
+ page_description: portfolio.pages?.about?.description,
860
875
  };
861
876
  const html = Mustache.render(template, data);
862
877
  files.set('about/index.html', Buffer.from(html, 'utf-8'));
@@ -878,6 +893,8 @@ async function generateExperimentsIndexInMemory(portfolio, themePath, theme, fil
878
893
  experiments: portfolio.experiments || [],
879
894
  colorScheme: settings.color_scheme || defaultColorScheme,
880
895
  nav_links: generateNavLinks(portfolio, true, 'experiments'),
896
+ page_title: portfolio.pages?.experiments?.title,
897
+ page_description: portfolio.pages?.experiments?.description,
881
898
  };
882
899
  const html = Mustache.render(template, data);
883
900
  files.set('experiments/index.html', Buffer.from(html, 'utf-8'));
@@ -899,6 +916,8 @@ async function generateWritingIndexInMemory(portfolio, themePath, theme, files)
899
916
  writing: portfolio.sections.writing || [],
900
917
  colorScheme: settings.color_scheme || defaultColorScheme,
901
918
  nav_links: generateNavLinks(portfolio, true, 'writing'),
919
+ page_title: portfolio.pages?.writing?.title,
920
+ page_description: portfolio.pages?.writing?.description,
902
921
  };
903
922
  const html = Mustache.render(template, data);
904
923
  files.set('writing/index.html', Buffer.from(html, 'utf-8'));
@@ -47,8 +47,8 @@
47
47
  <main class="page-content">
48
48
  <header class="page-header">
49
49
  <div class="header-ornament"></div>
50
- <h1>About</h1>
51
- {{#tagline}}<p>{{tagline}}</p>{{/tagline}}
50
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}About{{/page_title}}</h1>
51
+ {{#page_description}}<p>{{page_description}}</p>{{/page_description}}{{^page_description}}{{#tagline}}<p>{{tagline}}</p>{{/tagline}}{{/page_description}}
52
52
  </header>
53
53
 
54
54
  <div class="about-content">
@@ -47,8 +47,8 @@
47
47
  <main class="page-content">
48
48
  <header class="page-header">
49
49
  <div class="header-ornament"></div>
50
- <h1>Experiments</h1>
51
- <p>Explorations, studies, and curious investigations.</p>
50
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Experiments{{/page_title}}</h1>
51
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}Explorations, studies, and curious investigations.{{/page_description}}</p>
52
52
  </header>
53
53
 
54
54
  <div class="experiments-list">
@@ -47,8 +47,8 @@
47
47
  <main class="page-content">
48
48
  <header class="page-header">
49
49
  <div class="header-ornament"></div>
50
- <h1>Complete Works</h1>
51
- <p>A collection of projects spanning research, development, and creative endeavors.</p>
50
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Complete Works{{/page_title}}</h1>
51
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}A collection of projects spanning research, development, and creative endeavors.{{/page_description}}</p>
52
52
  </header>
53
53
 
54
54
  <div class="projects-list">
@@ -47,8 +47,8 @@
47
47
  <main class="page-content">
48
48
  <header class="page-header">
49
49
  <div class="header-ornament"></div>
50
- <h1>Publications</h1>
51
- <p>Articles, essays, and scholarly writings.</p>
50
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Publications{{/page_title}}</h1>
51
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}Articles, essays, and scholarly writings.{{/page_description}}</p>
52
52
  </header>
53
53
 
54
54
  <div class="writing-list">
@@ -46,8 +46,8 @@
46
46
 
47
47
  <main class="main-content">
48
48
  <header class="page-header">
49
- <h1>About</h1>
50
- {{#tagline}}<p>{{tagline}}</p>{{/tagline}}
49
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}About{{/page_title}}</h1>
50
+ {{#page_description}}<p>{{page_description}}</p>{{/page_description}}{{^page_description}}{{#tagline}}<p>{{tagline}}</p>{{/tagline}}{{/page_description}}
51
51
  </header>
52
52
 
53
53
  <div class="about-content">
@@ -46,8 +46,8 @@
46
46
 
47
47
  <main class="main-content">
48
48
  <header class="page-header">
49
- <h1>Experiments</h1>
50
- <p>Side projects, explorations, and things I'm tinkering with.</p>
49
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Experiments{{/page_title}}</h1>
50
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}Side projects, explorations, and things I'm tinkering with.{{/page_description}}</p>
51
51
  </header>
52
52
 
53
53
  <div class="experiments-grid">
@@ -46,8 +46,8 @@
46
46
 
47
47
  <main class="main-content">
48
48
  <header class="page-header">
49
- <h1>Projects</h1>
50
- <p>A collection of work spanning product development, open source, and research.</p>
49
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Projects{{/page_title}}</h1>
50
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}A collection of work spanning product development, open source, and research.{{/page_description}}</p>
51
51
  </header>
52
52
 
53
53
  <div class="projects-grid">
@@ -46,8 +46,8 @@
46
46
 
47
47
  <main class="main-content">
48
48
  <header class="page-header">
49
- <h1>Writing</h1>
50
- <p>Articles, blog posts, and technical writing.</p>
49
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Writing{{/page_title}}</h1>
50
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}Articles, blog posts, and technical writing.{{/page_description}}</p>
51
51
  </header>
52
52
 
53
53
  <div class="writing-list">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devfolio-page",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Your portfolio as code. Version control it like software.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -47,8 +47,8 @@
47
47
  <main class="page-content">
48
48
  <header class="page-header">
49
49
  <div class="header-ornament"></div>
50
- <h1>About</h1>
51
- {{#tagline}}<p>{{tagline}}</p>{{/tagline}}
50
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}About{{/page_title}}</h1>
51
+ {{#page_description}}<p>{{page_description}}</p>{{/page_description}}{{^page_description}}{{#tagline}}<p>{{tagline}}</p>{{/tagline}}{{/page_description}}
52
52
  </header>
53
53
 
54
54
  <div class="about-content">
@@ -47,8 +47,8 @@
47
47
  <main class="page-content">
48
48
  <header class="page-header">
49
49
  <div class="header-ornament"></div>
50
- <h1>Experiments</h1>
51
- <p>Explorations, studies, and curious investigations.</p>
50
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Experiments{{/page_title}}</h1>
51
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}Explorations, studies, and curious investigations.{{/page_description}}</p>
52
52
  </header>
53
53
 
54
54
  <div class="experiments-list">
@@ -47,8 +47,8 @@
47
47
  <main class="page-content">
48
48
  <header class="page-header">
49
49
  <div class="header-ornament"></div>
50
- <h1>Complete Works</h1>
51
- <p>A collection of projects spanning research, development, and creative endeavors.</p>
50
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Complete Works{{/page_title}}</h1>
51
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}A collection of projects spanning research, development, and creative endeavors.{{/page_description}}</p>
52
52
  </header>
53
53
 
54
54
  <div class="projects-list">
@@ -47,8 +47,8 @@
47
47
  <main class="page-content">
48
48
  <header class="page-header">
49
49
  <div class="header-ornament"></div>
50
- <h1>Publications</h1>
51
- <p>Articles, essays, and scholarly writings.</p>
50
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Publications{{/page_title}}</h1>
51
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}Articles, essays, and scholarly writings.{{/page_description}}</p>
52
52
  </header>
53
53
 
54
54
  <div class="writing-list">
@@ -46,8 +46,8 @@
46
46
 
47
47
  <main class="main-content">
48
48
  <header class="page-header">
49
- <h1>About</h1>
50
- {{#tagline}}<p>{{tagline}}</p>{{/tagline}}
49
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}About{{/page_title}}</h1>
50
+ {{#page_description}}<p>{{page_description}}</p>{{/page_description}}{{^page_description}}{{#tagline}}<p>{{tagline}}</p>{{/tagline}}{{/page_description}}
51
51
  </header>
52
52
 
53
53
  <div class="about-content">
@@ -46,8 +46,8 @@
46
46
 
47
47
  <main class="main-content">
48
48
  <header class="page-header">
49
- <h1>Experiments</h1>
50
- <p>Side projects, explorations, and things I'm tinkering with.</p>
49
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Experiments{{/page_title}}</h1>
50
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}Side projects, explorations, and things I'm tinkering with.{{/page_description}}</p>
51
51
  </header>
52
52
 
53
53
  <div class="experiments-grid">
@@ -46,8 +46,8 @@
46
46
 
47
47
  <main class="main-content">
48
48
  <header class="page-header">
49
- <h1>Projects</h1>
50
- <p>A collection of work spanning product development, open source, and research.</p>
49
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Projects{{/page_title}}</h1>
50
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}A collection of work spanning product development, open source, and research.{{/page_description}}</p>
51
51
  </header>
52
52
 
53
53
  <div class="projects-grid">
@@ -46,8 +46,8 @@
46
46
 
47
47
  <main class="main-content">
48
48
  <header class="page-header">
49
- <h1>Writing</h1>
50
- <p>Articles, blog posts, and technical writing.</p>
49
+ <h1>{{#page_title}}{{page_title}}{{/page_title}}{{^page_title}}Writing{{/page_title}}</h1>
50
+ <p>{{#page_description}}{{page_description}}{{/page_description}}{{^page_description}}Articles, blog posts, and technical writing.{{/page_description}}</p>
51
51
  </header>
52
52
 
53
53
  <div class="writing-list">