Its been a while I have written a tutorial. Well here is another.
Today we are going to learn a DOM manipulation to display fuzzy time (.... ago) in place of actual date and time in various places in our forums.
Yes, I know, it is in core, somewhat, but not everywhere and not with much flexibility. This tutorial is to target that gap only. We will be playing with the frontend using js only, so no core edit, no plugins, no PHP.
Dependency:
This code is dependent to jQuery library, well its already there with MyBB so don't worry about that.
We will be using the awesome jQuery plugin
timeago by Ryan McGeary.
First things first, lets include the plugin in our forums. Open the
headerinclude
template, find
{$stylesheets}
, add
before that:
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/jquery.timeago.min.js"></script>
You can include it in your site by downloading and linking a local copy, if you are not so comfortable / trusting CDNs. For them I am attaching the compressed version of the plugin (only 3.52KB). Download it, extract and upload in
jscripts
folder. Then link as below instead of above:
<script type="text/javascript" src="{$mybb->asset_url}/jscripts/jquery.timeago.min.js"></script>
Save the template for now. We are not done here, we will be back to this template for adding some more codes.
Now we have to deal with an issue. The jquery plugin expects the time format to be in
ISO 8601 format (something like:
2024-04-15T21:10:01Z
). MyBB displays the time in user readable strings which is of no use. Catch is we can always call the corresponding Unix Timestamp in template using different variables (find out, or else ask). Its then easy to convert to an ISO time string. So lets do this. For experiment we are gonna target
forumbit_depth2_forum_lastpost
template. Open the said template and find the variable
{$lastpost_date}
. This variable represents the last post time. We will use this too, as it will be transferred as tooltip. But the corresponding Unix timestamp variable for this is
{$lastpost_data['lastpost']}
. So replace the variable with the following line:
<time class="timeago" data-timestamp="{$lastpost_data['lastpost']}">{$lastpost_date}</time>
Save the template. Up to this everything is fine and backward compatible.
In a no-js scenario the time will display exactly as it was before. So, don't worry about breaking anything.
We have pulled the Unix timestamp in data attribute. Now we have to use that and make the ISO Time String for every available instance in page. Now time to go back to
headerinclude
template. Add the following code at the end of the template:
<script type="text/javascript">
$(function(){
$('time').each(function(){
let stamp = $(this).data('timestamp');
if(isNaN(stamp)){
$(this).removeClass('timeago');
} else {
$(this).attr('datetime', new Date(stamp*1000).toISOString());
}
})
$("time.timeago").timeago();
});
</script>
Save the template finally. Its done now.
See the magic, make a new post and watch the fuzzy time change after a minute (default value) automatically, without refreshing page.
Tutorial is not over, there is something more, but for now its all.
Happy coding