• Welcome to Simple Machines Community Forum. Please login or sign up.

[Alpha] AMP For SMF 2.1

Started by Antes, June 06, 2020, 09:27:58 AM

Previous topic - Next topic

spiros

One thing definitely needed is active links in breadcrumbs so that people can move around :)

Antes

Quote from: spiros on June 09, 2020, 11:11:41 AM
One thing definitely needed is active links in breadcrumbs so that people can move around :)

AMP is not a thing like -responsive-, I already added Full option that redirects you to same page but in full format, can add Home icon as well...

spiros

What I mean is that these in your demo: General Category => General Discussion should be linked (to respective AMP pages of course), or at least the board name + (AMP) Home link. Then, of course, one could access boards and topics from Home page. This can make it usable for full site navigation.

A more advanced option would be AMP takeover (by the way, you can check this Wordpress plugin for ideas), i.e. kick out everybody who is online and force the AMP theme as main site theme. It could be useful if one wants to perform maintenance without disabling access to the forums's pages given that no login option exists.

Antes

That requires me to rebuild all those pages in AMP format... I don't think its worth the time you spend on them.

AMP is a trend pushed by Google... and soon they are lifting AMP requirement for certain promoted pages, which probably end up many people to leave the standard or keep as-is. The only reason I built this small thingie to help people out and since it can work nicely alone, no harm only good come from it.

Xpresskonami

What I also discovered in the AMP for smf. It also similar to SMF wap2. I found out that some of the smf wap2 topics we're indexed in Google just like AMP. If the wap2 mod can be rewrites to AMP will it work?

Xpresskonami

Quote from: Antes on June 09, 2020, 05:23:44 PM
That requires me to rebuild all those pages in AMP format... I don't think its worth the time you spend on them.

AMP is a trend pushed by Google... and soon they are lifting AMP requirement for certain promoted pages, which probably end up many people to leave the standard or keep as-is. The only reason I built this small thingie to help people out and since it can work nicely alone, no harm only good come from it.

Can anyone please see to this, i use the AMP 2.1 Mod to do the NEND AMP 2.0. it only install but not working. 

Arantor

You can't just slap them together and hope it'll work - and the OP isn't going to work on a 2.0 version, please stop bumping and pushing for a 2.0 version.

The simple truth is that almost no-one here actually cares about making it easier to scrape your site.
No good deed goes unpunished
All helpful urges should be circumvented

Xpresskonami

Quote from: Xpresskonami on June 18, 2020, 02:11:08 PM
Quote from: Antes on June 09, 2020, 05:23:44 PM
That requires me to rebuild all those pages in AMP format... I don't think its worth the time you spend on them.

AMP is a trend pushed by Google... and soon they are lifting AMP requirement for certain promoted pages, which probably end up many people to leave the standard or keep as-is. The only reason I built this small thingie to help people out and since it can work nicely alone, no harm only good come from it.

Can anyone please see to this, i use the AMP 2.1 Mod to do the NEND AMP 2.0. it only install but not working.

Package-info.xml

<?xml version="1.0"?>
<!DOCTYPE package-info SYSTEM "http://www.simplemachines.org/xml/package-info">
<package-info xmlns="http://www.simplemachines.org/xml/package-info" xmlns:smf="http://www.simplemachines.org/">
<id>NEND:smfamp</id>
<name>Accelerated Mobile Pages</name>
<version>0.0.1</version>
<type>modification</type>
<install for="2.0 - 2.0.99">
<!-- <readme parsebbc="true">license.txt</readme> -->
<!-- <modification format="xml" type="file">install.xml</modification> -->
<require-file name="Amp.php" destination="$sourcedir" />
<require-file name="Amphooks.php" destination="$sourcedir" />
<require-file name="Amp.template.php" destination="$themedir" />
<database>install.php</database>
</install>
<uninstall for="2.0 - 2.0.99">
<!-- <modification reverse="true">install.xml</modification> -->
<remove-file name="Amp.php" destination="$sourcedir" />
<remove-file name="Amphooks.php" destination="$sourcedir" />
<remove-file name="Amp.template.php" destination="$themedir" />
</uninstall>
</package-info>



Install.php

<?php

// If SSI.php is in the same place as this file, and SMF isn't defined, this is being run standalone.
if (file_exists(dirname(__FILE__) . '/SSI.php') && !defined('SMF'))
require_once(dirname(__FILE__) . '/SSI.php');
// Hmm... no SSI.php and no SMF?
elseif (!defined('SMF'))
die('<b>Error:</b> Cannot install - please verify you put this in the same place as SMF\'s index.php.');
 
