mirror of
				https://github.com/gristlabs/grist-core.git
				synced 2025-06-13 20:53:59 +00:00 
			
		
		
		
	(core) Populate doc title, description and thumbnail in app.html
Summary: Fills in the title and description/thumbnail (for templates) in app.html if the page being requested is for a document. Test Plan: Tested manually. Reviewers: paulfitz Reviewed By: paulfitz Subscribers: dsagal Differential Revision: https://phab.getgrist.com/D3544
This commit is contained in:
		
							parent
							
								
									7078922a65
								
							
						
					
					
						commit
						c54dde3dba
					
				@ -128,6 +128,10 @@ function pagePanelsDoc(owner: IDisposableOwner, appModel: AppModel, appObj: App)
 | 
			
		||||
 | 
			
		||||
  // Set document title to strings like "DocName - Grist"
 | 
			
		||||
  owner.autoDispose(subscribe(pageModel.currentDocTitle, (use, docName) => {
 | 
			
		||||
    // If the document hasn't loaded yet, don't update the title; since the HTML document already has
 | 
			
		||||
    // a title element with the document's name, there's no need for further action.
 | 
			
		||||
    if (!pageModel.currentDoc.get()) { return; }
 | 
			
		||||
 | 
			
		||||
    document.title = `${docName}${getPageTitleSuffix(getGristConfig())}`;
 | 
			
		||||
  }));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ import {User} from './entity/User';
 | 
			
		||||
import {HomeDBManager} from './lib/HomeDBManager';
 | 
			
		||||
 | 
			
		||||
// Special public organization that contains examples and templates.
 | 
			
		||||
const TEMPLATES_ORG_DOMAIN = process.env.GRIST_ID_PREFIX ?
 | 
			
		||||
export const TEMPLATES_ORG_DOMAIN = process.env.GRIST_ID_PREFIX ?
 | 
			
		||||
  `templates-${process.env.GRIST_ID_PREFIX}` :
 | 
			
		||||
  'templates';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,14 @@
 | 
			
		||||
import {getPageTitleSuffix, GristLoadConfig, HideableUiElements, IHideableUiElement} from 'app/common/gristUrls';
 | 
			
		||||
import {getTagManagerSnippet} from 'app/common/tagManager';
 | 
			
		||||
import {Document} from 'app/common/UserAPI';
 | 
			
		||||
import {isAnonymousUser, RequestWithLogin} from 'app/server/lib/Authorizer';
 | 
			
		||||
import {RequestWithOrg} from 'app/server/lib/extractOrg';
 | 
			
		||||
import {GristServer} from 'app/server/lib/GristServer';
 | 
			
		||||
import {getSupportedEngineChoices} from 'app/server/lib/serverUtils';
 | 
			
		||||
import * as express from 'express';
 | 
			
		||||
import * as fse from 'fs-extra';
 | 
			
		||||
import jsesc from 'jsesc';
 | 
			
		||||
import * as handlebars from 'handlebars';
 | 
			
		||||
import * as path from 'path';
 | 
			
		||||
 | 
			
		||||
export interface ISendAppPageOptions {
 | 
			
