def parseIndexYamlItems(yamlItems): result = '' for yamlItem in yamlItems: item = '<div class="[[ITEM_CLASSES]]">' itemClasses = ['devsite-landing-row-item'] descriptionClasses = ['devsite-landing-row-item-description'] link = None if 'path' in yamlItem: link = '<a href="' + yamlItem['path'] + '">' if 'icon' in yamlItem: if link: item += link if 'icon_name' in yamlItem['icon']: item += '<div class="devsite-landing-row-item-icon material-icons">' item += yamlItem['icon']['icon_name'] item += '</div>' descriptionClasses.append('devsite-landing-row-item-icon-description') if 'path' in yamlItem['icon']: item += '<img class="devsite-landing-row-item-icon" src="' item += yamlItem['icon']['path'] item += '">' descriptionClasses.append('devsite-landing-row-item-icon-description') if link: item += '</a>' if 'image_path' in yamlItem: imgClass = 'devsite-landing-row-item-image' if 'image_left' in yamlItem: imgClass += ' devsite-landing-row-item-image-left' item += '<img src="' + yamlItem['image_path'] + '" ' item += 'class="' + imgClass + '">' elif not 'youtube_id' in yamlItem: itemClasses.append('devsite-landing-row-item-no-image') if 'description' in yamlItem: item += '<div class="[[DESCRIPTION_CLASSES]]">' if 'heading' in yamlItem: if link: item += link item += '<h3 id="' + devsiteHelper.slugify(yamlItem['heading']) +'">' item += yamlItem['heading'] + '</h3>' # item += '<h3>' + yamlItem['heading'] + '</h3>' if link: item += '</a>' item += yamlItem['description'] if 'buttons' in yamlItem: item += '<div class="devsite-landing-row-item-buttons">' for button in yamlItem['buttons']: item += '<a href="' + button['path'] + '"' if 'classname' in button: item += ' class="' + button['classname'] + '"' else: item += ' class="button button-white"' item += '>' + button['label'] + '</a>' item += '</div>' item += '</div>' if 'custom_html' in yamlItem: item += devsiteHelper.renderDevSiteContent(yamlItem['custom_html']) if 'youtube_id' in yamlItem: item += '<div class="devsite-landing-row-item-youtube">' item += '<iframe class="devsite-embedded-youtube-video" ' item += 'frameborder="0" allowfullscreen ' item += 'src="//www.youtube.com/embed/' + yamlItem['youtube_id'] item += '?autohide=1&showinfo=0&enablejsapi=1">' item += '</iframe>' item += '</div>' item += '</div>' item = item.replace('[[ITEM_CLASSES]]', ' '.join(itemClasses)) item = item.replace('[[DESCRIPTION_CLASSES]]', ' '.join(descriptionClasses)) result += item return result
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'): body = '' parsedYaml = yaml.load(rawYaml) bookPath = parsedYaml['book_path'] bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) projectPath = parsedYaml['project_path'] page = parsedYaml['landing_page'] rows = page['rows'] title = 'Web' banner = devsiteHelper.getAnnouncementBanner(projectPath, lang) header = 'Generic Page Header Here' customCss = '' lowerTabs = devsiteHelper.getLowerTabs(bookYaml) if 'custom_css_path' in page: customCss = '<link rel="stylesheet" href="' customCss += page['custom_css_path'] customCss += '">' if 'header' in page: header = '<div class="devsite-collapsible-section">' header += '<div class="devsite-header-background devsite-full-site-width">' header += '<div class="devsite-product-id-row devsite-full-site-width">' if 'description' in page['header']: header += '<div class="devsite-product-description-row">' header += '<div class="devsite-product-description">' header += page['header']['description'] header += '</div></div>' if 'buttons' in page['header']: header += '<div class="devsite-product-button-row">' for button in page['header']['buttons']: header += '<a class="button" href="' header += button['path'] + '">' + button['label'] + '</a>' header += '</div>' header += '</div></div></div>' if 'name' in page['header']: title = page['header']['name'] for row in rows: sectionClass = ['devsite-landing-row'] section = '<section class="[[SECTION_CLASSES]]">' if 'classname' in row: sectionClass.append(row['classname']) numItems = None if 'columns' in row: numItems = len(row['columns']) elif 'items' in row: numItems = len(row['items']) if numItems: sectionClass.append('devsite-landing-row-' + str(numItems) + '-up') if 'heading' in row: section += '<h2 id="' + devsiteHelper.slugify( row['heading']) + '">' section += row['heading'] + '</h2>' if 'items' in row: section += '<div class="devsite-landing-row-group">' section += parseIndexYamlItems(row['items']) section += '</div>' if 'columns' in row: for column in row['columns']: section += '<div class="devsite-landing-row-column">' if 'items' in column: section += parseIndexYamlItems(column['items']) section += '</div>' section += '</section>' section = section.replace('[[SECTION_CLASSES]]', ' '.join(sectionClass)) body += section body = devsiteHelper.renderDevSiteContent(body, lang) return render( 'gae/home.tpl', { 'title': title, 'announcementBanner': banner, 'requestPath': requestPath, 'lowerTabs': lowerTabs, 'customcss': customCss, 'header': header, 'content': body, 'lang': lang, 'footerPromo': devsiteHelper.getFooterPromo(), 'footerLinks': devsiteHelper.getFooterLinkBox() })
def generateYaml(lang, requestPath, rawYaml): content = '' parsedYaml = yaml.load(rawYaml) page = parsedYaml['landing_page'] rows = page['rows'] title = 'Web' banner = devsiteHelper.getAnnouncementBanner(lang) header = 'Generic Page Header Here' customCss = '' if 'custom_css_path' in page: customCss = '<link rel="stylesheet" href="' customCss += page['custom_css_path'] customCss += '">' if 'header' in page: header = '<div class="devsite-collapsible-section">' header += '<div class="devsite-header-background devsite-full-site-width">' header += '<div class="devsite-product-id-row devsite-full-site-width">' if 'description' in page['header']: header += '<div class="devsite-product-description-row">' header += '<div class="devsite-product-description">' header += page['header']['description'] header += '</div></div>' if 'buttons' in page['header']: header += '<div class="devsite-product-button-row">' for button in page['header']['buttons']: header += '<a class="button" href="' header += button['path'] + '">' + button['label'] + '</a>' header += '</div>' header += '</div></div></div>' if 'name' in page['header']: title = page['header']['name'] for row in rows: sectionClass = ['devsite-landing-row'] section = '<section class="[[SECTION_CLASSES]]">' if 'classname' in row: sectionClass.append(row['classname']) numItems = None if 'columns' in row: numItems = len(row['columns']) elif 'items' in row: numItems = len(row['items']) if numItems: sectionClass.append('devsite-landing-row-' + str(numItems) + '-up') if 'heading' in row: section += '<h2 id="' + devsiteHelper.slugify(row['heading']) +'">' section += row['heading'] + '</h2>' if 'items' in row: section += parseIndexYamlItems(row['items']) if 'columns' in row: for column in row['columns']: section += '<div class="devsite-landing-row-column">' if 'items' in column: section += parseIndexYamlItems(column['items']) section += '</div>' section += '</section>' section = section.replace('[[SECTION_CLASSES]]', ' '.join(sectionClass)) content += section content = devsiteHelper.renderDevSiteContent(content, lang) text = render('gae/home.tpl', { 'title': title, 'announcementBanner': banner, 'requestPath': requestPath, 'customcss': customCss, 'header': header, 'content': content, 'lang': lang, 'footerPromo': devsiteHelper.getFooterPromo(), 'footerLinks': devsiteHelper.getFooterLinkBox() } ) return text
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 parse(requestPath, fileLocation, content, lang='en'): template = 'gae/article.tpl' ## Get the HTML tag htmlTag = re.search(r'<html.*?>', content) if htmlTag is None: log.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) dateUpdated = re.search(r"{# wf_updated_on:[ ]?(.*)[ ]?#}", content) if dateUpdated is None: dateUpdated = 'Unknown' else: dateUpdated = dateUpdated.group(1) # Remove any comments {# something #} body = re.sub(r'{#.+?#}', '', body) body = re.sub(r'{% comment %}.*?{% endcomment %}(?ms)', '', body) # Show warning for unsupported elements for tag in UNSUPPORTED_TAGS: if re.search(tag, body) 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>' body = re.sub(tag, replaceWith, body) # Show warning for template tags if re.search('{{', body) is not None: logging.warn(' - Warning: possible unescaped template tag') # Render any DevSite specific tags body = devsiteHelper.renderDevSiteContent(body, lang) # Read the page title title = re.search('<title>(.*?)</title>', head) if title is None: title = '** UNKNOWN TITLE **' else: title = title.group(1) if body.find('<h1>') == -1: body = '<h1 class="page-title">' + title + '</h1>\n\n' + body # Read the book.yaml file and generate the left hand nav bookPath = re.search('name=\"book_path\" value=\"(.*?)\"', head) if bookPath is None: logging.error('Unable to read book_path') leftNav = 'Book not found.' lowerTabs = '' else: bookPath = bookPath.group(1) bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) leftNav = devsiteHelper.getLeftNav(requestPath, bookYaml) lowerTabs = devsiteHelper.getLowerTabs(bookYaml) # Read the project.yaml file projectPath = re.search('name=\"project_path\" value=\"(.*?)\"', head) if bookPath is None: logging.error('Unable to read project_path') else: projectPath = projectPath.group(1) announcementBanner = devsiteHelper.getAnnouncementBanner( projectPath, lang) # Replaces <pre> tags with prettyprint enabled tags body = re.sub(r'^<pre>(?m)', r'<pre class="prettyprint">', body) # Checks if the page should be displayed in full width mode fullWidth = re.search('name=\"full_width\" value=\"true\"', head) if fullWidth is not None: template = 'gae/home.tpl' # # Build the table of contents & transform so it fits within DevSite toc = '- TOC NYI - ' # 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) 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 return render( template, { 'title': title, 'head': head, 'announcementBanner': announcementBanner, 'lowerTabs': lowerTabs, 'gitHubIssueUrl': gitHubIssueUrl, 'gitHubEditUrl': gitHubEditUrl, 'requestPath': requestPath.replace('/index', ''), 'leftNav': leftNav, 'content': body, 'toc': toc, 'dateUpdated': dateUpdated, 'lang': lang, 'footerPromo': devsiteHelper.getFooterPromo(), 'footerLinks': devsiteHelper.getFooterLinkBox() })
def parse(requestPath, fileLocation, rawYaml, lang='en'): body = '' parsedYaml = yaml.load(rawYaml) bookPath = parsedYaml['book_path'] bookYaml = devsiteHelper.parseBookYaml(bookPath, lang) projectPath = parsedYaml['project_path'] page = parsedYaml['landing_page'] rows = page['rows'] title = 'Web' if 'title' in parsedYaml: title = parsedYaml['title'] headerTitle = None description = 'Description pulled from <code>_project.yaml</code>' headerButtons = None banner = devsiteHelper.getAnnouncementBanner(projectPath, lang) customHeader = None customCSS = None lowerTabs = devsiteHelper.getLowerTabs(bookYaml) if len(lowerTabs) <= 1: lowerTabs = None if 'custom_css_path' in page: customCSS = '<link rel="stylesheet" href="' customCSS += page['custom_css_path'] customCSS += '">' if 'header' in page: if 'custom_html' in page['header']: customHeader = page['header']['custom_html'] else: if 'name' in page['header']: headerTitle = page['header']['name'] if 'description' in page['header']: description = page['header']['description'] if 'buttons' in page['header']: headerButtons = [] for button in page['header']['buttons']: headerButton = '<a class="button" href="' headerButton += button['path'] + '">' + button[ 'label'] + '</a>' headerButtons.append(headerButton) for row in rows: sectionClass = ['devsite-landing-row'] section = '<section class="[[SECTION_CLASSES]]">' if 'classname' in row: sectionClass.append(row['classname']) numItems = None if 'columns' in row: numItems = len(row['columns']) elif 'items' in row: numItems = len(row['items']) if numItems: sectionClass.append('devsite-landing-row-' + str(numItems) + '-up') if 'heading' in row: section += '<h2 id="' + devsiteHelper.slugify( row['heading']) + '">' section += row['heading'] + '</h2>' if 'description' in row: section += '<p class="devsite-landing-row-description">' section += row['description'] + '</p>' if 'items' in row: section += '<div class="devsite-landing-row-group">' section += parseIndexYamlItems(row['items']) section += '</div>' if 'columns' in row: section += '<div class="devsite-landing-row-group">' for column in row['columns']: section += '<div class="devsite-landing-row-column">' # if 'items' in column: section += parseIndexYamlItems([column]) section += '</div>' section += '</div>' section += '</section>' section = section.replace('[[SECTION_CLASSES]]', ' '.join(sectionClass)) body += section body = devsiteHelper.renderDevSiteContent(body, lang) return render( 'gae/home.tpl', { 'title': title, 'headerTitle': title, 'description': description, 'headerButtons': headerButtons, 'announcementBanner': banner, 'requestPath': requestPath, 'lowerTabs': lowerTabs, 'customCSS': customCSS, 'customHeader': customHeader, 'content': body, 'lang': lang, 'footerPromo': devsiteHelper.getFooterPromo(), 'footerLinks': devsiteHelper.getFooterLinkBox() })
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)