diff --git a/CHANGELOG.md b/CHANGELOG.md index bdb7ea502..cfc95d387 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added a blog post: _Hacktoberfest 2025_ + ### Changed - Removed the deprecated `ITEM` activity type diff --git a/apps/api/src/app/endpoints/sitemap/sitemap.controller.ts b/apps/api/src/app/endpoints/sitemap/sitemap.controller.ts index fb581c72e..b42ae3594 100644 --- a/apps/api/src/app/endpoints/sitemap/sitemap.controller.ts +++ b/apps/api/src/app/endpoints/sitemap/sitemap.controller.ts @@ -37,6 +37,7 @@ export class SitemapController { response.setHeader('content-type', 'application/xml'); response.send( interpolate(this.sitemapXml, { + blogPosts: this.sitemapService.getBlogPosts({ currentDate }), personalFinanceTools: this.configurationService.get( 'ENABLE_FEATURE_SUBSCRIPTION' ) diff --git a/apps/api/src/app/endpoints/sitemap/sitemap.service.ts b/apps/api/src/app/endpoints/sitemap/sitemap.service.ts index 3774d2274..b8cdfc5c6 100644 --- a/apps/api/src/app/endpoints/sitemap/sitemap.service.ts +++ b/apps/api/src/app/endpoints/sitemap/sitemap.service.ts @@ -17,6 +17,121 @@ export class SitemapService { private readonly i18nService: I18nService ) {} + public getBlogPosts({ currentDate }: { currentDate: string }) { + const rootUrl = this.configurationService.get('ROOT_URL'); + + return [ + { + languageCode: 'de', + routerLink: ['2021', '07', 'hallo-ghostfolio'] + }, + { + languageCode: 'en', + routerLink: ['2021', '07', 'hello-ghostfolio'] + }, + { + languageCode: 'en', + routerLink: ['2022', '01', 'ghostfolio-first-months-in-open-source'] + }, + { + languageCode: 'en', + routerLink: ['2022', '07', 'ghostfolio-meets-internet-identity'] + }, + { + languageCode: 'en', + routerLink: ['2022', '07', 'how-do-i-get-my-finances-in-order'] + }, + { + languageCode: 'en', + routerLink: ['2022', '08', '500-stars-on-github'] + }, + { + languageCode: 'en', + routerLink: ['2022', '10', 'hacktoberfest-2022'] + }, + { + languageCode: 'en', + routerLink: ['2022', '11', 'black-friday-2022'] + }, + { + languageCode: 'en', + routerLink: [ + '2022', + '12', + 'the-importance-of-tracking-your-personal-finances' + ] + }, + { + languageCode: 'de', + routerLink: ['2023', '01', 'ghostfolio-auf-sackgeld-vorgestellt'] + }, + { + languageCode: 'en', + routerLink: ['2023', '02', 'ghostfolio-meets-umbrel'] + }, + { + languageCode: 'en', + routerLink: ['2023', '03', 'ghostfolio-reaches-1000-stars-on-github'] + }, + { + languageCode: 'en', + routerLink: [ + '2023', + '05', + 'unlock-your-financial-potential-with-ghostfolio' + ] + }, + { + languageCode: 'en', + routerLink: ['2023', '07', 'exploring-the-path-to-fire'] + }, + { + languageCode: 'en', + routerLink: ['2023', '08', 'ghostfolio-joins-oss-friends'] + }, + { + languageCode: 'en', + routerLink: ['2023', '09', 'ghostfolio-2'] + }, + { + languageCode: 'en', + routerLink: ['2023', '09', 'hacktoberfest-2023'] + }, + { + languageCode: 'en', + routerLink: ['2023', '11', 'black-week-2023'] + }, + { + languageCode: 'en', + routerLink: ['2023', '11', 'hacktoberfest-2023-debriefing'] + }, + { + languageCode: 'en', + routerLink: ['2024', '09', 'hacktoberfest-2024'] + }, + { + languageCode: 'en', + routerLink: ['2024', '11', 'black-weeks-2024'] + }, + { + languageCode: 'en', + routerLink: ['2025', '09', 'hacktoberfest-2025'] + } + ] + .map(({ languageCode, routerLink }) => { + return this.createRouteSitemapUrl({ + currentDate, + languageCode, + rootUrl, + route: { + routerLink: ['blog', ...routerLink], + path: undefined + } + }); + }) + .join('\n'); + } + public getPersonalFinanceTools({ currentDate }: { currentDate: string }) { const rootUrl = this.configurationService.get('ROOT_URL'); @@ -43,20 +158,21 @@ export class SitemapService { }); return personalFinanceTools.map(({ alias, key }) => { - const location = [ - rootUrl, - languageCode, + const routerLink = [ resourcesPath, personalFinanceToolsPath, `${productPath}-${alias ?? key}` - ].join('/'); - - return [ - ' ', - ` ${location}`, - ` ${currentDate}T00:00:00+00:00`, - ' ' - ].join('\n'); + ]; + + return this.createRouteSitemapUrl({ + currentDate, + languageCode, + rootUrl, + route: { + routerLink, + path: undefined + } + }); }); }).join('\n'); } diff --git a/apps/api/src/assets/sitemap.xml b/apps/api/src/assets/sitemap.xml index fb2a5403e..2d4d121bf 100644 --- a/apps/api/src/assets/sitemap.xml +++ b/apps/api/src/assets/sitemap.xml @@ -5,5 +5,6 @@ xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> ${publicRoutes} + ${blogPosts} ${personalFinanceTools} diff --git a/apps/api/src/middlewares/html-template.middleware.ts b/apps/api/src/middlewares/html-template.middleware.ts index 665b93354..892b1ab5e 100644 --- a/apps/api/src/middlewares/html-template.middleware.ts +++ b/apps/api/src/middlewares/html-template.middleware.ts @@ -75,6 +75,10 @@ const locales = { '/en/blog/2024/11/black-weeks-2024': { featureGraphicPath: 'assets/images/blog/black-weeks-2024.jpg', title: `Black Weeks 2024 - ${title}` + }, + '/en/blog/2025/09/hacktoberfest-2025': { + featureGraphicPath: 'assets/images/blog/hacktoberfest-2025.png', + title: `Hacktoberfest 2025 - ${title}` } }; diff --git a/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts b/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts new file mode 100644 index 000000000..72990ca47 --- /dev/null +++ b/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component.ts @@ -0,0 +1,17 @@ +import { publicRoutes } from '@ghostfolio/common/routes/routes'; + +import { Component } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +@Component({ + host: { class: 'page' }, + imports: [MatButtonModule, RouterModule], + selector: 'gf-hacktoberfest-2025-page', + templateUrl: './hacktoberfest-2025-page.html' +}) +export class Hacktoberfest2025PageComponent { + public routerLinkAbout = publicRoutes.about.routerLink; + public routerLinkBlog = publicRoutes.blog.routerLink; + public routerLinkOpenStartup = publicRoutes.openStartup.routerLink; +} diff --git a/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.html b/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.html new file mode 100644 index 000000000..318d86aa0 --- /dev/null +++ b/apps/client/src/app/pages/blog/2025/09/hacktoberfest-2025/hacktoberfest-2025-page.html @@ -0,0 +1,202 @@ +
+
+
+
+
+

