Improving My WordPress Author Subscription Site

Recently, I’ve been assessing tools to move my subscription service — where readers can read all of my stories first, plus get additional rewards — to my WordPress site. I’ve assessed several plugin options, and done a deep dive into my top 2 options: Paid Memberships Pro and ARMember.

WordPress was originally created for blogging, so it is a great tool for reading. But if you compare the experience to other online reading or ebook platforms, you’ll notice some gaps. And as I dug deeper into the experience I wanted to create for my users, I began to uncover even more gaps.

This article will outline those gaps and how I’m managing them on my site. Everything in this article works as of WordPress 6.5.2.


Set up

In order to keep my WordPress setup straightforward, I decided to create custom post types and taxonomies. The post types separate my blog posts from my story content.

  • Custom post types
    • Episodes (you could do chapters)
    • Stories
  • Custom taxonomies
    • Series
    • Genres
    • Visibility (to control who can see what episode)

To do this, I used a plugin called Advanced Custom Fields.

I created Stories, which are each part of a series. I set visibilities for each episode, and my story content goes into each episode.

One of my tiers gets early access to new episodes. In order to accomplish this, I used a plugin called PublishPress Future, which allows me to change the Visibility after a certain number of days.

Inline Comments

One of the most exciting features on Ream for me was inline comments. As a reader, I LOVE being able to react or comment inline on stories by my favorite authors! If a paragraph is funny, I can react with a laughing face to that particular paragraph. If a character does something I disagree with, I can comment with a “Don’t do it, girl!”

However, during my time on Ream, I’ve rarely seen inline comments used by readers. And the alternative is chapter-based comments, which is typical on platforms like Wattpad and Kindle Vella. So while I think it’s a great feature, it may not be entirely necessary.

Based on my research, plugins were developed for inline commenting once upon a time for WordPress. However, most of them are no longer supported. I did come across a plugin called Comments – WPDiscuz which, in its free version, supports inline commenting, but you have to manually add the comment tag to paragraphs where you want commenting to be added. That’s a lot of work for something that will only rarely be used.

Update: I decided to keep Comments – WP Discuz installed because I like the user interface it provides for comments.

This is something I’d like to look into further someday, but currently, it’s not a priority.

Flexible Reading Experience

Why have ebooks become so popular? Is it only because you can fit so many ebooks on one device? Maybe, but I’d wager that a big part of it is the ability to customize your reading experience. On Laterpress and Ream, you can adjust your personal reading experience. Make the text bigger or smaller, change to dark mode, or change fonts at your whim!

This is important to me because it’s a question of accessibility. I’ve employed an accessibility plugin to fill in some of the gaps. I’m using a plugin called One Click Accessibility. It’s not a perfect analogue of ereader functionality, but I do think it provides the necessary functionality to make my website more accessible.

This plugin allows users to increase or decrease text size, switch to grayscale, high contrast, negative contrast, or light background mode, underline links, or change the font to a more readable font.

A green square with a wheelchair icon has been clicked, opening a side panel of accessibility tools. The available options are Increast Text, Decrease Text, Grayscale, High Contrast, Negative Contrast, Light Background, Links Underline, Readable Font, and Reset.
Options available to users from the One Click Accessibility menu

Disabling Select Text

Many platforms make it difficult to select text, thus reducing the ease of pirating someone’s work. Now, if someone wants to pirate a story, they’ll figure out a way to do it, but we don’t have to make it easy for them. Luckily, this can be achieved with some additional code.

I use the plugin Code Snippets to add the following PHP to only my posts (not pages) so that if text is selected, it can’t be copied.

add_action('wp_head', 'smartRightClick');
function smartRightClick()
{ 
	if( is_single() && 'post' == get_post_type() ) {
	?>
		<script>
		function addLink() {
		var selection = window.getSelection();         
		pagelink = "This website does not allow copying text.";         
		copytext = pagelink;         
		newdiv = document.createElement('div');         
		newdiv.style.position = 'absolute';         
		newdiv.style.left = '-99999px';         
		document.body.appendChild(newdiv);         
		newdiv.innerHTML = copytext;         
		selection.selectAllChildren(newdiv);         
		window.setTimeout(function () {         
		document.body.removeChild(newdiv);         
		}, 100);         
		}         
		document.addEventListener('copy', addLink);  
		</script>     
<?php } 
}

And I also have implemented the following CSS to disable selecting text on posts only.

