diff options
author | Christian Cleberg <hello@cleberg.net> | 2023-12-02 23:27:35 -0600 |
---|---|---|
committer | Christian Cleberg <hello@cleberg.net> | 2023-12-02 23:27:35 -0600 |
commit | 3d4da5ac6000a4871c5caa80d1e61f2782da3069 (patch) | |
tree | 29f36b50823d22f4c7df0a3db3ede83192ae649f /blog/2021-04-23-php-comment-system.org | |
parent | dcf0186e16b6ac8f0e00a3aeb9734421ce548177 (diff) | |
download | cleberg.net-3d4da5ac6000a4871c5caa80d1e61f2782da3069.tar.gz cleberg.net-3d4da5ac6000a4871c5caa80d1e61f2782da3069.tar.bz2 cleberg.net-3d4da5ac6000a4871c5caa80d1e61f2782da3069.zip |
feat: finish converting md to org
Diffstat (limited to 'blog/2021-04-23-php-comment-system.org')
-rw-r--r-- | blog/2021-04-23-php-comment-system.org | 374 |
1 files changed, 198 insertions, 176 deletions
diff --git a/blog/2021-04-23-php-comment-system.org b/blog/2021-04-23-php-comment-system.org index 50c77f1..d539a4e 100644 --- a/blog/2021-04-23-php-comment-system.org +++ b/blog/2021-04-23-php-comment-system.org @@ -1,151 +1,161 @@ -+++ -date = 2021-04-23 -title = "Roll Your Own Static Commenting System in PHP" -description = "Learn how to skip the tedium of finding the proper commenting system by simply rolling your own in PHP." -draft = false -+++ +#+title: Roll Your Own Static Commenting System in PHP +#+date: 2021-04-23 -## The Terrible-ness of Commenting Systems +** The Terrible-ness of Commenting Systems +:PROPERTIES: +:CUSTOM_ID: the-terrible-ness-of-commenting-systems +:END: +The current state of affairs regarding interactive comment systems is, +well, terrible. It is especially awful if you're a privacy conscious +person who does not generally load third-party scripts or frames on the +websites you visit. -The current state of affairs regarding interactive comment systems is, well, -terrible. It is especially awful if you're a privacy conscious person who does -not generally load third-party scripts or frames on the websites you visit. - -Even further, many comment systems are charging exorbitant fees for something -that should be standard. +Even further, many comment systems are charging exorbitant fees for +something that should be standard. Of course, there are some really terrible options: -- Facebook Comments -- Discourse - -There are some options that are better but still use too many scripts, frames, -or social integrations on your web page that could impact some users: - -- Disqus -- Isso -- Remark42 - -Lastly, I looked into a few unique ways of generating blog comments, such as -using Twitter threads or GitHub issues to automatically post issues. However, -these both rely on external third-party sites that I don't currently use. - -## Stay Static with Server-Side Comments - -The main issue for my personal use-case is that my blog is completely, 100% -static. I use PHP on the back-end but website visitors only see HTML and a -single CSS file. No external javascript and no embedded frames. - -So, how do we keep a site static and still allow users to interact with blog -posts? The key actually pretty simple - I'm already using PHP, so why not rely -on the classic HTML `<form>` and a PHP script to save the comments somewhere? As -it turns out, this was a perfect solution for me. - -The second issue for my personal use-case is that I am trying to keep the -contents of my website accessible over time, as described by @brandur, in his -post entitled -[Blog with Markdown + Git, and degrade gracefully through time](https://brandur.org/fragments/graceful-degradation-time) -. - -This means I cannot rely on a database for comments, since I do not rely on a -database for any other part of my websites. - -I blog in plain Markdown files, commit all articles to Git, and ensure that -future readers will be able to see the source data long after I'm gone, or the -website has gone offline. However, I still haven't committed any images served -on my blog to Git, as I'm not entirely sold on Git LFS yet - for now, images can -be found at [img.cleberg.net](https://img.cleberg.net). - -Saving my comments back to the Git repository ensures that another aspect of my -site will degrade gracefully. - -## Create a Comment Form - -Okay, let's get started. The first step is to create an HTML form that users can -see and utilize to submit comments. This is fairly easy and can be changed -depending on your personal preferences. - -Take a look at the code block below for the form I currently use. Note that -`<current-url>` is replaced automatically in PHP with the current post's URL, so -that my PHP script used later will know which blog post the comment is related -to. +- Facebook Comments +- Discourse + +There are some options that are better but still use too many scripts, +frames, or social integrations on your web page that could impact some +users: + +- Disqus +- Isso +- Remark42 + +Lastly, I looked into a few unique ways of generating blog comments, +such as using Twitter threads or GitHub issues to automatically post +issues. However, these both rely on external third-party sites that I +don't currently use. + +** Stay Static with Server-Side Comments +:PROPERTIES: +:CUSTOM_ID: stay-static-with-server-side-comments +:END: +The main issue for my personal use-case is that my blog is completely, +100% static. I use PHP on the back-end but website visitors only see +HTML and a single CSS file. No external javascript and no embedded +frames. + +So, how do we keep a site static and still allow users to interact with +blog posts? The key actually pretty simple - I'm already using PHP, so +why not rely on the classic HTML =<form>= and a PHP script to save the +comments somewhere? As it turns out, this was a perfect solution for me. + +The second issue for my personal use-case is that I am trying to keep +the contents of my website accessible over time, as described by +[cite/t:@brandur], in his post entitled +[[https://brandur.org/fragments/graceful-degradation-time][Blog with +Markdown + Git, and degrade gracefully through time]] . + +This means I cannot rely on a database for comments, since I do not rely +on a database for any other part of my websites. + +I blog in plain Markdown files, commit all articles to Git, and ensure +that future readers will be able to see the source data long after I'm +gone, or the website has gone offline. However, I still haven't +committed any images served on my blog to Git, as I'm not entirely sold +on Git LFS yet - for now, images can be found at +[[https://img.cleberg.net][img.cleberg.net]]. + +Saving my comments back to the Git repository ensures that another +aspect of my site will degrade gracefully. + +** Create a Comment Form +:PROPERTIES: +:CUSTOM_ID: create-a-comment-form +:END: +Okay, let's get started. The first step is to create an HTML form that +users can see and utilize to submit comments. This is fairly easy and +can be changed depending on your personal preferences. + +Take a look at the code block below for the form I currently use. Note +that =<current-url>= is replaced automatically in PHP with the current +post's URL, so that my PHP script used later will know which blog post +the comment is related to. The form contains the following structure: -1. `<form>` - This is the form and will determine which PHP script to send the - comment to. -2. `<section hidden>` - This section is hidden from the user and is used to - ensure that we know which blog post sent the comment. -3. `<section>` Display Name (Optional) - Used to accept a display name, if - entered. -4. `<section>` Comment (Required) - Used to accept the user's full comment. - Markdown is allowed. -5. `<button>` - A button to submit the form. - -```html +1. =<form>= - This is the form and will determine which PHP script to + send the comment to. +2. =<section hidden>= - This section is hidden from the user and is used + to ensure that we know which blog post sent the comment. +3. =<section>= Display Name (Optional) - Used to accept a display name, + if entered. +4. =<section>= Comment (Required) - Used to accept the user's full + comment. Markdown is allowed. +5. =<button>= - A button to submit the form. + +#+begin_src html <form action="/comment.php" method="POST"> - <h3>Leave a Comment</h3> - <section hidden> - <label class="form-label" for="postURL">Post URL</label> - <input - class="form-control" - id="postURL" - name="postURL" - type="text" - value="<current-url>" - /> - </section> - <section> - <label class="form-label" for="userName">Display Name</label> - <input - class="form-control" - id="userName" - name="userName" - placeholder="John Doe" - type="text" - /> - </section> - <section> - <label class="form-label" for="userContent">Your Comment</label> - <textarea - class="form-control" - id="userContent" - name="userContent" - rows="3" - placeholder="# Feel free to use Markdown" - aria-describedby="commentHelp" - required - ></textarea> - <div id="commentHelp" class="form-text"> - Comments are saved as Markdown and cannot be edited or deleted. - </div> - </section> - <button type="submit">Submit</button> + <h3>Leave a Comment</h3> + <section hidden> + <label class="form-label" for="postURL">Post URL</label> + <input + class="form-control" + id="postURL" + name="postURL" + type="text" + value="<current-url>" + /> + </section> + <section> + <label class="form-label" for="userName">Display Name</label> + <input + class="form-control" + id="userName" + name="userName" + placeholder="John Doe" + type="text" + /> + </section> + <section> + <label class="form-label" for="userContent">Your Comment</label> + <textarea + class="form-control" + id="userContent" + name="userContent" + rows="3" + placeholder="# Feel free to use Markdown" + aria-describedby="commentHelp" + required + ></textarea> + <div id="commentHelp" class="form-text"> + Comments are saved as Markdown and cannot be edited or deleted. + </div> + </section> + <button type="submit">Submit</button> </form> -``` - -## Handle Comments via POST +#+end_src -Now that we have a form and can submit comments, we need to create a PHP script -so that the server can fetch the comment data and save it. Make sure your PHP -script name matches the name you entered in the `action` field in your form. +** Handle Comments via POST +:PROPERTIES: +:CUSTOM_ID: handle-comments-via-post +:END: +Now that we have a form and can submit comments, we need to create a PHP +script so that the server can fetch the comment data and save it. Make +sure your PHP script name matches the name you entered in the =action= +field in your form. -See the code block below for the contents of my `comment.php` script. We perform -the following tasks in this script: +See the code block below for the contents of my =comment.php= script. We +perform the following tasks in this script: 1. Grab the POST data from the HTML form. -2. Sanitize the comment data with `htmlentities`. -3. Set the display name to `Anonymous` if it was left blank. +2. Sanitize the comment data with =htmlentities=. +3. Set the display name to =Anonymous= if it was left blank. 4. Create a PHP object that combines all of this data. -5. Check if our destination file `comments.json` exists. +5. Check if our destination file =comments.json= exists. 6. If so, convert the PHP object to JSON and save it to the file. -7. If the `comments.json` file does not exist, the script will exit with an - error. You can alter this to ensure it creates the script, but my source code - includes the file by default, so it will always exist. -8. Finally, send the user back to the `#comments` section of the blog post they - just read. +7. If the =comments.json= file does not exist, the script will exit with + an error. You can alter this to ensure it creates the script, but my + source code includes the file by default, so it will always exist. +8. Finally, send the user back to the =#comments= section of the blog + post they just read. -```php +#+begin_src php // Get the content sent from the comment form $comment = htmlentities($_POST['userContent']); $post_url = $_POST['postURL']; @@ -180,30 +190,35 @@ if (file_exists($file_name)) { // Send the user back header('Location: ' . $post_url . '#comments'); -``` +#+end_src -If you're using Apache, make sure the `www-data` user on your server has the -correct permissions to your website directory or else it will not be able to -write to `comments.json`. +If you're using Apache, make sure the =www-data= user on your server has +the correct permissions to your website directory or else it will not be +able to write to =comments.json=. -```sh +#+begin_src sh chgrp -R www-data /path/to/website/ chmod -R g+w comments.json -``` - -## Display User Comments - -Now that we can submit comments, and they are saved to the `comments.json` file, -let's make sure we can show those comments in each blog post. - -The code block below shows the function I use to decode my `comments.json` file, -check if the comments apply to the current post, and then display them. - -This piece of code should **really** be inside a function (or at least in an -organized PHP workflow). Don't just copy-and-paste and expect it to work. You -need to at least supply a `$query` variable depending on the page visited. - -```php +#+end_src + +** Display User Comments +:PROPERTIES: +:CUSTOM_ID: display-user-comments +:END: +Now that we can submit comments, and they are saved to the +=comments.json= file, let's make sure we can show those comments in each +blog post. + +The code block below shows the function I use to decode my +=comments.json= file, check if the comments apply to the current post, +and then display them. + +This piece of code should *really* be inside a function (or at least in +an organized PHP workflow). Don't just copy-and-paste and expect it to +work. You need to at least supply a =$query= variable depending on the +page visited. + +#+begin_src php $query = 'your-blog-post.html'; // Load saved comments @@ -235,28 +250,35 @@ foreach ($comments as $comment) { } echo $comment_section; -``` - -## Bonus: Create a 'Recent Comments' Page - -Finally, the last part of my current system is to create a Recent Comments page -so that I can easily check-in on my blog and moderate any spam. As an -alternative, you could use PHP's `mail()` function to email you for each blog -comment. - -The code to do this is literally the same code as the previous section, I just -make sure it is printed when someone visits `https://example.com/comments/`. - -## Possible Enhancements - -This comment system is by no means a fully-developed system. I have noted a few -possible enhancements here that I may implement in the future: - -- Create a secure moderator page with user authentication at - `https://blog.example.com/mod/`. This page could have the option to edit or - delete any comment found in `comments.json`. -- Create a temporary file, such as `pending_comments.json`, that will store - newly-submitted comments and won't display on blog posts until approved by a - moderator. -- Create a `/modlog/` page with a chronological log, showing which moderator - approved which comments and why certain comments were rejected. +#+end_src + +** Bonus: Create a 'Recent Comments' Page +:PROPERTIES: +:CUSTOM_ID: bonus-create-a-recent-comments-page +:END: +Finally, the last part of my current system is to create a Recent +Comments page so that I can easily check-in on my blog and moderate any +spam. As an alternative, you could use PHP's =mail()= function to email +you for each blog comment. + +The code to do this is literally the same code as the previous section, +I just make sure it is printed when someone visits +=https://example.com/comments/=. + +** Possible Enhancements +:PROPERTIES: +:CUSTOM_ID: possible-enhancements +:END: +This comment system is by no means a fully-developed system. I have +noted a few possible enhancements here that I may implement in the +future: + +- Create a secure moderator page with user authentication at + =https://blog.example.com/mod/=. This page could have the option to + edit or delete any comment found in =comments.json=. +- Create a temporary file, such as =pending_comments.json=, that will + store newly-submitted comments and won't display on blog posts until + approved by a moderator. +- Create a =/modlog/= page with a chronological log, showing which + moderator approved which comments and why certain comments were + rejected. |