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)
Scam Warning
romans1423
Registered User
Posts: 1552
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Auto-linking Reddit References

Post by romans1423 » Sun Dec 09, 2018 3:47 pm

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.

User avatar
mrgoldy
Jr. Extension Validator
Posts: 1104
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: [REQUEST] Auto-linking Reddit References

Post by mrgoldy » Sun Dec 09, 2018 6:24 pm

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?

romans1423
Registered User
Posts: 1552
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 » Sun Dec 09, 2018 7:32 pm

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.

User avatar
mrgoldy
Jr. Extension Validator
Posts: 1104
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: Auto-linking Reddit References

Post by mrgoldy » Sun Dec 09, 2018 8:08 pm

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

romans1423
Registered User
Posts: 1552
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 » Tue Dec 11, 2018 6:19 am

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);
	}
}

User avatar
JoshyPHP
Code Contributor
Posts: 1012
Joined: Mon Jul 11, 2011 12:28 am

Re: Auto-linking Reddit References

Post by JoshyPHP » 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:

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 thing that does BBCodes in 3.2.

User avatar
ViolaF
Registered User
Posts: 1454
Joined: Tue Aug 14, 2012 11:52 pm

Re: Auto-linking Reddit References

Post by ViolaF » Tue Dec 11, 2018 5:47 pm

Thanks, Josh...

romans1423
Registered User
Posts: 1552
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 » Tue Dec 11, 2018 10:07 pm

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

User avatar
AbaddonOrmuz
Registered User
Posts: 661
Joined: Wed Dec 25, 2013 9:06 pm
Location: /dev/null
Name: Alfredo Ramos
Contact:

Re: Auto-linking Reddit References

Post by AbaddonOrmuz » Tue Dec 11, 2018 11:37 pm

The # character is just a regex delimiter, see:

https://secure.php.net/manual/en/regexp ... miters.php
Some of my phpBB extensions: [ Imgur | SEO Metadata | Markdown ]
Check out all my extensions
Arch Linux user

User avatar
mrgoldy
Jr. Extension Validator
Posts: 1104
Joined: Tue Oct 06, 2009 7:34 pm
Location: The Netherlands
Name: Gijs
Contact:

Re: Auto-linking Reddit References

Post by mrgoldy » Tue Dec 11, 2018 11:37 pm

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.

User avatar
JoshyPHP
Code Contributor
Posts: 1012
Joined: Mon Jul 11, 2011 12:28 am

Re: Auto-linking Reddit References

Post by JoshyPHP » Tue Dec 11, 2018 11:48 pm

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 thing that does BBCodes in 3.2.

romans1423
Registered User
Posts: 1552
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 » Wed Dec 12, 2018 3:46 am

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:

romans1423
Registered User
Posts: 1552
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 » Wed Dec 12, 2018 4:52 am

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'
		);
	}
}

User avatar
AbaddonOrmuz
Registered User
Posts: 661
Joined: Wed Dec 25, 2013 9:06 pm
Location: /dev/null
Name: Alfredo Ramos
Contact:

Re: Auto-linking Reddit References

Post by AbaddonOrmuz » Wed Dec 12, 2018 6:19 am

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: [ Imgur | SEO Metadata | Markdown ]
Check out all my extensions
Arch Linux user

romans1423
Registered User
Posts: 1552
Joined: Sat Nov 02, 2002 4:44 pm
Location: Connersville, IN
Name: Rick Beckman
Contact:

Re: Auto-linking Reddit References

Post by romans1423 » Wed Dec 12, 2018 7:25 am

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.

Post Reply

Return to “Extension Requests”