/* Disable right click in single posts */
.single-post .single-content *{ 
-webkit-touch-callout: none; /* iOS Safari */  
-webkit-user-select: none; /* Safari */  
-khtml-user-select: none; /* Konqueror HTML */  
-moz-user-select: none; /* Old versions of Firefox */  
-ms-user-select: none; /* Internet Explorer/Edge */  
user-select: none; /* Non-prefixed version, currently supported by Chrome, Opera and Firefox */ } 

Navigation

A key feature to ANY serial reading platform is the ability to navigate from one chapter to another. This would be straightforward if WordPress, by default, limited the Next and Previous links to only a specific category. Unfortunately, it does not.

I found a php snippet that can be used to handle this. Again, I’m using Code Snippets to add the following php code to my site. However, this will affect all categories, so if you need it to work only for specific categories (ie, your story categories), you’ll likely need to modify the code.

add_filter( 'next_post_link',     'my_adjacent_post_link', 10, 5 );
add_filter( 'previous_post_link', 'my_adjacent_post_link', 10, 5 );

function my_adjacent_post_link( $output, $format, $link, $post, $adjacent )
{
	$previous = 'previous' === $adjacent;

	if ( ! ( $previous && is_attachment() ) ) {
		$post = get_adjacent_post( true, '', $previous, 'category' );
	}

	if ( ! $post ) {
		$output = '';
	} else {
		$title = $post->post_title;

		if ( empty( $post->post_title ) ) {
			$title = $previous ? __( 'Previous Post' ) : __( 'Next Post' );
		}

		$title = apply_filters( 'the_title', $title, $post->ID );

		$date = mysql2date( get_option( 'date_format' ), $post->post_date );
		$rel  = $previous ? 'prev' : 'next';

		$string = '<a href="' . get_permalink( $post ) . '" rel="' . $rel . '">';
		$inlink = str_replace( '%title', $title, $link );
		$inlink = str_replace( '%date', $date, $inlink );
		$inlink = $string . $inlink . '</a>';

		$output = str_replace( '%link', $inlink, $format );
	}

	return $output;
}

Additionally, navigation around the different pages of my membership required me to create a new sidebar. All of my membership pages use a sidebar layout with this new sidebar, which links to the Community News Feed, Stories, My Profile, and Change Password pages. If I add more restricted pages, I can add a link to the sidebar and it’ll show up on all of the membership pages.

I also have created a sidebar specific to each series (using a plugin called Sidebar Manager) that gives you relevant links to that series.

Notify Users of New Posts

Since my plan is to publish stories in a series of WordPress posts (organized into categories), I need a way to notify users when a new chapter/post is published. None of the membership plugins I evaluated do this, even though it seems like such a critical feature!

Luckily, there are a wide variety of plugins already available to take care of this in WordPress. I’ve decided to use MailPoet for this. For now, users can sign up for 2 lists: Community Posts and Story Updates. Currently, I’ve decided to implement an additional sign up form once users become a member to ensure they’ve opted in to being notified and comply with privacy laws and email best practices. But in the future, I’d like to be able to combine this all into one step when they sign up. Update: MailPoet didn’t work out because it will only send email notifications for PUBLIC posts.

Instead, I’ve decided to use PublishPress Planner‘s Notification settings. There, I’m able to ensure that members only get email notifications for content they have access to based on their user role. The downside is that there’s no “subscribe” or “unsubscribe” feature. To accommodate that, my current strategy is to add a message to the signup form and to add a message at the bottom of all emails that indicates that users can email me to unsubscribe. It’s not ideal, but it’s better than nothing.

Hopefully I won’t get many requests to unsubscribe from one or more kinds of updates. But if I get requests, I’ll need to remove the related user role from the user. Currently, one tier-specific role controls all notifications. I may choose to automate and streamline this in the future.

I’m managing these user roles by assigning a tier-specific user role on signup (user roles were created with the plugin User Role Editor), then I use a custom script to assign the ARMember role automatically to any new user who has a tier-specific role.

function add_armember_role ( $user_id ) {
	$u = new \WP_User( $user_id );
        $roles_and_caps = $u->get_role_caps();
	if ( 
		in_array( 'tier1', (array) $roles_and_caps ) || 
		in_array( 'tier2', (array) $roles_and_caps ) || 
		in_array( 'tier3', (array) $roles_and_caps ) )) {
 
    		$u->add_role( 'armember' );
	}
}