db_extend('packages');

// Insert the hooks.
$hooks = array(
'integrate_pre_include' => '$sourcedir/Amphooks.php',
'integrate_actions' => 'amp_actions',
'integrate_pre_css_output' => 'amp_headers'
);

if (!empty(
$context['uninstalling']))
$hook_function 'remove_integration_function';
else
$hook_function 'add_integration_function';

foreach (
$hooks as $hook => $function)
$hook_function($hook$function);


Amphooks.php

<?php

if (!defined('SMF'))
die('Hacking attempt...');

// Hook Add Action
function amp_actions(&$actionArray)
{
  global 
$sourcedir$modSettings;

  
$actionArray += array('html' => array('Amp.php''Amp'));
}

function 
amp_headers() {
  global 
$context$scripturl$topic;

if (!empty($topic)) {
echo '
<link rel="amphtml" href="'
$scripturl '?action=amp;topic=' $topic .'">';
}
}


Amp.template.php

<?php
/**
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines https://www.simplemachines.org
 * @copyright 2020 Simple Machines and individual contributors
 * @license https://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.0
 */

/**
 * The header. Defines the look and layout of the page as well as a form for choosing print options.
 */
function template_html_above(){

global $scripturl$context$boardurl;

echo '<!doctype html>
<html amp lang="en">
<head>
<meta charset="' 
. (empty($context['character_set']) ? 'ISO-8859-1' strtolower($context['character_set'])).'">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<title>'
$context['page_title'], '</title>
<link rel="canonical" href="'
$context['canonical'], '" />
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<script type="application/ld+json">{
"@context": "http://schema.org",
"@type": "Article",
"mainEntityOfPage":{"@type":"WebPage","@id":"'
$context['canonical'], '"},
"headline": "'
$context['page_title'], '",
"datePublished": "'
$context['posted'], '",
"dateModified":"'
$context['modified'], '",
"image":{"@type": "ImageObject","url": "'
.$context['rel_img'].'","width": "auto","height": "auto"},
"author":{"@type":"Person","name":"'
.$context['amp']['poster_name'].'"},
"publisher":{"@type": "Organization","name":"SI Community","logo":{"@type":"ImageObject","url":"'
.$boardurl.'/img/viral/site_thumb.png","width":"auto","height":"auto"}}
}</script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
<style amp-custom>.logo {background-color:#28D;font-variant:small-caps;color:#ffc;text-align:left;padding:6px;box-shadow:0 1px 2px rgba(10,10,10,0.4)}.logo > a {color:#DEF;font:1.1em trebuchet,Helvetica,sans-serif;font-weight: bold;text-decoration:none}.logo amp-img{float:left}.heading {padding:5px;margin-top:0.83em}.who, .who a{color:#999;text-decoration:none}.sep{border:none;height:1px;background-color:#aaa;width:100px;}h3 a{text-decoration:none;color:#000;}.ampbutton{border: 0;background-color:#28D;font-weight:bold;color:#FFF;cursor:pointer;padding: 5px 10px;font-size:large}.ampbutton:hover{background-color:#4AF}blockquote,body,dd,dl,figure,hr,html,ol,pre{margin:0;padding:0}blockquote>:last-child{margin-bottom:0}body,html{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;overflow-x:hidden}img{border:0;max-width:100%}b,strong{font-weight:600}h1,h2,h3,h4,h5{color:#0379C4;font-weight:300;margin-top:1.1em;margin-bottom:.5em}h1{font-size:43px}h2{font-size:36px}h3{font-size:26px}a{color:#0379C4;text-decoration:none}a:hover{text-decoration:underline}a.button{padding:1em;display:block;text-align:center}blockquote{color:#797c82;border-left:4px solid #f5f5f5;padding-left:15px;font-size:18px;letter-spacing:-1px;font-style:italic}ol li,ul li{color:#424242;font-size:16px;font-weight:300;line-height:24px}@media only screen and (max-width:956px){ol li,ul li{font-size:16px;line-height:28px}}code,kbd,pre,samp,tt{font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:.9em;background:#f2f9ff;border:1px solid #b2e7ff;border-radius:3px;color:#222}code{font-size:13px;padding:2px 5px;display:block}a code{color:#035386;white-space:nowrap;border-bottom-width:2px;border-color:#29aae3}a:hover code{color:#fff;background-color:#29aae3}h1 code,h2 code,h3 code,h4 code,h5 code{font-size:.9em}pre{overflow:auto;-moz-tab-size:2;-o-tab-size:2;tab-size:2;word-break:normal;line-height:1.4;padding:1em}pre>code{white-space:pre;word-wrap:initial;display:block}pre>code td{border:0}table{border-collapse:collapse;width:100%}td,th{border:1px solid #FFF;background:#F7F7F7;padding:.5rem;text-align:left;color:#424242;font-size:16px;font-weight:300;line-height:24px;vertical-align:top}@media only screen and (max-width:956px){td,th{font-size:16px;line-height:28px}}th{background:#0379C4;color:#fff;font-weight:400}</style>
<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>
</head>
<body>'
;
}

function 
template_html_below() {
echo '
</body>
</html>'
;
}

function 
template_AmpTopic(){

global $context$scripturl$boardurl;

echo '
<div class="logo">
<a href="'
.$scripturl.'"><amp-img src="'.$boardurl.'/img/viral/site_thumb.svg" alt="SI Community" title="SI Community" height="20px" width="20px"></amp-img></a>
&nbsp;&nbsp;<a href="'
.$scripturl.'?board=' $context['amp']['id_board'].'">' $context['amp']['board_name'] . '</a>
</div>
'
.($context['head_img'] ? '<a href="'.$scripturl.'?topic='.$context['amp']['id_topic'].';topicseen#new"><amp-img width="600" height="500" layout="responsive" src="'.$context['rel_img'].'"></amp-img></a>' '').'
<div class="heading">
<center>
<a href="'
.$scripturl.'"><amp-img src="'.$boardurl.'/img/viral/site_thumb50.png" alt="SI Community" title="SI Community" height="50px" width="50px"></amp-img></a>
<h3><a href="'
.$scripturl.'?topic='.$context['amp']['id_topic'].'">'.$context['page_title'].'</a></h3>
<hr class="sep">
<span>
<b>SI Community</b><br>
<small class="who">
<a href="'
.$scripturl.'?action=profile;u=' $context['amp']['id_member'].'">' $context['amp']['poster_name'] . '</a> • 
'
.date('M j, Y'$context['amp']['poster_time']).'
</small>
</span>
</center>
</div>
<div class="heading">
'
.$context['amp']['body'].'
<center>
<div class="amp-ad-container">
<amp-ad width=300 height=250 type="adsense" data-ad-client="ca-pub-3272970468196826" data-ad-slot="8230679555"></amp-ad>
</div>
</center>
<p><a href="'
.$scripturl.'?topic='.$context['amp']['id_topic'].'"><center><button class="ampbutton">Read More</button></center></a></p>
</div>'
;
}
?>



Amp.php

<?php
/**
 * This file contains just one function that formats a topic to be AMP friendly
 *
 * Simple Machines Forum (SMF)
 *
 * @package SMF
 * @author Simple Machines https://www.simplemachines.org
 * @copyright 2020 Simple Machines and individual contributors
 * @license https://www.simplemachines.org/about/smf/license.php BSD
 *
 * @version 2.0
 */
if (!defined('SMF'))
die('Hacking attempt...');

function 
AmpMain() {
if (isset($_REQUEST['t']))
AmpTopic($_REQUEST['t']);
elseif (isset($_REQUEST['m']))
AmpMedia($_REQUEST['m']);
else
si404();
}

function 
AmpTopic($id) {

global $context$smcFunc$scripturl$boardurl$modSettings;

loadTemplate('Amp');
$context['template_layers'] = array('html');
$context['sub_template'] = 'AmpTopic';
$modSettings['disableQueryCheck'] = 1;
$request $smcFunc['db_query']('''
SELECT
m.poster_time, m.subject, m.id_topic, m.id_member, m.id_msg, b.id_board, b.name AS board_name,
IFNULL(mem.real_name, m.poster_name) AS poster_name, m.body, b.thumb_board as thumb, m.modified_time,
(SELECT id_attach FROM {db_prefix}attachments WHERE id_thumb != 0 AND {db_prefix}attachments.id_msg = m.id_msg ORDER BY id_attach LIMIT 1) AS id_attach
FROM {db_prefix}topics AS t
INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
INNER JOIN {db_prefix}boards AS b ON (b.id_board = t.id_board)
LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
WHERE {query_wanna_see_board} AND t.id_topic = {int:id}
LIMIT 1' 
,
array(
'id' => (int) $id
)
);
$context['amp'] = $smcFunc['db_fetch_assoc']($request);

if ($context['amp']) {
$context['amp']['subject'] = censorText($context['amp']['subject']);
$context['page_title'] = $context['amp']['subject'];
$context['canonical'] = $scripturl '?topic=' $context['amp']['id_topic'];
$context['posted'] = date('Y-m-d\TH:i:s'$context['amp']['poster_time']);
$context['modified'] = date('Y-m-d\TH:i:s', empty($context['amp']['modified_time']) ? $context['amp']['poster_time'] : $context['amp']['modified_time']);
$context['head_img'] = false;
if (preg_match('[smg id=([0-9]+)(.*)]'$context['amp']['body'], $match))
$context['head_img'] = $context['rel_img'] = $scripturl.'?action=media;sa=media;in='.$match[1].';preview';
elseif (preg_match('#\[img(.*)\](.*)\[\/img\]#Ui'$context['amp']['body'], $match))
$context['head_img'] = $context['rel_img'] = $match[2];
elseif (isset($context['amp']['id_attach']) && $context['amp']['id_attach'] != 0)
$context['head_img'] = $context['rel_img'] = $scripturl '?action=dlattach;topic='.$context['amp']['id_topic'].';attach='.$context['amp']['id_attach'].';image';
elseif (isset($context['amp']['thumb']) && $context['amp']['thumb'] != '')
$context['rel_img'] = $boardurl.'/img/b/sm/'.$context['amp']['thumb'];
else
$context['rel_img'] = $boardurl.'/img/viral/site_thumb.png';

$context['amp']['body'] = amp_rewrite(parse_bbc($context['amp']['body']));
} else
si404();

// Add 1 to the number of views of this topic.
if (empty($_SESSION['last_read_topic']) || $_SESSION['last_read_topic'] != $id) {
$smcFunc['db_query']('''
UPDATE {db_prefix}topics
SET num_views = num_views + 1
WHERE id_topic = {int:current_topic}'
,
array(
'current_topic' => (int) $id,
)
);
$_SESSION['last_read_topic'] = $id;
}
}

function 
amp_rewrite($data) {

/*
 * This is resource intensive, especially since we parse the BCC and
 * now we are doing more just to make sure the markup is up to AMP standard.
 * Good thing it is just one post.
 */

// This does happen, empty media descriptions, so we return a empty string.
if (empty($data))
return('');

// Lets use the DOM first, the server will thank us for it.
libxml_use_internal_errors(true);
$DOM = new DOMDocument();
$DOM->loadHTML('<?xml encoding="utf-8" ?>
'.$data);
$XPath = new DOMXPath($DOM);

// Got class but no style, no borders no limits :P
foreach(array('style','border') as $attribute)
foreach($XPath->query('//*[@'.$attribute.']') as $item)
$item->removeAttribute($attribute);

// Unallowed stuff, button is allowed but figured it looked ugly with it and without the other stuff
foreach(array('script','frame','frameset','object','param','applet','embed','form','input','textarea','select','option','button','iframe','video','audio') as $item)
while($node = $XPath->query('//'.$item)->item(0))
$node->parentNode->removeChild($node);

// Put the stuff back.
$data = $DOM->saveHTML($XPath->query('//body')->item(0));
foreach(array('body','/body') as $item)
$data = str_replace('<'.$item.'>', '', $data);
libxml_clear_errors();

// Remove the code BBC select JavaScript.
$data = preg_replace('~<a .*?href="javascript.*?>.*?</a>~si', '', $data);

// Other stuff below, <amp- is not valid HTML, that is why we can't do it in the DOM. :(

//Some stuff needs to be done one at a time, borrowed from SMF.
$pos = -1;
while ($pos !== false){
$last_pos = isset($last_pos) ? max($pos, $last_pos) : $pos;
$pos = strpos($data, '<', $pos + 1);
if ($pos === false || $last_pos > $pos)
$pos = strlen($data) + 1;
if ($last_pos < $pos - 1){
$last_pos = max($last_pos, 0);
$str = substr($data, $last_pos, $pos - $last_pos);

// Image is *
$str = preg_replace('~<img (.*?)class="(emoji|smiley)\b.*?>~si', '<amp-img width="30" height="30" $1></amp-img>', $str);
$str = preg_replace('~<img (.*?)>~si', '<center><amp-img width="300" height="250" $1></amp-img></center>', $str);

if ($str != substr($data, $last_pos, $pos - $last_pos)){
$data = substr($data, 0, $last_pos) . $str . substr($data, $pos);
$old_pos = strlen($data) + $last_pos;
$pos = strpos($data, '<', $last_pos);
$pos = $pos === false ? $old_pos : min($pos, $old_pos);
}
}
if ($pos >= strlen($data) - 1)
break;
}

return $data;
}
?>


These are the code in the attachment file for the AMP 2.0

Xpresskonami

Quote from: Arantor on June 18, 2020, 02:14:57 PM
You can't just slap them together and hope it'll work - and the OP isn't going to work on a 2.0 version, please stop bumping and pushing for a 2.0 version.

The simple truth is that almost no-one here actually cares about making it easier to scrape your site.

I am not installing 2.1 on 2.0, i only try to use the 2.1 to work on the 2.0 like i see the code for each were similar. and doing this in support forum together might also help

Arantor

Except that you can't use 2.1 code in 2.0, because it's not 2.1 - and this isn't actually helping anyone.
No good deed goes unpunished
All helpful urges should be circumvented

Doug Heffernan

Quote from: Arantor on June 06, 2020, 12:29:12 PM
Quote from: @rjen on June 06, 2020, 12:24:29 PM
Quoteno, there won't be a SMF 2.0 version of it -even paid-*

Can't you READ?

You're assuming he cares enough to read beyond "what free stuff have people built for my use?"

Hilarious. That got a chuckle out of me.  ;D

Antes

I know this is morally wrong (or grey) but I really jump to wrong/grey side this time... I released v0.0.2 for AMP4SMF2.1 (smol update), and AMP4SMF2... Both are in my discord you can find in my signature... Also I have ResponsiveCurve2 on the way... I'm truly sorry for doing this but posting here just sickens me.

As I said in other topic, the only reason I'm keeping the updates rolling this way or that way because you guys still support me financially even tho I disappear time to time and ethically this is the right way to pay most of you back.

Xpresskonami

Quote from: Antes on July 04, 2020, 08:20:36 AM
I know this is morally wrong (or grey) but I really jump to wrong/grey side this time... I released v0.0.2 for AMP4SMF2.1 (smol update), and AMP4SMF2... Both are in my discord you can find in my signature... Also I have ResponsiveCurve2 on the way... I'm truly sorry for doing this but posting here just sickens me.

As I said in other topic, the only reason I'm keeping the updates rolling this way or that way because you guys still support me financially even tho I disappear time to time and ethically this is the right way to pay most of you back.

:'( O:) O:) :'( :'( :'(
You re teasing we Smf 2.0 user, you just released another version of the Amp for SMF 2.1 version. I hope someday, someone will release for SMF 2.0 user... Anyway! You really doing a great job. Well done ... I give you 5 🌟 🌟 🌟 🌟 🌟 star


Arantor

Did you not read the part where it says you can get it from his Discord server? Or are you really so lazy you can't even do that and need to have it handed to you on a plate?
No good deed goes unpunished
All helpful urges should be circumvented

Xpresskonami

Quote from: Antes on July 04, 2020, 08:20:36 AM
I released v0.0.2 for AMP4SMF2.1 (smol update), and AMP4SMF2... Both are in my discord you can find in my signature... Also I have ResponsiveCurve2 on the way... I'm truly sorry for doing this but posting here just sickens me.


You really did a good and great job Antes. the mod is working well with smf 2.0 You can check DEMO FOR AMP 2.0 Is the mod working with pretty url? i try to fetch out the pretty url link for it but seem not working or i might input invalid link

Xpresskonami

Quote from: Arantor on July 06, 2020, 06:33:18 AM
Did you not read the part where it says you can get it from his Discord server? Or are you really so lazy you can't even do that and need to have it handed to you on a plate?

Just sort of word to this...

Arantor

I just have a problem with people who beg and beg and demand things to be done for them because they don't want to spend any effort themselves. Like people who expect things to be uploaded here rather than having to follow links because that's so much effort.
No good deed goes unpunished
All helpful urges should be circumvented

Xpresskonami

Quote from: Arantor on July 06, 2020, 07:12:41 AM
I just have a problem with people who beg and beg and demand things to be done for them because they don't want to spend any effort themselves. Like people who expect things to be uploaded here rather than having to follow links because that's so much effort.

I see!

Advertisement: