mirror of https://github.com/ghostfolio/ghostfolio
8 changed files with 105 additions and 94 deletions
@ -0,0 +1,82 @@ |
|||||
|
import * as fs from 'fs'; |
||||
|
|
||||
|
import { NextFunction, Request, Response } from 'express'; |
||||
|
import { join } from 'path'; |
||||
|
import { DATE_FORMAT, interpolate } from '@ghostfolio/common/helper'; |
||||
|
import { environment } from '@ghostfolio/api/environments/environment'; |
||||
|
import { SUPPORTED_LANGUAGE_CODES } from '@ghostfolio/common/config'; |
||||
|
import { format } from 'date-fns'; |
||||
|
|
||||
|
const title = 'Ghostfolio – Open Source Wealth Management Software'; |
||||
|
|
||||
|
// TODO
|
||||
|
const descriptions = { |
||||
|
en: 'Ghostfolio is a personal finance dashboard to keep track of your assets like stocks, ETFs or cryptocurrencies across multiple platforms.' |
||||
|
}; |
||||
|
|
||||
|
// TODO
|
||||
|
const locales = { |
||||
|
'/en/blog/2022/08/500-stars-on-github': { |
||||
|
featureGraphicPath: 'assets/images/blog/500-stars-on-github.jpg', |
||||
|
title: `500 Stars - ${title}` |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const getPathOfIndexHtmlFile = (aLocale: string) => { |
||||
|
return join(__dirname, '..', 'client', aLocale, 'index.html'); |
||||
|
}; |
||||
|
|
||||
|
const isFileRequest = (filename: string) => { |
||||
|
if (filename === '/assets/LICENSE') { |
||||
|
return true; |
||||
|
} else if ( |
||||
|
filename.includes('auth/ey') || |
||||
|
filename.includes( |
||||
|
'personal-finance-tools/open-source-alternative-to-markets.sh' |
||||
|
) |
||||
|
) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
return filename.split('.').pop() !== filename; |
||||
|
}; |
||||
|
|
||||
|
export const StaticMiddleware = async ( |
||||
|
request: Request, |
||||
|
response: Response, |
||||
|
next: NextFunction |
||||
|
) => { |
||||
|
const path = request.originalUrl.replace(/\/$/, ''); |
||||
|
const languageCode = path.substr(1, 2); |
||||
|
|
||||
|
const currentDate = format(new Date(), DATE_FORMAT); |
||||
|
const rootUrl = 'https://ghostfol.io'; |
||||
|
|
||||
|
if ( |
||||
|
path.startsWith('/api/') || |
||||
|
isFileRequest(path) /*|| |
||||
|
!environment.production*/ |
||||
|
) { |
||||
|
// Skip
|
||||
|
next(); |
||||
|
} else if (SUPPORTED_LANGUAGE_CODES.includes(languageCode)) { |
||||
|
// TODO: Only load once
|
||||
|
const indexHtml = interpolate( |
||||
|
fs.readFileSync(getPathOfIndexHtmlFile(languageCode), 'utf8'), |
||||
|
{ |
||||
|
currentDate, |
||||
|
languageCode, |
||||
|
path, |
||||
|
rootUrl, |
||||
|
description: descriptions[languageCode], |
||||
|
featureGraphicPath: |
||||
|
locales[path]?.featureGraphicPath ?? 'assets/cover.png', |
||||
|
title: locales[path]?.title ?? title |
||||
|
} |
||||
|
); |
||||
|
|
||||
|
return response.send(indexHtml); |
||||
|
} else { |
||||
|
// TODO
|
||||
|
} |
||||
|
}; |
@ -1,63 +0,0 @@ |
|||||
<!DOCTYPE html> |
|
||||
<html class="h-100 position-relative" lang="${languageCode}"> |
|
||||
<head> |
|
||||
<title>${title}</title> |
|
||||
<base href="/" /> |
|
||||
<meta charset="utf-8" /> |
|
||||
<meta content="yes" name="apple-mobile-web-app-capable" /> |
|
||||
<meta content="${description}" name="description" /> |
|
||||
<meta |
|
||||
content="app, asset, cryptocurrency, dashboard, etf, finance, management, performance, portfolio, software, stock, trading, wealth, web3" |
|
||||
name="keywords" |
|
||||
/> |
|
||||
<meta content="yes" name="mobile-web-app-capable" /> |
|
||||
<meta content="summary_large_image" name="twitter:card" /> |
|
||||
<meta |
|
||||
content="Ghostfolio is a personal finance dashboard to keep track of your assets like stocks, ETFs or cryptocurrencies" |
|
||||
name="twitter:description" |
|
||||
/> |
|
||||
<meta content="${rootUrl}/${featureGraphicPath}" name="twitter:image" /> |
|
||||
<meta content="${title}" name="twitter:title" /> |
|
||||
<meta |
|
||||
content="initial-scale=1, viewport-fit=cover, width=device-width" |
|
||||
name="viewport" |
|
||||
/> |
|
||||
<meta content="#FFFFFF" name="theme-color" /> |
|
||||
<meta content="" property="og:description" /> |
|
||||
<meta content="${title}" property="og:title" /> |
|
||||
<meta content="website" property="og:type" /> |
|
||||
<meta content="${rootUrl}${path}" property="og:url" /> |
|
||||
<meta content="${rootUrl}/${featureGraphicPath}" property="og:image" /> |
|
||||
<meta content="${currentDate}T00:00:00+00:00" property="og:updated_time" /> |
|
||||
<meta content="${title}" property="og:site_name" /> |
|
||||
|
|
||||
<link |
|
||||
href="../assets/apple-touch-icon.png" |
|
||||
rel="apple-touch-icon" |
|
||||
sizes="180x180" |
|
||||
/> |
|
||||
<link |
|
||||
href="../assets/favicon-32x32.png" |
|
||||
rel="icon" |
|
||||
sizes="32x32" |
|
||||
type="image/png" |
|
||||
/> |
|
||||
<link |
|
||||
href="../assets/favicon-16x16.png" |
|
||||
rel="icon" |
|
||||
sizes="16x16" |
|
||||
type="image/png" |
|
||||
/> |
|
||||
<link href="../assets/site.webmanifest" rel="manifest" /> |
|
||||
</head> |
|
||||
<body> |
|
||||
<gf-root></gf-root> |
|
||||
|
|
||||
<script src="../ionicons/ionicons.esm.js" type="module"></script> |
|
||||
<script nomodule="" src="ionicons.js"></script> |
|
||||
|
|
||||
<noscript |
|
||||
>Please enable JavaScript to continue using this application.</noscript |
|
||||
> |
|
||||
</body> |
|
||||
</html> |
|
Loading…
Reference in new issue