Skip to content

Commit

Permalink
Improved template support (google#5656)
Browse files Browse the repository at this point in the history
* Work in progress

* WIP

* WIP

* WIP

* left nav status icons

* lower tab higlighting

* remove errant logging

* custom_image support

* custom header support

* Remove dead code

* code cleanup

* support for devsite tags in index.yaml
  • Loading branch information
petele authored Jan 17, 2018
1 parent cf074d6 commit 0e005df
Show file tree
Hide file tree
Showing 34 changed files with 934 additions and 996 deletions.
38 changes: 25 additions & 13 deletions devsiteHelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,30 +285,42 @@ def buildLeftNav(bookYaml, lang='en'):
result = ''
for item in bookYaml:
if 'path' in item:
result += '<li class="devsite-nav-item">\n'
itemClass = 'devsite-nav-item'
if 'status' in item:
itemClass += ' devsite-nav-has-status devsite-nav-' + item['status']
result += '<li class="' + itemClass + '">\n'
result += '<a href="' + item['path'] + '" class="devsite-nav-title">\n'
result += '<span class="devsite-nav-text">'
result += '<span>' + cgi.escape(item['title']) + '</span>\n'
result += '</span>'
if 'status' in item:
result += '<span class="devsite-nav-icon-wrapper">'
result += '<span class="devsite-nav-icon material-icons"></span>'
result += '</span>'
result += '</a>\n'
result += '</li>\n'
elif 'heading' in item:
result += '<li class="devsite-nav-item devsite-nav-item-heading">\n';
result += '<span class="devsite-nav-title devsite-nav-title-no-path" ';
result += 'track-type="leftNav" track-name="expandNavSectionNoLink" ';
result += 'track-metadata-position="0">\n';
itemClass = 'devsite-nav-item devsite-nav-item-heading'
result += '<li class="' + itemClass + '">\n';
result += '<span class="devsite-nav-title devsite-nav-title-no-path">\n';
result += '<span>' + cgi.escape(item['heading']) + '</span>\n';
result += '</span>\n</li>\n';
elif 'section' in item:
# Sub-section
result += '<li class="devsite-nav-item devsite-nav-item-section-expandable">\n'
result += '<span class="devsite-nav-title devsite-nav-title-no-path" '
result += 'track-type="leftNav" track-name="expandNavSectionNoLink" '
result += 'track-metadata-position="0">\n'
itemClass = 'devsite-nav-item devsite-nav-item-section-expandable x'
if 'style' in item:
itemClass += ' devsite-nav-accordion'
if 'status' in item:
itemClass += ' devsite-nav-has-status devsite-nav-' + item['status']
result += '<li class="' + itemClass + '">\n'
result += '<span class="devsite-nav-title devsite-nav-title-no-path">\n'
result += '<span>' + cgi.escape(item['title']) + '</span>\n'
if 'status' in item:
result += '<span class="devsite-nav-icon-wrapper">'
result += '<span class="devsite-nav-icon material-icons"></span>'
result += '</span>'
result += '</span>'
result += '<a '
result += 'class="devsite-nav-toggle devsite-nav-toggle-collapsed material-icons" '
result += 'track-type="leftNav" track-name="expandNavSectionArrow" '
result += 'track-metadata-position="0">\n'
result += '<a class="devsite-nav-toggle devsite-nav-toggle-collapsed material-icons">\n'
result += '</a>'
result += '<ul class="devsite-nav-section devsite-nav-section-collapsed">\n'
result += buildLeftNav(item['section'])
Expand Down
70 changes: 0 additions & 70 deletions devsiteIndex.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,73 +44,3 @@ def getDirIndex(requestPath):
link = os.path.join('/web', requestPath, os.path.splitext(f)[0])
result += '<li><a href="' + link + '">' + link + '</a></li>'
return result


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>'
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
140 changes: 65 additions & 75 deletions devsiteParseHTML.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import os
import re
import yaml
import logging
import devsiteHelper
from google.appengine.ext.webapp.template import render

SOURCE_PATH = os.path.join(os.path.dirname(__file__), 'src/content/')
UNSUPPORTED_TAGS = [
r'{% link_sample_button .+%}',
r'{% include_code (.+)%}'
]


def parse(requestPath, fileLocation, content, lang='en'):
template = 'gae/article.tpl'
context = {
'lang': lang,
'requestPath': requestPath.replace('/index', ''),
'bodyClass': 'devsite-doc-page'
}

## Get the HTML tag
htmlTag = re.search(r'<html.*?>', content)
Expand All @@ -34,103 +36,91 @@ def parse(requestPath, fileLocation, content, lang='en'):
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 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)
if bookPath is None:
logging.error('Unable to read book_path')
leftNav = 'Book not found.'
lowerTabs = ''
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:
bookPath = bookPath.group(1)
bookYaml = devsiteHelper.parseBookYaml(bookPath, lang)
leftNav = devsiteHelper.getLeftNav(requestPath, bookYaml)
lowerTabs = devsiteHelper.getLowerTabs(bookYaml)
context['logoRowTitle'] = projectYaml['name']

# 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)
# 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">', 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 is not None:
template = 'gae/home.tpl'
if fullWidth:
context['fullWidth'] = True

# # 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)
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: ' + title + ' ['
gitHubIssueUrl += 'new?title=Feedback for: ' + context['pageTitle'] + ' ['
gitHubIssueUrl += lang + ']&body='
gitHubIssueUrl += gitHubEditUrl
context['gitHubIssueUrl'] = gitHubIssueUrl

# 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()
})
return render('gae/page-article.html', context)
Loading

0 comments on commit 0e005df

Please sign in to comment.