Hacktoberfest 2025

+
2025-09-27
+ Hacktoberfest 2025 with Ghostfolio Teaser +
+
+

+ Ghostfolio is joining + Hacktoberfest for the fourth + time and we are looking + forward to meeting new open-source contributors along the way. Every + year in October, Hacktoberfest celebrates open source by + highlighting projects, maintainers, and contributors worldwide. Open + source maintainers around the globe dedicate extra time to support + new contributors while guiding them through their first pull + requests on + GitHub. +

+
+
+

+ Meet Ghostfolio: a modern Dashboard for Personal Finance +

+

+ Ghostfolio is a web application + that makes it easy to manage your personal finances. It aggregates + your assets and helps you make informed decisions to balance your + portfolio or plan future investments. +

+

+ The software is fully written in + TypeScript and + organized as an Nx workspace, utilizing + the latest framework releases. The backend is based on + NestJS in combination with + PostgreSQL as a database + together with Prisma and + Redis for caching. The frontend is + developed with Angular. +

+

+ With over 200 contributors, the OSS project is used daily by a + growing global community. Ghostfolio counts more than + 6’600 stars on GitHub + and + 1’600’000+ pulls on Docker Hub, standing out for its simple and user-friendly experience. +

+
+
+

How you can make an impact

+

+ Every contribution makes a difference. Whether it is implementing + new features, resolving bugs, refactoring code, enhancing + documentation, adding unit tests, or translating content into + another language, you can actively shape our project. +

