# Hugo behind paywall/membership : conditional rendering

**URL:** <https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793>\
**Category:** support\
**Created:** [March 13, 2024, 2:05am UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793 "2024-03-13T02:05:36Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![aurelienpierre](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/aurelienpierre/32/18358_2.png) [@aurelienpierre](https://discourse.gohugo.io/u/aurelienpierre)\
**Post date:** [March 13, 2024, 2:05am UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/1 "2024-03-13T02:05:36Z")

</div>

I’m almost done completing my migration of WordPress ~~server-side SQL views~~ blogs to Hugo, and the last remaining step is migrating those membership-based ones. The architecture I have in mind is this:

- private\_html/
  - `404.html`
  - non-members/ → Hugo-rendered website
  - members/ → Hugo-rendered website

- public\_html/
  - `.htaccess`
  - `index.php`
  - `login.php`
  - `subscribe.php`
  - `account.php`

`.htaccess` would handle URL rewriting to `index.php`:

```htaccess
RewriteEngine On
RewriteBase /
# Redirect all traffic to index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php [QSA,L]

```

`index.php` would do the triage:

```php
// Get the full URL before redirection by .htaccess
$parsed_url = parse_url($_SERVER['REQUEST_URI']);

// Separate domain from path
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '/';

$PUBLIC = '../public_html/non-members';
$PRIVATE = '../public_html/members';

$is_logged_in = is_valid($_COOKIE["token"]);

// Redirect the path to the static website pages
switch($path) {
  // PHP endpoints
  case "/login.php":
  case "/account.php":
  case "/subscribe.php":
    require_once($path);
    break;

  // Regular pages
  default:
    $member_target = $PRIVATE . $path . 'index.html';
    $nomember_target = $PUBLIC . $path . 'index.html';

    if($is_logged_in && file_exists($member_target))
      require_once($member_target);
    else if(file_exists($nomember_target))
      require_once($nomember_target);
    else
      require_once('../public_html/404.html');
    break;
}

```

Now, given that Hugo doesn’t seem to have ways of producing content alternatives, I’m thinking of using a shortcode that would output the full page content if _some compilation flag_ is set, otherwise a truncated content or notification message. Then, `private_html/members` and `private_html/non-members` would each have the full website, one compiled with full content, the other with the truncated content.

Question is: how can I map a shortcode output to a custom building flag ?

Or is it a better way ?

---

<div class="post-metadata">

**Author:** ![iaeiou](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/iaeiou/32/15332_2.png) [@iaeiou](https://discourse.gohugo.io/u/iaeiou)\
**Post date:** [March 13, 2024, 9:07am UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/2 "2024-03-13T09:07:52Z")

</div>

Netlify provides a (paid) feature for password/membership protected sites:

> **[Site Protection overview](https://docs.netlify.com/security/secure-access-to-sites/site-protection/)**
>
> Use Site Protection to customize how visitors access your site. Configure protection for all site deploys or only Deploy Previews and branch deploys.

---

<div class="post-metadata">

**Author:** ![aurelienpierre](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/aurelienpierre/32/18358_2.png) [@aurelienpierre](https://discourse.gohugo.io/u/aurelienpierre)\
**Post date:** [March 13, 2024, 2:15pm UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/3 "2024-03-13T14:15:05Z")

</div>

Thanks but that’s obviously not what I’m after. I want stuff that works on regular LAMP servers and can be moved in the future to any other LAMP server. Also, no way I’m going to host anything that matters in Trumperica, I want my servers in Europe.

---

<div class="post-metadata">

**Author:** ![aurelienpierre](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/aurelienpierre/32/18358_2.png) [@aurelienpierre](https://discourse.gohugo.io/u/aurelienpierre)\
**Post date:** [March 13, 2024, 2:34pm UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/4 "2024-03-13T14:34:21Z")

</div>

So I guess, the path of least resistance is to use [config environments](https://gohugo.io/getting-started/configuration/#example), have a `_default` one with common options, then a `members` and a `nomembers` ones which declare some `[Site.Parameters]` boolean key, and have content respond to this boolean. Then build with `hugo -e members` or `hugo -e nomembers`.

And for user management, [https://www.userfrosting.com/](https://www.userfrosting.com/) seems KISS enough.

---

<div class="post-metadata">

**Author:** ![nternetinspired](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nternetinspired/32/19706_2.png) [@nternetinspired](https://discourse.gohugo.io/u/nternetinspired)\
**Post date:** [March 14, 2024, 1:46pm UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/5 "2024-03-14T13:46:15Z")

</div>

No disrespect, but wouldn’t it just be easier to use a CMS? I love Hugo, but it’s not always the best choice.

---

<div class="post-metadata">

**Author:** ![aurelienpierre](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/aurelienpierre/32/18358_2.png) [@aurelienpierre](https://discourse.gohugo.io/u/aurelienpierre)\
**Post date:** [March 14, 2024, 3:52pm UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/6 "2024-03-14T15:52:48Z")

</div>

Yes, it would be easier to have a CMS. That’s what I have now.

Then, you would have to install some plugin on said CMS to support Markdown syntax, then another to add auto table of contents. That’s assuming the CMS content editor doesn’t mess up and/or second-guess your syntax.

Then you would have to install a SEO plugin to get proper metadata in `<head>` and produce a `sitemap.xml`, because very few CMS have that in core. You need a way to discard those taxinomies archive pages from there, because they duplicate contents as for as search engine are concerned.

Then you would need to find a theme that looks reasonably close to what you want and is not coded with the butt, that is loading lots of static files even though you don’t use them. If you don’t find one, then you would have to design your own theme, but while Hugo lets you theme & template stuff as you need them, CMS need to have many endpoints covered from the start. Or you could use one of “page builder” themes that are slow in your browser, heavy on your server, and break every next update.

Then you would need a way to figure out multilanguage, because that has been a second thought in pretty much all CMS, so here you go, stacking crappy plugins on top of crappy plugins, hoping they play nice with each other (they won’t).

Then, of course, since all that is heavy on the server, you need a caching system. One that plays nice with all the aforementionned plugins, but again, very few CMS have that in core, so it’s another third-party plugin. Plugin’s user support love nothing more than blaming the caching plugin for everything remotely affecting their product, it’s never them.

Finally, you would need to mind the garbage collection in your database : multilinguage duplicates content, but duplicates metadata too, plus adds lots of stuff. Plugins you de-install don’t necessarily clean up after themselves. Neither do logs. One day you wake up, your 120-pages blog has a database of 600 MB, and you wonder why.

Not to mention, a dynamic CMS is a living organism that you need to keep updated all the time, for safety. But then, updates will create new bugs and incompatibilites, so you have to commit forever into maintaining it, the funniest part is it will break when you have the least amount of time to fix (Murphy’s law).

So, no its not easier with a CMS. Hugo does all the above in core. It’s no big deal scripting custom stuff in Hugo. Your Hugo scripts will have zero security issue for obvious reasons. It’s like doing LaTeX in your browser. If a future Hugo version breaks older templates, you just re-download the previous 80 MB Go package known to work, put it in your project directory, and keep building with that. You don’t even need it system-wide.

All the CMS-y part needed is a thin layer of PHP acting as firewall on top and directing users to a variant of the website based on the value of some cookie.

* * *

PS: I didn’t even mention responsive image sizes support or account security…

---

<div class="post-metadata">

**Author:** ![nternetinspired](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nternetinspired/32/19706_2.png) [@nternetinspired](https://discourse.gohugo.io/u/nternetinspired)\
**Post date:** [March 14, 2024, 4:48pm UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/7 "2024-03-14T16:48:49Z")

</div>

Think maybe you should look at something other than Wordpress. I have none of the problems you describe.

---

<div class="post-metadata">

**Author:** ![aurelienpierre](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/aurelienpierre/32/18358_2.png) [@aurelienpierre](https://discourse.gohugo.io/u/aurelienpierre)\
**Post date:** [March 14, 2024, 5:08pm UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/8 "2024-03-14T17:08:48Z")

</div>

What CMS are you using ?

---

<div class="post-metadata">

**Author:** ![nternetinspired](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/nternetinspired/32/19706_2.png) [@nternetinspired](https://discourse.gohugo.io/u/nternetinspired)\
**Post date:** [March 15, 2024, 9:28am UTC](https://discourse.gohugo.io/t/hugo-behind-paywall-membership-conditional-rendering/48793/9 "2024-03-15T09:28:10Z")

</div>

[Craft,](https://craftcms.com/) mostly.
