def parse(requestPath, fileLocation, content, lang='en'): context = { 'lang': lang, 'requestPath': requestPath.replace('/index', ''), 'bodyClass': 'devsite-doc-page', 'servedFromAppEngine': SERVED_FROM_AE } ## Get the HTML tag htmlTag = re.search(r'<html.*?>', content) if htmlTag is None: logging.warning('Does not contain <html> root element') else: htmlTag = htmlTag.group(0) # Check the HTML tag contains the devsite if htmlTag.find('devsite') == -1: return content # Isolate the <head> headStart = content.find('<head') headEnd = content.find('</head>') head = content[headStart:headEnd].strip() # Isolate the <body> bodyStart = content.find('<body') bodyEnd = content.rfind('</body>') body = content[bodyStart:bodyEnd].strip() body = re.sub(r'<body.*?>', '', body) # Remove any comments {# something #} body = re.sub(r'{#.+?#}', '', body) body = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', body) # Render any DevSite specific tags body = devsiteHelper.renderDevSiteContent(body, lang) # Read the project.yaml file projectPath = re.search('name=\"project_path\" value=\"(.*?)\"', head) projectPath = projectPath.group(1) projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang)) context['projectYaml'] = projectYaml # Read the parent project.yaml file if applicable parentProjectYaml = None if 'parent_project_metadata_path' in projectYaml: parentprojectPath = projectYaml['parent_project_metadata_path'] parentProjectYaml = yaml.load(devsiteHelper.readFile(parentprojectPath, lang)) # Read the book.yaml file and generate the left hand nav bookPath = re.search('name=\"book_path\" value=\"(.*?)\"', head) bookPath = bookPath.group(1) bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) context['bookYaml'] = devsiteHelper.expandBook(bookYaml) context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml) context['renderedLeftNav'] = devsiteHelper.getLeftNav(requestPath, bookYaml) # Get the logo row (TOP ROW) icon context['logoRowIcon'] = projectYaml['icon']['path'] # Get the logo row (TOP ROW) title if parentProjectYaml: context['logoRowTitle'] = parentProjectYaml['name'] else: context['logoRowTitle'] = projectYaml['name'] # Get the header title & description context['headerTitle'] = projectYaml['name'] # headerDescription is rarely shown, hiding temporarily # context['headerDescription'] = projectYaml['description'] # Read the page title pageTitle = [] titleRO = re.search('<title>(.*?)</title>', head) if titleRO: title = titleRO.group(1) pageTitle.append(title) if body.find('<h1>') == -1: body = '<h1 class="page-title">' + title + '</h1>\n\n' + body pageTitle.append(projectYaml['name']) pageTitle.append('WebFu Staging') context['pageTitle'] = ' | '.join(pageTitle) # Get the footer path & read/parse the footer file. footerPath = projectYaml['footer_path'] footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer'] for item in footers: if 'promos' in item: context['footerPromos'] = item['promos'] elif 'linkboxes' in item: context['footerLinks'] = item['linkboxes'] # Replaces <pre> tags with prettyprint enabled tags body = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint devsite-code-highlight">', body) # Adds code highlighting support, which requires devsite-code-highlight body = re.sub(r'^<pre class="prettyprint">(?m)', r'<pre class="prettyprint devsite-code-highlight">', body) context['content'] = body # Checks if the page should be displayed in full width mode fullWidth = re.search('name=\"full_width\" value=\"true\"', head) if fullWidth: context['fullWidth'] = True # # Build the table of contents & transform so it fits within DevSite context['renderedTOC'] = '<b>TOC Not Implemented</b> for DevSite HTML Pages' gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/' gitHubEditUrl += 'master/src/content/' gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '') context['gitHubEditUrl'] = gitHubEditUrl gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/' gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' [' gitHubIssueUrl += lang + ']&body=' gitHubIssueUrl += gitHubEditUrl context['gitHubIssueUrl'] = gitHubIssueUrl # Renders the content into the template return render('gae/page-article.html', context)
def parse(requestPath, fileLocation, content, lang='en'): context = { 'lang': lang, 'requestPath': requestPath.replace('/index', ''), 'bodyClass': 'devsite-doc-page', 'servedFromAppEngine': SERVED_FROM_AE } ## Get the HTML tag htmlTag = re.search(r'<html.*?>', content) if htmlTag is None: logging.warning('Does not contain <html> root element') else: htmlTag = htmlTag.group(0) # Check the HTML tag contains the devsite if htmlTag.find('devsite') == -1: return content # Isolate the <head> headStart = content.find('<head') headEnd = content.find('</head>') head = content[headStart:headEnd].strip() # Isolate the <body> bodyStart = content.find('<body') bodyEnd = content.rfind('</body>') body = content[bodyStart:bodyEnd].strip() body = re.sub(r'<body.*?>', '', body) # Remove any comments {# something #} body = re.sub(r'{#.+?#}', '', body) body = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', body) # Render any DevSite specific tags body = devsiteHelper.renderDevSiteContent(body, lang) # Read the project.yaml file projectPath = re.search('name=\"project_path\" value=\"(.*?)\"', head) projectPath = projectPath.group(1) projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang)) context['projectYaml'] = projectYaml # Read the parent project.yaml file if applicable parentProjectYaml = None if 'parent_project_metadata_path' in projectYaml: parentprojectPath = projectYaml['parent_project_metadata_path'] parentProjectYaml = yaml.load( devsiteHelper.readFile(parentprojectPath, lang)) # Read the book.yaml file and generate the left hand nav bookPath = re.search('name=\"book_path\" value=\"(.*?)\"', head) bookPath = bookPath.group(1) bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) context['bookYaml'] = devsiteHelper.expandBook(bookYaml) context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml) context['renderedLeftNav'] = devsiteHelper.getLeftNav( requestPath, bookYaml) # Get the logo row (TOP ROW) icon context['logoRowIcon'] = projectYaml['icon']['path'] # Get the logo row (TOP ROW) title if parentProjectYaml: context['logoRowTitle'] = parentProjectYaml['name'] else: context['logoRowTitle'] = projectYaml['name'] # Get the header title & description context['headerTitle'] = projectYaml['name'] # headerDescription is rarely shown, hiding temporarily # context['headerDescription'] = projectYaml['description'] # Read the page title pageTitle = [] titleRO = re.search('<title>(.*?)</title>', head) if titleRO: title = titleRO.group(1) pageTitle.append(title) if body.find('<h1>') == -1: body = '<h1 class="page-title">' + title + '</h1>\n\n' + body pageTitle.append(projectYaml['name']) pageTitle.append('WebFu Staging') context['pageTitle'] = ' | '.join(pageTitle) # Get the footer path & read/parse the footer file. footerPath = projectYaml['footer_path'] footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer'] for item in footers: if 'promos' in item: context['footerPromos'] = item['promos'] elif 'linkboxes' in item: context['footerLinks'] = item['linkboxes'] # Replaces <pre> tags with prettyprint enabled tags body = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint devsite-code-highlight">', body) # Adds code highlighting support, which requires devsite-code-highlight body = re.sub(r'^<pre class="prettyprint">(?m)', r'<pre class="prettyprint devsite-code-highlight">', body) context['content'] = body # Checks if the page should be displayed in full width mode fullWidth = re.search('name=\"full_width\" value=\"true\"', head) if fullWidth: context['fullWidth'] = True # # Build the table of contents & transform so it fits within DevSite context[ 'renderedTOC'] = '<b>TOC Not Implemented</b> for DevSite HTML Pages' gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/' gitHubEditUrl += 'main/src/content/' gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '') context['gitHubEditUrl'] = gitHubEditUrl gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/' gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' [' gitHubIssueUrl += lang + ']&body=' gitHubIssueUrl += gitHubEditUrl context['gitHubIssueUrl'] = gitHubIssueUrl # Renders the content into the template return render('gae/page-article.html', context)
def getPage(requestPath, lang): response = None title = 'Web Fundamentals' leftNav = '- No Left Nav Found - ' toc = '- No TOC Found - ' banner = devsiteHelper.getAnnouncementBanner(lang) template = 'gae/article.tpl' fileLocations = [ os.path.join(SOURCE_PATH, lang, requestPath) + '.md', os.path.join(SOURCE_PATH, 'en', requestPath) + '.md', os.path.join(SOURCE_PATH, lang, requestPath) + '.jshtml', os.path.join(SOURCE_PATH, 'en', requestPath) + '.jshtml', ] for fileLocation in fileLocations: if os.path.isfile(fileLocation): content = open(fileLocation, 'r').read() content = content.decode('utf8') # If it's a .jshtml file, just serve it. if fileLocation.endswith('.jshtml'): return content dateUpdated = re.search(r"{# wf_updated_on:[ ]?(.*)[ ]?#}", content) if dateUpdated is None: logging.warn('Missing wf_updated_on tag.') dateUpdated = 'Unknown' else: dateUpdated = dateUpdated.group(1) ## Injects markdown includes into the markdown as appropriate includes = re.findall(r'^<<.+?\.md>>(?m)', content) for includeTag in includes: fileName = includeTag.replace('<<', '').replace('>>', '') fileName = os.path.join(os.path.dirname(fileLocation), fileName) include = devsiteHelper.readFile(fileName, lang) if include is None: include = 'Warning: Unable to find included markdown file.\n\n' content = content.replace(includeTag, include) # Remove any comments {# something #} from the markdown content = re.sub(r'{#.+?#}', '', content) content = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', content) # Show warning for unsupported elements for tag in UNSUPPORTED_TAGS: if re.search(tag, content) is not None: logging.error(' - Unsupported tag: ' + tag) replaceWith = '<aside class="warning">Web<strong>Fundamentals</strong>: ' replaceWith += '<span>Unsupported tag: <code>' + tag + '</code></span></aside>' content = re.sub(tag, replaceWith, content) # Show warning for template tags if re.search('{{', content) is not None: logging.warn(' - Warning: possible unescaped template tag') # Render any DevSite specific tags content = devsiteHelper.renderDevSiteContent(content, lang) # If it's a markdown file, parse it to HTML if fileLocation.endswith('.md'): content = re.sub(r'^Success: (.*?)\n^\n(?ms)', r'<aside class="success" markdown="1"><strong>Success:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Dogfood: (.*?)\n^\n(?ms)', r'<aside class="dogfood" markdown="1"><strong>Dogfood:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Note: (.*?)\n^\n(?ms)', r'<aside class="note" markdown="1"><strong>Note:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Caution: (.*?)\n^\n(?ms)', r'<aside class="caution" markdown="1"><strong>Caution:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Warning: (.*?)\n^\n(?ms)', r'<aside class="warning" markdown="1"><strong>Warning:</strong> <span>\1</span></aside>', content) # Adds a set of markdown extensions available to us on DevSite ext = [ 'markdown.extensions.attr_list', # Adds support for {: #someid } 'markdown.extensions.meta', # Removes the meta data from the top of the doc 'markdown.extensions.toc', # Generate the TOC for the right side 'markdown.extensions.tables', # Support for Markdown Tables 'markdown.extensions.extra', # Support for markdown='1' in tags 'markdown.extensions.def_list' # Support for definition lists ] md = markdown.Markdown(extensions=ext) content = md.convert(content) # Reads the book.yaml file and generate the lefthand nav if 'book_path' in md.Meta and len(md.Meta['book_path']) == 1: bookPath = md.Meta['book_path'][0] leftNav = devsiteHelper.getLeftNav(requestPath, bookPath, lang) # Checks if the page should be displayed in full width mode if 'full_width' in md.Meta and len(md.Meta['full_width']) == 1: fullWidth = md.Meta['full_width'][0] if fullWidth.lower().strip() == 'true': template = 'gae/home.tpl' # Build the table of contents & transform so it fits within DevSite toc = md.toc toc = toc.strip() # Strips the outer wrapper and the page title from the doc toc = re.sub(r'<div class="toc">(.*?<ul>){2}(?s)', '', toc) toc = re.sub(r'</ul>\s*</li>\s*</ul>\s*</div>(?s)', '', toc) # Add appropriate classes toc = re.sub(r'<ul>', '<ul class="devsite-page-nav-list">', toc) toc = re.sub(r'<a href', '<a class="devsite-nav-title" href', toc) toc = re.sub(r'<li>', '<li class="devsite-nav-item">', toc) # Replaces <pre> tags with prettyprint enabled tags content = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint">', content) # Get the page title from the markup. titleRO = re.search(r'<h1 class="page-title".*?>(.*?)<\/h1>', content) if titleRO: title = titleRO.group(1) gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/' gitHubEditUrl += 'master/src/content/' gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '') gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/' gitHubIssueUrl += 'new?title=Feedback for: ' + title + ' [' gitHubIssueUrl += lang + ']&body=' gitHubIssueUrl += gitHubEditUrl # Renders the content into the template response = render(template, { 'title': title, 'announcementBanner': banner, 'gitHubIssueUrl': gitHubIssueUrl, 'gitHubEditUrl': gitHubEditUrl, 'requestPath': requestPath.replace('index', ''), 'leftNav': leftNav, 'content': content, 'toc': toc, 'dateUpdated': dateUpdated, 'lang': lang} ) break return response
def parse(requestPath, fileLocation, content, lang='en'): context = { 'lang': lang, 'requestPath': requestPath.replace('/index', ''), 'bodyClass': 'devsite-doc-page', 'servedFromAppEngine': SERVED_FROM_AE } ## Injects markdown includes into the markdown as appropriate includes = re.findall(r'^<<.+?\.md>>(?m)', content) for includeTag in includes: fileName = includeTag.replace('<<', '').replace('>>', '') fileName = os.path.join(os.path.dirname(fileLocation), fileName) include = devsiteHelper.readFile(fileName, lang) if include is None: include = 'Warning: Unable to find included markdown file.\n\n' content = content.replace(includeTag, include) # Remove any comments {# something #} content = re.sub(r'{#.+?#}', '', content) content = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', content) # Remove any markdown=1 since it's not supported content = re.sub(r'markdown=[\'\"]?1[\'\"]?', '', content) # Render any DevSite specific tags content = devsiteHelper.renderDevSiteContent(content, lang) # Turn Callouts into the appropriate HTML elements content = re.sub( r'^Note: (.*?)\n^\n(?ms)', r'<aside class="note" markdown="1"><strong>Note:</strong> <span>\1</span></aside>', content) content = re.sub( r'^Caution: (.*?)\n^\n(?ms)', r'<aside class="caution" markdown="1"><strong>Caution:</strong> <span>\1</span></aside>', content) content = re.sub( r'^Warning: (.*?)\n^\n(?ms)', r'<aside class="warning" markdown="1"><strong>Warning:</strong> <span>\1</span></aside>', content) content = re.sub( r'^Key Point: (.*?)\n^\n(?ms)', r'<aside class="key-point" markdown="1"><strong>Key Point:</strong> <span>\1</span></aside>', content) content = re.sub( r'^Key Term: (.*?)\n^\n(?ms)', r'<aside class="key-term" markdown="1"><strong>Key Term:</strong> <span>\1</span></aside>', content) content = re.sub( r'^Objective: (.*?)\n^\n(?ms)', r'<aside class="objective" markdown="1"><strong>Objective:</strong> <span>\1</span></aside>', content) content = re.sub( r'^Success: (.*?)\n^\n(?ms)', r'<aside class="success" markdown="1"><strong>Success:</strong> <span>\1</span></aside>', content) content = re.sub( r'^Dogfood: (.*?)\n^\n(?ms)', r'<aside class="dogfood" markdown="1"><strong>Dogfood:</strong> <span>\1</span></aside>', content) # Adds a set of markdown extensions available to us on DevSite ext = [ 'markdown.extensions.attr_list', # Adds support for {: #someid } 'markdown.extensions.meta', # Removes the meta data from the top of the doc 'markdown.extensions.toc', # Generate the TOC for the right side 'markdown.extensions.tables', # Support for Markdown Tables 'markdown.extensions.def_list', # Support for definition lists 'markdown.extensions.extra' # ] md = markdown.Markdown(extensions=ext) content = md.convert(content) # Replaces <pre> tags with prettyprint enabled tags content = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint devsite-code-highlight">', content) # Adds code highlighting support, which requires devsite-code-highlight content = re.sub(r'^<pre class="prettyprint">(?m)', r'<pre class="prettyprint devsite-code-highlight">', content) # Save the content context['content'] = content # Get the project_path and read/parse the project file. projectPath = md.Meta['project_path'][0] projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang)) context['projectYaml'] = projectYaml # Read the parent project.yaml file if applicable parentProjectYaml = None if 'parent_project_metadata_path' in projectYaml: parentprojectPath = projectYaml['parent_project_metadata_path'] parentProjectYaml = yaml.load( devsiteHelper.readFile(parentprojectPath, lang)) # Reads the book.yaml file and generate the lefthand nav bookPath = md.Meta['book_path'][0] bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) context['bookYaml'] = devsiteHelper.expandBook(bookYaml) # context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml) context['renderedLeftNav'] = devsiteHelper.getLeftNav( requestPath, bookYaml) lowerTabs = devsiteHelper.getLowerTabs(bookYaml) context['lowerTabs'] = lowerTabs # Get the logo row (TOP ROW) icon context['logoRowIcon'] = projectYaml['icon']['path'] # Get the logo row (TOP ROW) title if parentProjectYaml: context['logoRowTitle'] = parentProjectYaml['name'] else: context['logoRowTitle'] = projectYaml['name'] # Get the header title & description context['headerTitle'] = projectYaml['name'] # headerDescription is rarely shown, hiding temporarily # context['headerDescription'] = projectYaml['description'] # Get the page title pageTitle = [] titleRO = re.search(r'<h1 class="page-title".*?>(.*?)<\/h1>', content) if titleRO: pageTitle.append(titleRO.group(1)) pageTitle.append(projectYaml['name']) pageTitle.append('WebFu Staging') context['pageTitle'] = ' | '.join(pageTitle) # Get the footer path & read/parse the footer file. footerPath = projectYaml['footer_path'] footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer'] for item in footers: if 'promos' in item: context['footerPromos'] = item['promos'] elif 'linkboxes' in item: context['footerLinks'] = item['linkboxes'] if 'full_width' in md.Meta and len(md.Meta['full_width']) == 1: context['fullWidth'] = True # Build the table of contents & transform so it fits within DevSite toc = md.toc toc = toc.strip() # Strips the outer wrapper and the page title from the doc toc = re.sub(r'<div class="toc">(.*?<ul>){2}(?s)', '', toc) toc = re.sub(r'</ul>\s*</li>\s*</ul>\s*</div>(?s)', '', toc) # Add appropriate classes toc = re.sub(r'<ul>', '<ul class="devsite-page-nav-list">', toc) toc = re.sub(r'<a href', '<a class="devsite-nav-title" href', toc) toc = re.sub(r'<li>', '<li class="devsite-nav-item">', toc) context['renderedTOC'] = toc gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/' gitHubEditUrl += 'main/src/content/' gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '') context['gitHubEditUrl'] = gitHubEditUrl gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/' gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' [' gitHubIssueUrl += lang + ']&body=' gitHubIssueUrl += gitHubEditUrl context['gitHubIssueUrl'] = gitHubIssueUrl return render('gae/page-article.html', context)
def parse(requestPath, fileLocation, rawYaml, lang='en'): context = { 'lang': lang, 'requestPath': requestPath.replace('/index', ''), 'bodyClass': 'devsite-landing-page', 'servedFromAppEngine': SERVED_FROM_AE } # Parse the Yaml parsedYaml = yaml.load(rawYaml) page = parsedYaml['landing_page'] if 'body_class' in page: context['bodyClass'] += ' ' + page['body_class'] # Get the project_path and read/parse the project file. projectPath = parsedYaml['project_path'] projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang)) context['projectYaml'] = projectYaml # Read the parent project.yaml file if applicable parentProjectYaml = None if 'parent_project_metadata_path' in projectYaml: parentprojectPath = projectYaml['parent_project_metadata_path'] parentProjectYaml = yaml.load(devsiteHelper.readFile(parentprojectPath, lang)) # Get the book path and read/parse the book file, then add the lower tabs. bookPath = parsedYaml['book_path'] bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) context['bookYaml'] = devsiteHelper.expandBook(bookYaml) context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml) # Get the row or column count for each row for row in page['rows']: if 'items' in row: count = len(row['items']) row['itemCount'] = count for item in row['items']: if 'custom_html' in item: c = item['custom_html'] item['custom_html'] = devsiteHelper.renderDevSiteContent(c, lang) elif 'columns' in row: count = len(row['columns']) row['itemCount'] = count elif 'custom_html' in row: row['itemCount'] = 1 c = row['custom_html'] row['custom_html'] = devsiteHelper.renderDevSiteContent(c, lang) context['rows'] = page['rows'] # Get the custom CSS path if 'custom_css_path' in page: context['customCSSPath'] = page['custom_css_path'] # Get the logo row (TOP ROW) icon context['logoRowIcon'] = projectYaml['icon']['path'] # Get the logo row (TOP ROW) title if 'header' in page and 'name' in page['header']: context['logoRowTitle'] = page['header']['name'] elif parentProjectYaml: context['logoRowTitle'] = parentProjectYaml['name'] else: context['logoRowTitle'] = projectYaml['name'] # Get the custom_html for the header if appropriate if 'header' in page and 'custom_html' in page['header']: context['customHeader'] = page['header']['custom_html'] # Get the header title if 'parent_project_metadata_path' in projectYaml: context['headerTitle'] = projectYaml['name'] elif 'title' in parsedYaml: context['headerTitle'] = parsedYaml['title'] else: context['headerTitle'] = projectYaml['name'] # Get the header description if 'header' in page and 'description' in page['header']: context['headerDescription'] = page['header']['description'] else: context['headerDescription'] = projectYaml['description'] # Get the header buttons if 'header' in page and 'buttons' in page['header']: context['headerButtons'] = page['header']['buttons'] # Set the page title pageTitle = [] if 'title' in parsedYaml: pageTitle.append(parsedYaml['title']) pageTitle.append(projectYaml['name']) pageTitle.append('WebFu Staging') context['pageTitle'] = ' | '.join(pageTitle) # Get the footer path & read/parse the footer file. footerPath = projectYaml['footer_path'] footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer'] for item in footers: if 'promos' in item: context['footerPromos'] = item['promos'] elif 'linkboxes' in item: context['footerLinks'] = item['linkboxes'] return render('gae/page-landing.html', context)
def parse(requestPath, fileLocation, rawYaml, lang='en'): context = { 'lang': lang, 'requestPath': requestPath.replace('/index', ''), 'bodyClass': 'devsite-landing-page', 'servedFromAppEngine': SERVED_FROM_AE } # Parse the Yaml parsedYaml = yaml.load(rawYaml) page = parsedYaml['landing_page'] # Get the project_path and read/parse the project file. projectPath = parsedYaml['project_path'] projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang)) context['projectYaml'] = projectYaml # Read the parent project.yaml file if applicable parentProjectYaml = None if 'parent_project_metadata_path' in projectYaml: parentprojectPath = projectYaml['parent_project_metadata_path'] parentProjectYaml = yaml.load( devsiteHelper.readFile(parentprojectPath, lang)) # Get the book path and read/parse the book file, then add the lower tabs. bookPath = parsedYaml['book_path'] bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) context['bookYaml'] = devsiteHelper.expandBook(bookYaml) context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml) # Get the row or column count for each row for row in page['rows']: if 'items' in row: count = len(row['items']) row['itemCount'] = count for item in row['items']: if 'custom_html' in item: c = item['custom_html'] item['custom_html'] = devsiteHelper.renderDevSiteContent( c, lang) elif 'columns' in row: count = len(row['columns']) row['itemCount'] = count elif 'custom_html' in row: row['itemCount'] = 1 c = row['custom_html'] row['custom_html'] = devsiteHelper.renderDevSiteContent(c, lang) context['rows'] = page['rows'] # Get the custom CSS path if 'custom_css_path' in page: context['customCSSPath'] = page['custom_css_path'] # Get the logo row (TOP ROW) icon context['logoRowIcon'] = projectYaml['icon']['path'] # Get the logo row (TOP ROW) title if 'header' in page and 'name' in page['header']: context['logoRowTitle'] = page['header']['name'] elif parentProjectYaml: context['logoRowTitle'] = parentProjectYaml['name'] else: context['logoRowTitle'] = projectYaml['name'] # Get the custom_html for the header if appropriate if 'header' in page and 'custom_html' in page['header']: context['customHeader'] = page['header']['custom_html'] # Get the header title if 'parent_project_metadata_path' in projectYaml: context['headerTitle'] = projectYaml['name'] elif 'title' in parsedYaml: context['headerTitle'] = parsedYaml['title'] else: context['headerTitle'] = projectYaml['name'] # Get the header description if 'header' in page and 'description' in page['header']: context['headerDescription'] = page['header']['description'] else: context['headerDescription'] = projectYaml['description'] # Get the header buttons if 'header' in page and 'buttons' in page['header']: context['headerButtons'] = page['header']['buttons'] # Set the page title pageTitle = [] if 'title' in parsedYaml: pageTitle.append(parsedYaml['title']) pageTitle.append(projectYaml['name']) pageTitle.append('WebFu Staging') context['pageTitle'] = ' | '.join(pageTitle) # Get the footer path & read/parse the footer file. footerPath = projectYaml['footer_path'] footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer'] for item in footers: if 'promos' in item: context['footerPromos'] = item['promos'] elif 'linkboxes' in item: context['footerLinks'] = item['linkboxes'] return render('gae/page-landing.html', context)
def getPage(requestPath, lang): response = None title = "Web Fundamentals" leftNav = "- No Left Nav Found - " toc = "- No TOC Found - " banner = devsiteHelper.getAnnouncementBanner(lang) template = "gae/article.tpl" fileLocations = [ os.path.join(SOURCE_PATH, lang, requestPath) + ".md", os.path.join(SOURCE_PATH, "en", requestPath) + ".md", os.path.join(SOURCE_PATH, lang, requestPath) + ".jshtml", os.path.join(SOURCE_PATH, "en", requestPath) + ".jshtml", ] for fileLocation in fileLocations: if os.path.isfile(fileLocation): content = open(fileLocation, "r").read() content = content.decode("utf8") # If it's a .jshtml file, just serve it. if fileLocation.endswith(".jshtml"): return content dateUpdated = re.search(r"{# wf_updated_on:[ ]?(.*)[ ]?#}", content) if dateUpdated is None: logging.warn("Missing wf_updated_on tag.") dateUpdated = "Unknown" else: dateUpdated = dateUpdated.group(1) ## Injects markdown includes into the markdown as appropriate includes = re.findall(r"^<<.+?\.md>>(?m)", content) for includeTag in includes: fileName = includeTag.replace("<<", "").replace(">>", "") fileName = os.path.join(os.path.dirname(fileLocation), fileName) include = devsiteHelper.readFile(fileName, lang) if include is None: include = "Warning: Unable to find included markdown file.\n\n" content = content.replace(includeTag, include) # Remove any comments {# something #} from the markdown content = re.sub(r"{#.+?#}", "", content) content = re.sub(r"{% comment %}.*?{% endcomment %}(?ms)", "", content) # Show warning for unsupported elements for tag in UNSUPPORTED_TAGS: if re.search(tag, content) is not None: logging.error(" - Unsupported tag: " + tag) replaceWith = '<aside class="warning">Web<strong>Fundamentals</strong>: ' replaceWith += "<span>Unsupported tag: <code>" + tag + "</code></span></aside>" content = re.sub(tag, replaceWith, content) # Show warning for template tags if re.search("{{", content) is not None: logging.warn(" - Warning: possible unescaped template tag") # Render any DevSite specific tags content = devsiteHelper.renderDevSiteContent(content, lang) # If it's a markdown file, parse it to HTML if fileLocation.endswith(".md"): content = re.sub( r"^Note: (.*?)\n^\n(?ms)", r'<aside class="note" markdown="1"><strong>Note:</strong> <span>\1</span></aside>', content, ) content = re.sub( r"^Caution: (.*?)\n^\n(?ms)", r'<aside class="caution" markdown="1"><strong>Caution:</strong> <span>\1</span></aside>', content, ) content = re.sub( r"^Warning: (.*?)\n^\n(?ms)", r'<aside class="warning" markdown="1"><strong>Warning:</strong> <span>\1</span></aside>', content, ) content = re.sub( r"^Key Point: (.*?)\n^\n(?ms)", r'<aside class="key-point" markdown="1"><strong>Key Point:</strong> <span>\1</span></aside>', content, ) content = re.sub( r"^Key Term: (.*?)\n^\n(?ms)", r'<aside class="key-term" markdown="1"><strong>Key Term:</strong> <span>\1</span></aside>', content, ) content = re.sub( r"^Objective: (.*?)\n^\n(?ms)", r'<aside class="objective" markdown="1"><strong>Objective:</strong> <span>\1</span></aside>', content, ) content = re.sub( r"^Success: (.*?)\n^\n(?ms)", r'<aside class="success" markdown="1"><strong>Success:</strong> <span>\1</span></aside>', content, ) content = re.sub( r"^Dogfood: (.*?)\n^\n(?ms)", r'<aside class="dogfood" markdown="1"><strong>Dogfood:</strong> <span>\1</span></aside>', content, ) # Adds a set of markdown extensions available to us on DevSite ext = [ "markdown.extensions.attr_list", # Adds support for {: #someid } "markdown.extensions.meta", # Removes the meta data from the top of the doc "markdown.extensions.toc", # Generate the TOC for the right side "markdown.extensions.tables", # Support for Markdown Tables "markdown.extensions.extra", # Support for markdown='1' in tags "markdown.extensions.def_list", # Support for definition lists ] md = markdown.Markdown(extensions=ext) content = md.convert(content) # Reads the book.yaml file and generate the lefthand nav if "book_path" in md.Meta and len(md.Meta["book_path"]) == 1: bookPath = md.Meta["book_path"][0] leftNav = devsiteHelper.getLeftNav(requestPath, bookPath, lang) # Checks if the page should be displayed in full width mode if "full_width" in md.Meta and len(md.Meta["full_width"]) == 1: fullWidth = md.Meta["full_width"][0] if fullWidth.lower().strip() == "true": template = "gae/home.tpl" # Build the table of contents & transform so it fits within DevSite toc = md.toc toc = toc.strip() # Strips the outer wrapper and the page title from the doc toc = re.sub(r'<div class="toc">(.*?<ul>){2}(?s)', "", toc) toc = re.sub(r"</ul>\s*</li>\s*</ul>\s*</div>(?s)", "", toc) # Add appropriate classes toc = re.sub(r"<ul>", '<ul class="devsite-page-nav-list">', toc) toc = re.sub(r"<a href", '<a class="devsite-nav-title" href', toc) toc = re.sub(r"<li>", '<li class="devsite-nav-item">', toc) # Replaces <pre> tags with prettyprint enabled tags content = re.sub(r"^<pre>(?m)", r'<pre class="prettyprint">', content) # Get the page title from the markup. titleRO = re.search(r'<h1 class="page-title".*?>(.*?)<\/h1>', content) if titleRO: title = titleRO.group(1) gitHubEditUrl = "https://github.com/google/WebFundamentals/blob/" gitHubEditUrl += "master/src/content/" gitHubEditUrl += fileLocation.replace(SOURCE_PATH, "") gitHubIssueUrl = "https://github.com/google/WebFundamentals/issues/" gitHubIssueUrl += "new?title=Feedback for: " + title + " [" gitHubIssueUrl += lang + "]&body=" gitHubIssueUrl += gitHubEditUrl # Renders the content into the template response = render( template, { "title": title, "announcementBanner": banner, "gitHubIssueUrl": gitHubIssueUrl, "gitHubEditUrl": gitHubEditUrl, "requestPath": requestPath.replace("index", ""), "leftNav": leftNav, "content": content, "toc": toc, "dateUpdated": dateUpdated, "lang": lang, }, ) break return response
def parse(requestPath, fileLocation, content, lang='en'): context = { 'lang': lang, 'requestPath': requestPath.replace('/index', ''), 'bodyClass': 'devsite-doc-page', 'servedFromAppEngine': SERVED_FROM_AE } ## Injects markdown includes into the markdown as appropriate includes = re.findall(r'^<<.+?\.md>>(?m)', content) for includeTag in includes: fileName = includeTag.replace('<<', '').replace('>>', '') fileName = os.path.join(os.path.dirname(fileLocation), fileName) include = devsiteHelper.readFile(fileName, lang) if include is None: include = 'Warning: Unable to find included markdown file.\n\n' content = content.replace(includeTag, include) # Remove any comments {# something #} content = re.sub(r'{#.+?#}', '', content) content = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', content) # Remove any markdown=1 since it's not supported content = re.sub(r'markdown=[\'\"]?1[\'\"]?', '', content) # Render any DevSite specific tags content = devsiteHelper.renderDevSiteContent(content, lang) # Turn Callouts into the appropriate HTML elements content = re.sub(r'^Note: (.*?)\n^\n(?ms)', r'<aside class="note" markdown="1"><strong>Note:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Caution: (.*?)\n^\n(?ms)', r'<aside class="caution" markdown="1"><strong>Caution:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Warning: (.*?)\n^\n(?ms)', r'<aside class="warning" markdown="1"><strong>Warning:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Key Point: (.*?)\n^\n(?ms)', r'<aside class="key-point" markdown="1"><strong>Key Point:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Key Term: (.*?)\n^\n(?ms)', r'<aside class="key-term" markdown="1"><strong>Key Term:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Objective: (.*?)\n^\n(?ms)', r'<aside class="objective" markdown="1"><strong>Objective:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Success: (.*?)\n^\n(?ms)', r'<aside class="success" markdown="1"><strong>Success:</strong> <span>\1</span></aside>', content) content = re.sub(r'^Dogfood: (.*?)\n^\n(?ms)', r'<aside class="dogfood" markdown="1"><strong>Dogfood:</strong> <span>\1</span></aside>', content) # Adds a set of markdown extensions available to us on DevSite ext = [ 'markdown.extensions.attr_list', # Adds support for {: #someid } 'markdown.extensions.meta', # Removes the meta data from the top of the doc 'markdown.extensions.toc', # Generate the TOC for the right side 'markdown.extensions.tables', # Support for Markdown Tables 'markdown.extensions.def_list', # Support for definition lists 'markdown.extensions.extra' # ] md = markdown.Markdown(extensions=ext) content = md.convert(content) # Replaces <pre> tags with prettyprint enabled tags content = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint devsite-code-highlight">', content) # Adds code highlighting support, which requires devsite-code-highlight content = re.sub(r'^<pre class="prettyprint">(?m)', r'<pre class="prettyprint devsite-code-highlight">', content) # Save the content context['content'] = content # Get the project_path and read/parse the project file. projectPath = md.Meta['project_path'][0] projectYaml = yaml.load(devsiteHelper.readFile(projectPath, lang)) context['projectYaml'] = projectYaml # Read the parent project.yaml file if applicable parentProjectYaml = None if 'parent_project_metadata_path' in projectYaml: parentprojectPath = projectYaml['parent_project_metadata_path'] parentProjectYaml = yaml.load(devsiteHelper.readFile(parentprojectPath, lang)) # Reads the book.yaml file and generate the lefthand nav bookPath = md.Meta['book_path'][0] bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) context['bookYaml'] = devsiteHelper.expandBook(bookYaml) # context['lowerTabs'] = devsiteHelper.getLowerTabs(bookYaml) context['renderedLeftNav'] = devsiteHelper.getLeftNav(requestPath, bookYaml) lowerTabs = devsiteHelper.getLowerTabs(bookYaml) context['lowerTabs'] = lowerTabs # Get the logo row (TOP ROW) icon context['logoRowIcon'] = projectYaml['icon']['path'] # Get the logo row (TOP ROW) title if parentProjectYaml: context['logoRowTitle'] = parentProjectYaml['name'] else: context['logoRowTitle'] = projectYaml['name'] # Get the header title & description context['headerTitle'] = projectYaml['name'] # headerDescription is rarely shown, hiding temporarily # context['headerDescription'] = projectYaml['description'] # Get the page title pageTitle = [] titleRO = re.search(r'<h1 class="page-title".*?>(.*?)<\/h1>', content) if titleRO: pageTitle.append(titleRO.group(1)) pageTitle.append(projectYaml['name']) pageTitle.append('WebFu Staging') context['pageTitle'] = ' | '.join(pageTitle) # Get the footer path & read/parse the footer file. footerPath = projectYaml['footer_path'] footers = yaml.load(devsiteHelper.readFile(footerPath, lang))['footer'] for item in footers: if 'promos' in item: context['footerPromos'] = item['promos'] elif 'linkboxes' in item: context['footerLinks'] = item['linkboxes'] if 'full_width' in md.Meta and len(md.Meta['full_width']) == 1: context['fullWidth'] = True # Build the table of contents & transform so it fits within DevSite toc = md.toc toc = toc.strip() # Strips the outer wrapper and the page title from the doc toc = re.sub(r'<div class="toc">(.*?<ul>){2}(?s)', '', toc) toc = re.sub(r'</ul>\s*</li>\s*</ul>\s*</div>(?s)', '', toc) # Add appropriate classes toc = re.sub(r'<ul>', '<ul class="devsite-page-nav-list">', toc) toc = re.sub(r'<a href', '<a class="devsite-nav-title" href', toc) toc = re.sub(r'<li>', '<li class="devsite-nav-item">', toc) context['renderedTOC'] = toc; gitHubEditUrl = 'https://github.com/google/WebFundamentals/blob/' gitHubEditUrl += 'master/src/content/' gitHubEditUrl += fileLocation.replace(SOURCE_PATH, '') context['gitHubEditUrl'] = gitHubEditUrl gitHubIssueUrl = 'https://github.com/google/WebFundamentals/issues/' gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' [' gitHubIssueUrl += lang + ']&body=' gitHubIssueUrl += gitHubEditUrl context['gitHubIssueUrl'] = gitHubIssueUrl return render('gae/page-article.html', context)