+

+ New to our codebase? No worries! We have labeled a few + issues + with hacktoberfest that are ideal for newcomers. +

+

+ The official Hacktoberfest website provides some valuable + resources for beginners + to start contributing in open source. +

+
+
+

Connect with us

+

+ If you have further questions or ideas, please join our + Slack + community or get in touch on X + @ghostfolio_. +

+

+ We look forward to collaborating.
+ Thomas from Ghostfolio +

+
+
+
    +
  • + Angular +
  • +
  • + Community +
  • +
  • + Dashboard +
  • +
  • + Docker +
  • +
  • + Finance +
  • +
  • + Fintech +
  • +
  • + Ghostfolio +
  • +
  • + GitHub +
  • +
  • + Hacktoberfest +
  • +
  • + Hacktoberfest 2025 +
  • +
  • + Investment +
  • +
  • + NestJS +
  • +
  • + Nx +
  • +
  • + October +
  • +
  • + Open Source +
  • +
  • + OSS +
  • +
  • + Personal Finance +
  • +
  • + Portfolio +
  • +
  • + Portfolio Tracker +
  • +
  • + Prisma +
  • +
  • + Redis +
  • +
  • + Software +
  • +
  • + TypeScript +
  • +
  • + UX +
  • +
  • + Wealth +
  • +
  • + Wealth Management +
  • +
  • + Web Application +
  • +
+
+ +
+
+
+
diff --git a/apps/client/src/app/pages/blog/blog-page-routing.module.ts b/apps/client/src/app/pages/blog/blog-page-routing.module.ts index 0e00ee530..9b352b7a8 100644 --- a/apps/client/src/app/pages/blog/blog-page-routing.module.ts +++ b/apps/client/src/app/pages/blog/blog-page-routing.module.ts @@ -201,6 +201,15 @@ const routes: Routes = [ (c) => c.BlackWeeks2024PageComponent ), title: 'Black Weeks 2024' + }, + { + canActivate: [AuthGuard], + path: '2025/09/hacktoberfest-2025', + loadComponent: () => + import( + './2025/09/hacktoberfest-2025/hacktoberfest-2025-page.component' + ).then((c) => c.Hacktoberfest2025PageComponent), + title: 'Hacktoberfest 2025' } ]; diff --git a/apps/client/src/app/pages/blog/blog-page.html b/apps/client/src/app/pages/blog/blog-page.html index babeec4c6..88b685d33 100644 --- a/apps/client/src/app/pages/blog/blog-page.html +++ b/apps/client/src/app/pages/blog/blog-page.html @@ -8,6 +8,30 @@ finance + + + + + @if (hasPermissionForSubscription) { diff --git a/apps/client/src/assets/images/blog/hacktoberfest-2025.png b/apps/client/src/assets/images/blog/hacktoberfest-2025.png new file mode 100644 index 000000000..ab04e6dce Binary files /dev/null and b/apps/client/src/assets/images/blog/hacktoberfest-2025.png differ