--- /dev/null
+{capture assign='pageTitle'}{$articleContent->title}{/capture}
+
+{capture assign='headContent'}
+ <script type="application/ld+json">
+ {
+ "@context": "http://schema.org",
+ "@type": "NewsArticle",
+ "mainEntityOfPage": "{$regularCanonicalURL}",
+ "headline": "{$articleContent->title}",
+ "datePublished": "{@$article->time|plainTime}",
+ "dateModified": "{@$article->time|plainTime}",
+ "description": "{@$articleContent->getFormattedTeaser()}",
+ "author": {
+ "@type": "Person",
+ "name": "{$article->username}"
+ },
+ "publisher": {
+ "@type": "Organization",
+ "name": "{PAGE_TITLE|language}",
+ "logo": {
+ "@type": "ImageObject",
+ "url": "{@$__wcf->getPath()}images/default-logo.png",{* @TODO *}
+ "width": 288,
+ "height": 40
+ }
+ }
+ {if $articleContent->getImage()}
+ ,"image": {
+ "@type": "ImageObject",
+ "url": "{$articleContent->getImage()->getThumbnailLink('large')}",
+ "width": {@$articleContent->getImage()->getThumbnailWidth('large')},
+ "height": {@$articleContent->getImage()->getThumbnailHeight('large')}
+ }
+ {/if}
+ }
+ </script>
+{/capture}
+
+{include file='ampHeader'}
+
+<article class="article">
+ <header class="articleHeader">
+ <h1 class="articleTitle">{$articleContent->title}</h1>
+ <h2 class="articleAuthor">{$article->username}</h2>
+ <time class="articleDate" datetime="{@$article->time|date:'c'}">{@$article->time|plainTime}</time>
+ </header>
+
+ {if $articleContent->getImage()}
+ <figure class="articleImage">
+ <amp-img src="{$articleContent->getImage()->getThumbnailLink('large')}" alt="{$articleContent->getImage()->altText}" height="{@$articleContent->getImage()->getThumbnailHeight('large')}" width="{@$articleContent->getImage()->getThumbnailWidth('large')}" layout="responsive"></amp-img>
+ {if $articleContent->getImage()->caption}
+ <figcaption>{$articleContent->getImage()->caption}</figcaption>
+ {/if}
+ </figure>
+ {/if}
+
+ {if $articleContent->teaser}
+ <div class="articleTeaser">
+ <p>{@$articleContent->getFormattedTeaser()}</p>
+ </div>
+ {/if}
+
+ <div class="articleContent">
+ {@$articleContent->getFormattedContent()}
+ </div>
+</article>
+
+{include file='ampFooter'}
--- /dev/null
+ </main>
+
+ <amp-sidebar id="sidebar" layout="nodisplay">
+ <button on="tap:sidebar.close">{lang}wcf.global.button.close{/lang}</button>
+
+ <h3>{lang}wcf.menu.page.navigation{/lang}</h3>
+ <ol>
+ {foreach from=$__wcf->getBoxHandler()->getBoxByIdentifier('com.woltlab.wcf.MainMenu')->getMenu()->getMenuItemNodeList() item=menuItemNode}
+ {if $menuItemNode->getDepth() == 1 || $menuItemNode->getParentNode()->isActiveNode()}
+ <li>
+ <a href="{$menuItemNode->getURL()}">{lang}{$menuItemNode->title}{/lang}</a>
+
+ {if $menuItemNode->hasChildren() && $menuItemNode->isActiveNode()}<ol>{else}</li>{/if}
+
+ {if !$menuItemNode->hasChildren() && $menuItemNode->isLastSibling()}
+ {@"</ol></li>"|str_repeat:$menuItemNode->getOpenParentNodes()}
+ {/if}
+ {/if}
+ {/foreach}
+ </ol>
+ <ol>
+ {foreach from=$__wcf->getBoxHandler()->getBoxByIdentifier('com.woltlab.wcf.FooterMenu')->getMenu()->getMenuItemNodeList() item=menuItemNode}
+ <li><a href="{$menuItemNode->getURL()}">{lang}{$menuItemNode->title}{/lang}</a></li>
+ {/foreach}
+ </ol>
+
+ <h3>{lang}wcf.menu.page.location{/lang}</h3>
+ <ol class="breadcrumbs">
+ {assign var=__breadcrumbsDepth value=0}
+ {foreach from=$__wcf->getBreadcrumbs() item=$breadcrumb}
+ <li><a href="{$breadcrumb->getURL()}">{$breadcrumb->getLabel()}</a></li>
+ {assign var=__breadcrumbsDepth value=$__breadcrumbsDepth + 1}
+ {/foreach}
+ </ol>
+ </amp-sidebar>
+
+ {if MODULE_COOKIE_POLICY_PAGE && !$__wcf->user->userID}
+ <amp-user-notification layout="nodisplay" id="cookie-policy-notice">
+ {lang}wcf.page.cookiePolicy.info{/lang}
+ <button on="tap:cookie-policy-notice.dismiss">{lang}wcf.global.button.close{/lang}</button>
+ </amp-user-notification>
+ {/if}
+
+ <footer class="footer">
+ <div class="copyright">{lang}wcf.page.copyright{/lang}</div>
+ </footer>
+ </body>
+</html>
--- /dev/null
+<!doctype html>
+<html amp lang="{@$__wcf->language->getFixedLanguageCode()}">
+ <head>
+ <meta charset="utf-8">
+ <title>{@$pageTitle} - {PAGE_TITLE|language}</title>
+ <link rel="canonical" href="{$regularCanonicalURL}">
+ <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
+ {if !$headContent|empty}
+ {@$headContent}
+ {/if}
+ <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:400,300,600">
+ <style amp-custom>
+ html {
+ box-sizing: border-box;
+ }
+
+ *,
+ *::before,
+ *::after {
+ box-sizing: inherit;
+ }
+
+ body {
+ background-color: #fff;
+ font-family: "Open Sans", "Segoe UI", "Lucida Grande", "Helvetica", sans-serif;
+ font-size: 14px;
+ }
+
+ a {
+ color: rgb(231, 76, 60);
+ text-decoration: none;
+ }
+
+ a:hover {
+ color: rgb(192, 57, 43);
+ text-decoration: none;
+ }
+
+ button {
+ background: none;
+ border: none;
+ color: inherit;
+ display: block;
+ font-family: "Open Sans", "Segoe UI", "Lucida Grande", "Helvetica", sans-serif;
+ font-size: 14px;
+ margin-top: 5px;
+ outline: 0;
+ overflow: hidden;
+ padding: 0;
+ text-transform: uppercase;
+ }
+
+ .header {
+ background-color: rgb(44, 62, 80);
+ color: #fff;
+ padding: 20px;
+ }
+
+ .header button {
+ margin-top: 10px;
+ }
+
+ .footer {
+ background-color: rgb(52, 73, 94);
+ color: rgb(189, 195, 199);
+ padding: 20px 10px;
+ }
+
+ .footer a {
+ color: rgb(189, 195, 199);
+ }
+
+ .footer a:hover {
+ color: rgb(255, 255, 255);
+ text-decoration: none;
+ }
+
+ .footer .copyright {
+ text-align: center;
+ }
+
+ .main {
+ color: rgb(44, 62, 80);
+ padding: 30px 10px;
+ }
+
+ .article .articleTitle {
+ font-weight: 300;
+ font-size: 23px;
+ line-height: 1.05;
+ margin: 0;
+ }
+
+ .article .articleAuthor {
+ color: rgb(125, 130, 135);
+ display: inline-block;
+ font-size: 14px;
+ font-weight: 400;
+ margin: 5px 0 0 0;
+ }
+
+ .article .articleAuthor::after {
+ color: rgb(125, 130, 135);
+ content: "\00b7";
+ margin-left: 6px;
+ }
+
+ .article .articleDate {
+ color: rgb(125, 130, 135);
+ }
+
+ .article .articleImage,
+ .article .articleContent,
+ .article .articleTeaser {
+ margin-top: 30px;
+ }
+
+ .article .articleTeaser {
+ font-weight: 600;
+ }
+
+ amp-user-notification {
+ background-color: rgb(217, 237, 247);
+ color: rgb(49, 112, 143);
+ padding: 10px;
+ }
+
+ amp-sidebar {
+ padding: 20px 10px 10px;
+ width: 250px;
+ }
+
+ amp-sidebar button {
+ margin-top: 0;
+ position: absolute;
+ right: 10px;
+ top: 10px;
+ }
+
+ amp-sidebar h3 {
+ font-size: 18px;
+ font-weight: 400;
+ margin: 20px 0 0;
+ }
+
+ amp-sidebar ol {
+ margin: 10px 0 0;
+ padding: 0;
+ }
+
+ amp-sidebar ol ol {
+ margin-left: 20px;
+ margin-top: 0;
+ }
+
+ amp-sidebar ol + ol {
+ margin-top: 0;
+ }
+
+ amp-sidebar li {
+ list-style: none;
+ }
+
+ amp-sidebar li a {
+ display: block;
+ padding: 7px 7px 7px 0;
+ }
+
+ .breadcrumbs li:nth-child(2) {
+ padding-left: 20px;
+ }
+ .breadcrumbs li:nth-child(3) {
+ padding-left: 30px;
+ }
+ .breadcrumbs li:nth-child(4) {
+ padding-left: 40px;
+ }
+ </style>
+ {literal}<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>{/literal}
+ <script async custom-element="amp-sidebar" src="https://cdn.ampproject.org/v0/amp-sidebar-0.1.js"></script>
+ <script async custom-element="amp-user-notification" src="https://cdn.ampproject.org/v0/amp-user-notification-0.1.js"></script>
+ <script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
+ <script async src="https://cdn.ampproject.org/v0.js"></script>
+ </head>
+<body>
+ <header class="header">
+ <div class="logo">
+ <a href="{link}{/link}"><amp-img width="288" height="40" src="{@$__wcf->getPath()}images/default-logo.png"></amp-img></a>{* @TODO *}
+ </div>
+
+ <button on='tap:sidebar.toggle'>{lang}wcf.global.page.pagination{/lang}</button>
+ </header>
+ <main class="main">
{/if}
{/foreach}
{/if}
+ <link rel="amphtml" href="{link controller='ArticleAmp' object=$articleContent}{/link}">
{/capture}
{include file='header'}
--- /dev/null
+<?php
+namespace wcf\page;
+use wcf\data\article\content\ViewableArticleContent;
+use wcf\data\article\ArticleEditor;
+use wcf\data\article\ViewableArticle;
+use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\PermissionDeniedException;
+use wcf\system\page\PageLocationManager;
+use wcf\system\WCF;
+
+/**
+ * Shows the amp version of an article.
+ *
+ * @author Marcel Werk
+ * @copyright 2001-2016 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package WoltLabSuite\Core\Page
+ * @since 3.0
+ */
+class ArticleAmpPage extends AbstractPage {
+ /**
+ * @inheritDoc
+ */
+ public $templateName = 'ampArticle';
+
+ /**
+ * @inheritDoc
+ */
+ public $neededModules = ['MODULE_ARTICLE'];
+
+ /**
+ * article content id
+ * @var integer
+ */
+ public $articleContentID = 0;
+
+ /**
+ * article content object
+ * @var ViewableArticleContent
+ */
+ public $articleContent;
+
+ /**
+ * article object
+ * @var ViewableArticle
+ */
+ public $article;
+
+ /**
+ * @inheritDoc
+ */
+ public function readParameters() {
+ parent::readParameters();
+
+ if (isset($_REQUEST['id'])) $this->articleContentID = intval($_REQUEST['id']);
+ $this->articleContent = ViewableArticleContent::getArticleContent($this->articleContentID);
+ if ($this->articleContent === null) {
+ throw new IllegalLinkException();
+ }
+ $this->article = ViewableArticle::getArticle($this->articleContent->articleID);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function checkPermissions() {
+ parent::checkPermissions();
+
+ if (!$this->article->canRead()) {
+ throw new PermissionDeniedException();
+ }
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function readData() {
+ parent::readData();
+
+ // update view count
+ $articleEditor = new ArticleEditor($this->article->getDecoratedObject());
+ $articleEditor->updateCounters([
+ 'views' => 1
+ ]);
+
+ // set location
+ PageLocationManager::getInstance()->addParentLocation('com.woltlab.wcf.CategoryArticleList', $this->article->categoryID, $this->article->getCategory());
+ foreach ($this->article->getCategory()->getParentCategories() as $parentCategory) {
+ PageLocationManager::getInstance()->addParentLocation('com.woltlab.wcf.CategoryArticleList', $parentCategory->categoryID, $parentCategory);
+ }
+ PageLocationManager::getInstance()->addParentLocation('com.woltlab.wcf.ArticleList');
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function assignVariables() {
+ parent::assignVariables();
+
+ WCF::getTPL()->assign([
+ 'articleContentID' => $this->articleContentID,
+ 'articleContent' => $this->articleContent,
+ 'article' => $this->article,
+ 'category' => $this->article->getCategory(),
+ 'regularCanonicalURL' => $this->articleContent->getLink()
+ ]);
+ }
+}
overflow: hidden;
img {
- width: 100%;
+ height: auto !important;
+ width: 100% !important;
}
}