		||||
@ -65,8 +68,10 @@ export function makeGristConfig(homeUrl: string|null, extra: Partial<GristLoadCo
 | 
			
		||||
export function makeMessagePage(staticDir: string) {
 | 
			
		||||
  return async (req: express.Request, resp: express.Response, message: any) => {
 | 
			
		||||
    const fileContent = await fse.readFile(path.join(staticDir, "message.html"), 'utf8');
 | 
			
		||||
    const content = fileContent
 | 
			
		||||
      .replace("<!-- INSERT MESSAGE -->", `<script>window.message = ${JSON.stringify(message)};</script>`);
 | 
			
		||||
    const content = fileContent.replace(
 | 
			
		||||
      "<!-- INSERT MESSAGE -->",
 | 
			
		||||
      `<script>window.message = ${jsesc(message, {isScriptContext: true, json: true})};</script>`
 | 
			
		||||
    );
 | 
			
		||||
    resp.status(200).type('html').send(content);
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@ -98,10 +103,15 @@ export function makeSendAppPage(opts: {
 | 
			
		||||
    const warning = testLogin ? "<div class=\"dev_warning\">Authentication is not enforced</div>" : "";
 | 
			
		||||
    const content = fileContent
 | 
			
		||||
      .replace("<!-- INSERT WARNING -->", warning)
 | 
			
		||||
      .replace("<!-- INSERT TITLE -->", getPageTitle(config))
 | 
			
		||||
      .replace("<!-- INSERT META -->", getPageMetadataHtmlSnippet(config))
 | 
			
		||||
      .replace("<!-- INSERT TITLE SUFFIX -->", getPageTitleSuffix(server?.getGristConfig()))
 | 
			
		||||
      .replace("<!-- INSERT BASE -->", `<base href="${staticBaseUrl}">` + tagManagerSnippet)
 | 
			
		||||
      .replace("<!-- INSERT CUSTOM -->", customHeadHtmlSnippet)
 | 
			
		||||
      .replace("<!-- INSERT CONFIG -->", `<script>window.gristConfig = ${JSON.stringify(config)};</script>`);
 | 
			
		||||
      .replace(
 | 
			
		||||
        "<!-- INSERT CONFIG -->",
 | 
			
		||||
        `<script>window.gristConfig = ${jsesc(config, {isScriptContext: true, json: true})};</script>`
 | 
			
		||||
      );
 | 
			
		||||
    resp.status(options.status).type('html').send(content);
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@ -123,3 +133,51 @@ function configuredPageTitleSuffix() {
 | 
			
		||||
  const result = process.env.GRIST_PAGE_TITLE_SUFFIX;
 | 
			
		||||
  return result === "_blank" ? "" : result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a page title suitable for inserting into an HTML title element.
 | 
			
		||||
 *
 | 
			
		||||
 * Currently returns the document name if the page being requested is for a document, or
 | 
			
		||||
 * a placeholder, "Loading...", that's updated in the client once the page has loaded.
 | 
			
		||||
 *
 | 
			
		||||
 * Note: The string returned is escaped and safe to insert into HTML.
 | 
			
		||||
 */
 | 
			
		||||
function getPageTitle(config: GristLoadConfig): string {
 | 
			
		||||
  const maybeDoc = getDocFromConfig(config);
 | 
			
		||||
  if (!maybeDoc) { return 'Loading...'; }
 | 
			
		||||
 | 
			
		||||
  return handlebars.Utils.escapeExpression(maybeDoc.name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a string representation of 0 or more HTML metadata elements.
 | 
			
		||||
 *
 | 
			
		||||
 * Currently includes the document description and thumbnail if the requested page is
 | 
			
		||||
 * for a document and the document has one set.
 | 
			
		||||
 *
 | 
			
		||||
 * Note: The string returned is escaped and safe to insert into HTML.
 | 
			
		||||
 */
 | 
			
		||||
function getPageMetadataHtmlSnippet(config: GristLoadConfig): string {
 | 
			
		||||
  const metadataElements: string[] = [];
 | 
			
		||||
  const maybeDoc = getDocFromConfig(config);
 | 
			
		||||
 | 
			
		||||
  const description = maybeDoc?.options?.description;
 | 
			
		||||
  if (description) {
 | 
			
		||||
    const content = handlebars.Utils.escapeExpression(description);
 | 
			
		||||
    metadataElements.push(`<meta name="description" content="${content}">`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const thumbnail = maybeDoc?.options?.icon;
 | 
			
		||||
  if (thumbnail) {
 | 
			
		||||
    const content = handlebars.Utils.escapeExpression(thumbnail);
 | 
			
		||||
    metadataElements.push(`<meta name="thumbnail" content="${content}">`);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return metadataElements.join('\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getDocFromConfig(config: GristLoadConfig): Document | null {
 | 
			
		||||
  if (!config.getDoc || !config.assignmentId) { return null; }
 | 
			
		||||
 | 
			
		||||
  return config.getDoc[config.assignmentId] ?? null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,7 @@
 | 
			
		||||
    "@types/fs-extra": "5.0.4",
 | 
			
		||||
    "@types/image-size": "0.0.29",
 | 
			
		||||
    "@types/js-yaml": "3.11.2",
 | 
			
		||||
    "@types/jsesc": "3.0.1",
 | 
			
		||||
    "@types/jsonwebtoken": "7.2.8",
 | 
			
		||||
    "@types/lodash": "4.14.117",
 | 
			
		||||
    "@types/lru-cache": "5.1.1",
 | 
			
		||||
@ -113,6 +114,7 @@
 | 
			
		||||
    "fs-extra": "7.0.0",
 | 
			
		||||
    "grain-rpc": "0.1.7",
 | 
			
		||||
    "grainjs": "1.0.2",
 | 
			
		||||
    "handlebars": "4.4.5",
 | 
			
		||||
    "highlight.js": "9.13.1",
 | 
			
		||||
    "http-proxy-agent": "5.0.0",
 | 
			
		||||
    "https-proxy-agent": "5.0.1",
 | 
			
		||||
@ -120,6 +122,7 @@
 | 
			
		||||
    "image-size": "0.6.3",
 | 
			
		||||
    "jquery": "2.2.1",
 | 
			
		||||
    "js-yaml": "3.12.0",
 | 
			
		||||
    "jsesc": "3.0.2",
 | 
			
		||||
    "jsonwebtoken": "8.3.0",
 | 
			
		||||
    "knockout": "3.5.0",
 | 
			
		||||
    "locale-currency": "0.0.2",
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
<meta charset="utf8">
 | 
			
		||||
<!-- INSERT META -->
 | 
			
		||||
 | 
			
		||||
<!-- INSERT BASE -->
 | 
			
		||||
 | 
			
		||||
@ -15,7 +16,7 @@
 | 
			
		||||
<link rel="stylesheet" href="icons/icons.css">
 | 
			
		||||
<!-- INSERT CUSTOM -->
 | 
			
		||||
 | 
			
		||||
<title>Loading...<!-- INSERT TITLE SUFFIX --></title>
 | 
			
		||||
<title><!-- INSERT TITLE --><!-- INSERT TITLE SUFFIX --></title>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
  <!-- INSERT WARNING -->
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										36
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								yarn.lock
									
									
									
									
									
								
							@ -3230,6 +3230,17 @@ gtoken@^5.0.4:
 | 
			
		||||
    google-p12-pem "^3.0.3"
 | 
			
		||||
    jws "^4.0.0"
 | 
			
		||||
 | 
			
		||||
handlebars@4.4.5:
 | 
			
		||||
  version "4.4.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.4.5.tgz#1b1f94f9bfe7379adda86a8b73fb570265a0dddd"
 | 
			
		||||
  integrity sha512-0Ce31oWVB7YidkaTq33ZxEbN+UDxMMgThvCe8ptgQViymL5DPis9uLdTA13MiRPhgvqyxIegugrP97iK3JeBHg==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    neo-async "^2.6.0"
 | 
			
		||||
    optimist "^0.6.1"
 | 
			
		||||
    source-map "^0.6.1"
 | 
			
		||||
  optionalDependencies:
 | 
			
		||||
    uglify-js "^3.1.4"
 | 
			
		||||
 | 
			
		||||
har-schema@^2.0.0:
 | 
			
		||||
  version "2.0.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
 | 
			
		||||
@ -4352,6 +4363,11 @@ minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.5:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
 | 
			
		||||
  integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
 | 
			
		||||
 | 
			
		||||
minimist@~0.0.1:
 | 
			
		||||
  version "0.0.10"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
 | 
			
		||||
  integrity sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==
 | 
			
		||||
 | 
			
		||||
minimist@~1.1.1:
 | 
			
		||||
  version "1.1.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8"
 | 
			
		||||
@ -4575,7 +4591,7 @@ negotiator@0.6.2:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
 | 
			
		||||
  integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
 | 
			
		||||
 | 
			
		||||
neo-async@^2.6.2:
 | 
			
		||||
neo-async@^2.6.0, neo-async@^2.6.2:
 | 
			
		||||
  version "2.6.2"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
 | 
			
		||||
  integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
 | 
			
		||||
@ -4820,6 +4836,14 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
 | 
			
		||||
  dependencies:
 | 
			
		||||
    wrappy "1"
 | 
			
		||||
 | 
			
		||||
optimist@^0.6.1:
 | 
			
		||||
  version "0.6.1"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
 | 
			
		||||
  integrity sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==
 | 
			
		||||
  dependencies:
 | 
			
		||||
    minimist "~0.0.1"
 | 
			
		||||
    wordwrap "~0.0.2"
 | 
			
		||||
 | 
			
		||||
os-browserify@~0.3.0:
 | 
			
		||||
  version "0.3.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
 | 
			
		||||
@ -6510,6 +6534,11 @@ typescript@4.7.4:
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
 | 
			
		||||
  integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
 | 
			
		||||
 | 
			
		||||
uglify-js@^3.1.4:
 | 
			
		||||
  version "3.16.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.3.tgz#94c7a63337ee31227a18d03b8a3041c210fd1f1d"
 | 
			
		||||
  integrity sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==
 | 
			
		||||
 | 
			
		||||
uid-safe@2.1.5, uid-safe@~2.1.5:
 | 
			
		||||
  version "2.1.5"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"
 | 
			
		||||
@ -6864,6 +6893,11 @@ winston@2.4.5:
 | 
			
		||||
    isstream "0.1.x"
 | 
			
		||||
    stack-trace "0.0.x"
 | 
			
		||||
 | 
			
		||||
wordwrap@~0.0.2:
 | 
			
		||||
  version "0.0.3"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
 | 
			
		||||
  integrity sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==
 | 
			
		||||
 | 
			
		||||
wrap-ansi@^5.1.0:
 | 
			
		||||
  version "5.1.0"
 | 
			
		||||
  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user