add_action( 'user_register', 'add_armember_role' );

Glossary

Now here’s a feature I haven’t found anywhere else! I write science fantasy, which means there is a lot of terminology to remember. In my ebooks, I link words to a “Compendium” at the back, which has definitions and more silly stories related to the words.

I wanted to implement something similar for reading on my site. I chose to use the plugin Glossary by Codeat for this. It highlights terms, shows a tooltip when the user hovers over it, and links to the glossary article when the user clicks it. This is definitely one of those plugins that I’ll pay for once I can cover the cost of the Pro version!

The word "alternate realities" is highlighted in an article. Above it is a dark grey tooltip that reads "Imagine a world where one event occurred differently than in your reality, and where that difference led to another difference until the differences snowballed into a world very different than the one you know and (arguably) enjoy. Speaking of snowballing, traveling between realities can feel like you've been hit with... More. The word more is a link.
An example of the tooltip shown when a user hovers over a term in the glossary.

Reading Progress & Bookmarks

UPDATE: The bookmarking didn’t end up working out. I wasn’t able to apply it to custom post types, which is how I’m creating my episodes. I couldn’t find a replacement, so I scrapped the idea for now.

Users need to be able to bookmark their place in a story. An ideal situation would auto-save their last reading location, but unfortunately, I haven’t seen anything like that for WordPress.

The best I could come up with is to provide Bookmarks with the CBX Bookmark & Favorite plugin. This will allow users to manage and save their place at the post level. So, if they stop at the end of a post, they can save a bookmark and easily get back to it. My only complaint with this plugin is that you can’t place the bookmark link at the top and bottom of the post.

The bookmark icon with the work Bookmark after it. A popup is just below it, prompting the user to select a category to add the bookmark to. The user can also add, manage, or search existing categories.
The popup that appears when a user clicks the bookmark link at the end of a post.

Other Customizations

Custom backgrounds per series

That’s right. The page background changes based on the story members are reading. I love this little extra flavor because it can set the vibe for the reading experience. I’m still working on preparing the art for each story, but here’s a screenshot to give you an idea.

I’m doing this by creating a custom body class based on the story the episode is a part of. To set the class, I use the following script. I also add an “episode” class to limit this change to only episodes.

add_filter('body_class','add_category_to_single');
  function add_category_to_single($classes) {
    if (is_single() ) {
      global $post;
      foreach((get_the_category($post->ID)) as $category) {
        // add category slug to the $classes array
        $classes[] = $category->category_nicename;
      }
		if($post->is_episode === true){ 
  			$post->addClass('episode'); 
		} 
    }
    // return the $classes array
    return $classes;
  }

The next step is to add some custom CSS to the site, one record for each background image.

body.tovy-01-tmatmd, body.tovy-02-tpatmc, body.tovy-03-tsatrohl, body.tovy-04-tratc, body.tovy-05-teatbm, body.tovy-00-ttatl, body.tovy-shorts {
background: url("/path/to/file/ToVY-WordPress-Header.jpg") no-repeat fixed 0 0 ;
background-size: cover;
}

Larger base font and hyphenated justified text

To improve readability, I wanted the base font in all my posts and episodes to be larger. I also wanted my font to be justified, and allow for hyphenation for long words. The following CSS did the trick. Note that I had to apply these rules to p (paragraph) tags and li (list) tags.

.single-post .single-content > p, .single-episode .single-content > p, .single-episode .single-content p, .single-episode .single-content li, .single-post .single-content li {
	font-size: 1.5rem;
	line-height: 1.3em;
	letter-spacing: -.4px !important;
	text-align: justify;
	-webkit-hyphens: auto;
        -moz-hyphens: auto;
        -ms-hyphens: auto;
        -o-hyphens: auto;
        word-break:break-word;
        hyphens: auto;
}

Custom blockquote color

This one is a bit indulgent, but I don’t care. I customized the blockquotes so that they’re custom colors for each story. I use blockquotes whenever I’m sharing text that’s being read. It’s simple CSS, but I’m going for a fully immersive experience. I’m able to do it specifically for a story by using the body classes I created earlier.

.read-alboct blockquote {
	border-left: 5px solid #F24218;
}

That’s it so far! With a little research and effort, WordPress can be a great place to host my stories!

What’s your Reaction?
+1
0
+1
1
+1
0
+1
0
+1
0
+1
0
+1
0