1+ /**
2+ * Site configuration loader for HelloEmily.dev
3+ * Dynamically loads site metadata and configures page elements
4+ */
5+
6+ document . addEventListener ( 'DOMContentLoaded' , function ( ) {
7+ // Load site metadata from JSON file
8+ fetch ( './content/site-metadata.json' )
9+ . then ( response => response . json ( ) )
10+ . then ( data => {
11+ applySiteMetadata ( data ) ;
12+ } )
13+ . catch ( error => {
14+ console . error ( 'Error loading site metadata:' , error ) ;
15+ } ) ;
16+
17+ // Load about content from markdown file
18+ fetch ( './content/about-me.md' )
19+ . then ( response => response . text ( ) )
20+ . then ( markdown => {
21+ // Simple markdown parsing for paragraphs
22+ const htmlContent = parseSimpleMarkdown ( markdown ) ;
23+ const aboutTextContainer = document . querySelector ( '.about-text' ) ;
24+
25+ if ( aboutTextContainer ) {
26+ aboutTextContainer . innerHTML = htmlContent ;
27+ }
28+ } )
29+ . catch ( error => {
30+ console . error ( 'Error loading about content:' , error ) ;
31+ } ) ;
32+ } ) ;
33+
34+ /**
35+ * Applies site metadata to the page
36+ * @param {Object } metadata - Site metadata object
37+ */
38+ function applySiteMetadata ( metadata ) {
39+ // Set page title
40+ document . title = metadata . title ;
41+
42+ // Set meta description
43+ const metaDescription = document . querySelector ( 'meta[name="description"]' ) ;
44+ if ( metaDescription ) {
45+ metaDescription . setAttribute ( 'content' , metadata . description ) ;
46+ }
47+
48+ // Update navigation if it exists
49+ const navList = document . querySelector ( 'nav ul' ) ;
50+ if ( navList && metadata . navigation ) {
51+ navList . innerHTML = '' ;
52+ metadata . navigation . forEach ( item => {
53+ const li = document . createElement ( 'li' ) ;
54+ li . innerHTML = `<a href="${ item . url } ">${ item . name } </a>` ;
55+ navList . appendChild ( li ) ;
56+ } ) ;
57+ }
58+
59+ // Update contact email
60+ const contactEmail = document . querySelector ( '.contact-email' ) ;
61+ if ( contactEmail && metadata . contact && metadata . contact . email ) {
62+ contactEmail . innerHTML = `Email: <a href="mailto:${ metadata . contact . email } ">${ metadata . contact . email } </a>` ;
63+ }
64+
65+ // Update social links
66+ const socialLinks = document . querySelector ( '.social-links' ) ;
67+ if ( socialLinks && metadata . social ) {
68+ socialLinks . innerHTML = '' ;
69+
70+ if ( metadata . social . github ) {
71+ socialLinks . innerHTML += `<a href="${ metadata . social . github } " target="_blank">GitHub</a>` ;
72+ }
73+
74+ if ( metadata . social . linkedin ) {
75+ socialLinks . innerHTML += `<a href="${ metadata . social . linkedin } " target="_blank">LinkedIn</a>` ;
76+ }
77+
78+ if ( metadata . social . instagram ) {
79+ socialLinks . innerHTML += `<a href="${ metadata . social . instagram } " target="_blank">Instagram</a>` ;
80+ }
81+ }
82+
83+ // Update skills section if it exists
84+ const skillsContainer = document . querySelector ( '.skills-container' ) ;
85+ if ( skillsContainer && metadata . skills ) {
86+ skillsContainer . innerHTML = '' ;
87+
88+ metadata . skills . forEach ( category => {
89+ const skillCategory = document . createElement ( 'div' ) ;
90+ skillCategory . className = 'skill-category' ;
91+
92+ skillCategory . innerHTML = `
93+ <h3>${ category . category } </h3>
94+ <ul class="skill-list">
95+ ${ category . items . map ( skill => `<li>${ skill } </li>` ) . join ( '' ) }
96+ </ul>
97+ ` ;
98+
99+ skillsContainer . appendChild ( skillCategory ) ;
100+ } ) ;
101+ }
102+ }
103+
104+ /**
105+ * Simple markdown parser for basic formatting
106+ * @param {string } markdown - Markdown text
107+ * @return {string } HTML content
108+ */
109+ function parseSimpleMarkdown ( markdown ) {
110+ let html = '' ;
111+ const lines = markdown . split ( '\n' ) ;
112+ let inParagraph = false ;
113+
114+ lines . forEach ( line => {
115+ // Handle headers
116+ if ( line . startsWith ( '# ' ) ) {
117+ if ( inParagraph ) {
118+ html += '</p>' ;
119+ inParagraph = false ;
120+ }
121+ html += `<h2>${ line . substring ( 2 ) } </h2>` ;
122+ }
123+ else if ( line . startsWith ( '## ' ) ) {
124+ if ( inParagraph ) {
125+ html += '</p>' ;
126+ inParagraph = false ;
127+ }
128+ html += `<h3>${ line . substring ( 3 ) } </h3>` ;
129+ }
130+ // Handle list items
131+ else if ( line . startsWith ( '- ' ) ) {
132+ if ( inParagraph ) {
133+ html += '</p>' ;
134+ inParagraph = false ;
135+ }
136+ if ( ! html . endsWith ( '</ul>' ) && ! html . endsWith ( '<ul>' ) ) {
137+ html += '<ul>' ;
138+ }
139+ html += `<li>${ line . substring ( 2 ) } </li>` ;
140+ }
141+ // Handle empty lines
142+ else if ( line . trim ( ) === '' ) {
143+ if ( inParagraph ) {
144+ html += '</p>' ;
145+ inParagraph = false ;
146+ }
147+ if ( html . endsWith ( '</li>' ) ) {
148+ html += '</ul>' ;
149+ }
150+ }
151+ // Handle regular paragraphs
152+ else {
153+ if ( ! inParagraph ) {
154+ html += '<p>' ;
155+ inParagraph = true ;
156+ } else {
157+ html += ' ' ;
158+ }
159+ html += line ;
160+ }
161+ } ) ;
162+
163+ if ( inParagraph ) {
164+ html += '</p>' ;
165+ }
166+
167+ return html ;
168+ }
0 commit comments