Auto-linking Reddit References

Looking for an Extension? Have an Extension request? Post your request here for help. (Note: This forum is community supported; while there is an Extensions Development Team, said team does not dedicate itself to handling requests in this forum)
Anti-Spam Guide
User avatar
romans1423
Registered User
Posts: 1560
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Auto-linking Reddit References

Post by romans1423 »

I've been out of the phpBB game for a long time, and I'm having trouble wrapping my mind around how extensions are built/structured. This feels like it should be a simple thing to accomplish but I'm just not getting it...

Anyway, I want to automatically link Reddit references in posts on my board. There are two kinds:

r/subredditname -- these always take the form of r/ followed by a string containing letters, numbers, and underscores (underscore can't be the first character). When detected, these should be automatically turned into a link of the form:

Code: Select all

<a href="https://www.reddit.com/r/subredditname" target="_new">r/subredditname</a>
u/username -- these always take the form of u/ followed by a string containing letters, numbers, underscores, and dashes. When detected, these should be automatically turned into a link of the form:

Code: Select all

<a href="https://www.reddit.com/user/username" target="_new">r/username</a>
Any help would be appreciated!
Last edited by romans1423 on Sun Dec 09, 2018 7:30 pm, edited 1 time in total.
RickBeckman.org | The Fellowship Hall – Diversity-friendly Religious Forums
User avatar
mrgoldy
Former Team Member
Posts: 1394
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: [REQUEST] Auto-linking Reddit References

Post by mrgoldy »

And why not simply create a BBCode for those instances?
So it will be something like [reddit]r/subreddit[/reddit. Which then automatically turned into a link with its HTML replacement?
Or does this per sé have to be automatic parsing when a post text contains r/subreddit?
phpBB Studio / Member of the Studio

Contributing: You can do it too! Including testing Pull Requests (PR).
phpBB Development and Testing made easy.
User avatar
romans1423
Registered User
Posts: 1560
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 »

I have a BBCode already set up ([r]) for this, but we're wanting it to be automated, which is the behavior on not only Reddit but also Facebook Messenger when simply typing a subreddit name. Automatic linking is far more intuitive, I think.
RickBeckman.org | The Fellowship Hall – Diversity-friendly Religious Forums
User avatar
mrgoldy
Former Team Member
Posts: 1394
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: Auto-linking Reddit References

Post by mrgoldy »

Okay, well if you want to get into the 'extension' side of things, this documentation will help you out:
- https://area51.phpbb.com/docs/dev/3.2.x ... index.html

And the phpBB Skeleton Extension will give you a head start on some of the files:
- https://area51.phpbb.com/docs/dev/3.2.x ... nsion.html

You will mostly need the new s9e text formatter and alter the parsing and/or rendering to your needs.
- https://area51.phpbb.com/docs/dev/3.2.x ... ode-engine
phpBB Studio / Member of the Studio

Contributing: You can do it too! Including testing Pull Requests (PR).
phpBB Development and Testing made easy.
User avatar
romans1423
Registered User
Posts: 1560
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 »

OK, I've gotten this far... I have a working extension installed, I've figured out how to modify the text of posts a bit, but now I can't figure out how to actually piece together the code I have. When in use, it simply blanks out every post -- whoops. I mimicked the phpBB code that makes email addresses clickable as closely as I could understand it. The functions I copied/trimmed down were make_clickable() and make_clickable_callback().

Code: Select all

class main_listener implements EventSubscriberInterface
{
	static public function getSubscribedEvents()
	{
		return array(
			'core.modify_text_for_display_after'	=> 'autolink_reddit_references',
		);
	}

	public function make_reddit_reference_clickable_callback($matches)
	{
		// make sure no HTML entities were matched
		$chars = array('<', '>', '"');
		$split = false;

		$url = $matches[2];

		foreach ($chars as $char)
		{
			$next_split = strpos($url, $char);
			if ($next_split !== false)
			{
				$split = ($split !== false) ? min($split, $next_split) : $next_split;
			}
		}

		if ($split !== false)
		{
			// an HTML entity was found, so the URL has to end before it
			$append			= substr($url, $split) . $relative_url;
			$url			= substr($url, 0, $split);
		}

		// if the last character of the url is a punctuation mark, exclude it from the url
		$last_char = $url[strlen($url) - 1];

		switch ($last_char)
		{
			case '.':
			case '?':
			case '!':
			case ':':
			case ',':
				$append = $last_char;
				$url = substr($url, 0, -1);
			break;

			// set last_char to empty here, so the variable can be used later to
			// check whether a character was removed
			default:
				$last_char = '';
			break;
		}

		$text	= $url;
		$url	= 'https://www.reddit.com/' . $url;

		$url	= htmlspecialchars($url);
		$text	= htmlspecialchars($text);
		$append	= htmlspecialchars($append);

		$html	= "<a href=\"$url\">$text</a>$append";

		return $html;
	}

	public function make_reddit_reference_clickable($text)
	{
		static $reddit_regex;

		$reddit_regex = '(r|u)\/(([a-z0-9]{1}[a-z0-9\-\_]{0,62}[a-z0-9]{1}))+';

		if (preg_match('/(^|[\n\t (>])(' . $reddit_regex . ')/iu', $text, $matches))
		{
			$text = preg_replace_callback('/(^|[\n\t (>])(' . $reddit_regex . ')/iu', array($this, 'make_reddit_reference_clickable_callback'), $text);
		}

		return $text;
	}

	/**
	 * A sample PHP event
	 * Modifies the names of the forums on index
	 *
	 * @param \phpbb\event\data	$event	Event object
	 */
	public function autolink_reddit_references($event)
	{
		$event['text'] = $this->make_reddit_reference_clickable($text);
	}
}
RickBeckman.org | The Fellowship Hall – Diversity-friendly Religious Forums
User avatar
JoshyPHP
Code Contributor
Posts: 1288
Joined: Mon Jul 11, 2011 12:28 am

Re: Auto-linking Reddit References

Post by JoshyPHP »

If you do it at parsing time, it will allow you to leverage the Preg plugin and reduce the code for your extension to this:

Code: Select all

class main_listener implements EventSubscriberInterface
{
	public static function getSubscribedEvents()
	{
		return ['core.text_formatter_s9e_configure_after' => 'onConfigure'];
	}
	public function onConfigure($event)
	{
		$configurator = $event['configurator'];
		
		$configurator->Preg->replace(
			'#\\br/(?<name>\\w+)#',
			'<a href="https://www.reddit.com/r/$1" target="_new">$0</a>',
			'REDDITSUB'
		);
		$configurator->Preg->replace(
			'#\\bu/(?<username>\\w+)#',
			'<a href="https://www.reddit.com/user/$1" target="_new">$0</a>',
			'REDDITUSER'
		);
	}
}
I wrote the library that handles markup in phpBB 3.2+.
User avatar
ViolaF
I've Been Banned!
Posts: 1609
Joined: Tue Aug 14, 2012 11:52 pm

Re: Auto-linking Reddit References

Post by ViolaF »

Thanks, Josh...
User avatar
romans1423
Registered User
Posts: 1560
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 »

JoshyPHP wrote: Tue Dec 11, 2018 9:31 am If you do it at parsing time, it will allow you to leverage the Preg plugin and reduce the code for your extension to this
I used the code as given, and it doesn't change anything in my posts. References like r/murderedywords aren't linked. Is there a reference for what is valid in the regex patterns there? I don't recognize a lot of that, such as "#." Why do we need to match a # character?

I even used their own example along side your two blocks of replacement code, and nothing happens with it either. And yes, the extension I'm editing is active -- if I use invalid code, it obviously breaks my site. LOL
RickBeckman.org | The Fellowship Hall – Diversity-friendly Religious Forums
User avatar
AlfredoRamos
Recognised Extension Developer
Posts: 1302
Joined: Wed Dec 25, 2013 9:06 pm
Location: /dev/null
Name: Alfredo
Contact:

Re: Auto-linking Reddit References

Post by AlfredoRamos »

The # character is just a regex delimiter, see:

https://secure.php.net/manual/en/regexp ... miters.php
Some of my phpBB extensions:
:chart_with_upwards_trend: SEO Metadata | Image Markdown | :shield: hCaptcha
:trophy: Check out all my validated extensions :trophy:

:penguin: Arch Linux user | Linux Boards :penguin:
User avatar
mrgoldy
Former Team Member
Posts: 1394
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: Auto-linking Reddit References

Post by mrgoldy »

I suggest using a site like regexr to get familiar with RegEx expressions.
The # signs are the delimiters, meaning they mark the beginning and the end of the expression to check for.

I think how ever a few too many characters are escaped in the example provided by Joshy, not tested it myself on a board though.
Could you try the following examples:

Code: Select all

	public function onConfigure($event)
	{
		$configurator = $event['configurator'];
		
		$configurator->Preg->replace(
			'#\br\/(?<name>\w+)#',
			'<a href="https://www.reddit.com/r/$1" target="_new">$0</a>',
			'REDDITSUB'
		);
		$configurator->Preg->replace(
			'#\bu\/(?<username>\w+)#',
			'<a href="https://www.reddit.com/user/$1" target="_new">$0</a>',
			'REDDITUSER'
		);
	}
Explanation:
# are the delimiters, as explained above.
\b means look for the end of any word, a "end of word character". Such as spaces, commas, dots, new lines, etc..
r look for the letter r (case sensitive!)
\/ look for the / symbol, I believe that needs escaping, hence the prepended \.
() is a capturing group, group 1, refered to in the next line for the replacement, see the $1
- The entire regex line is capture group 0, anything between () will then start counting up.
?<username> is the name of this particular capturing group
\w looks for a word, a word can consist of letter, digits and underscores (exactly what you are looking for)
+ is a quantifier, meaning it needs atleast 1 word or more to match.

Hope this helps.
phpBB Studio / Member of the Studio

Contributing: You can do it too! Including testing Pull Requests (PR).
phpBB Development and Testing made easy.
User avatar
JoshyPHP
Code Contributor
Posts: 1288
Joined: Mon Jul 11, 2011 12:28 am

Re: Auto-linking Reddit References

Post by JoshyPHP »

romans1423 wrote: Tue Dec 11, 2018 10:07 pm nothing happens with it either
Doing things at parsing time means it happens at posting time, so it only applies to new posts and posts being edited.

The regexp is correctly escaped. Meta-characters should be escaped in PHP so they're unambiguous and forward-compatible with syntax changes.
I wrote the library that handles markup in phpBB 3.2+.
User avatar
romans1423
Registered User
Posts: 1560
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 »

Regexr is one of my favorite coding sites -- I used it to piece together the Regex that was in use in my original code above.

I'm still not getting any success with any code posted so far, and it doesn't matter if I view an old post, new post, edited post, or anything. I've tested each scenario. :cry:
RickBeckman.org | The Fellowship Hall – Diversity-friendly Religious Forums
User avatar
romans1423
Registered User
Posts: 1560
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 »

I'm having absolutely zero luck with the s9e configurator thing.

I even tried this super simple example, but even it does nothing when posting an entry with "test" in it:

Code: Select all

$configurator->Preg->replace(
			'/(test)/',
			'pass',
			'PASSFAIL'
		);
This is the full text of my main_listener.php file which was created by the phpBB Extension Skeleton tool. I haven't modified anything else that the tool created because this was the first thing I wanted to get to work. None of the configurator customizations work, either on post views, new posts, or post edits. :\

Code: Select all

<?php
/**
 *
 * Local Customizations. An extension for the phpBB Forum Software package.
 *
 * @copyright (c) 2018, Rick Beckman
 * @license GNU General Public License, version 2 (GPL-2.0)
 *
 */

namespace secnow\secnowsoc\event;

/**
 * @ignore
 */
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * SecularNow.xyz Customizations Event listener.
 */
class main_listener implements EventSubscriberInterface
{
	public static function getSubscribedEvents()
	{
		return ['core.text_formatter_s9e_configure_after' => 'onConfigure'];
	}
	public function onConfigure($event)
	{
		$configurator = $event['configurator'];

		# Reddit subreddits
		$configurator->Preg->replace(
			'#\br\/(?<name>\w+)#',
			'<a href="https://www.reddit.com/r/{name}" target="_new">{name}</a>',
			'REDDITSUB'
		);
		# Reddit usernames
		$configurator->Preg->replace(
			'#\bu\/(?<username>\w+)#',
			'<a href="https://www.reddit.com/user/{username}" target="_new">{username}</a>',
			'REDDITUSER'
		);
		# Twitter usernames, from the S9E Configurator documentation
		$configurator->Preg->replace(
			'/@(?<username>\\w+)/',
			'<a href="https://twitter.com/{@username}">@{username}</a>',
			'TWITTERUSER'
		);
		# Super simple test
		$configurator->Preg->replace(
			'/(test)/',
			'pass',
			'PASSFAIL'
		);
	}
}
RickBeckman.org | The Fellowship Hall – Diversity-friendly Religious Forums
User avatar
AlfredoRamos
Recognised Extension Developer
Posts: 1302
Joined: Wed Dec 25, 2013 9:06 pm
Location: /dev/null
Name: Alfredo
Contact:

Re: Auto-linking Reddit References

Post by AlfredoRamos »

You need to clear the cache after making changes.

Try the following, I tested it:

Code: Select all

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class listener implements EventSubscriberInterface
{
	static public function getSubscribedEvents()
	{
		return [
			'core.text_formatter_s9e_configure_after' => 'reddit_autolink'
		];
	}

	public function reddit_autolink($event)
	{
		$configurator = $event['configurator'];

		$configurator->Preg->replace(
			'#\\br/([^_]\\w+)\\b#',
			'<a href="https://www.reddit.com/r/$1" class="postlink" rel="nofollow noreferrer noopener">$0</a>',
			'SUBREDDIT'
		);

		$configurator->Preg->replace(
			'#\\bu/([^_]\\w+)\\b#',
			'<a href="https://www.reddit.com/user/$1" class="postlink" rel="nofollow noreferrer noopener">$0</a>',
			'REDDITUSER'
		);
	}
}
It checks that the username and subreddit does not start with _
Some of my phpBB extensions:
:chart_with_upwards_trend: SEO Metadata | Image Markdown | :shield: hCaptcha
:trophy: Check out all my validated extensions :trophy:

:penguin: Arch Linux user | Linux Boards :penguin:
User avatar
romans1423
Registered User
Posts: 1560
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 »

Oh.

My.

God.

THANK YOU.

Something so simple. Ugh. I knew phpBB cached template things, but I never even considered that configurator rules would be cached as well.
RickBeckman.org | The Fellowship Hall – Diversity-friendly Religious Forums
Post Reply

Return to “Extension Requests”