A legend has left us. On the 19th of this month, one
Chuck Norris, martial artist and action movie icon, passed away. One of the things that really stood out in the Chuck Norris mythos was... well, the Chuck Norris mythos. Remember back in the 2000s, how popular "Chuck Norris facts" became?
Well, today, in loving ass-kicking memory, we'll do something like this! It'll be a page that returns a random Chuck Norris fact each time. But this is a tech blog, so the fact has to be tech-based! And this is an image that we'll be using, which I generated using
Meta AI.
 |
| chucknorris.jpg |
Let's begin by creating a PHP page. We'll deal with the HTML portion first. We'll also use some jQuery UI to create nice animations. Note that in the body, we have div tags styled using the CSS classes
number,
fact and
rip.
<!DOCTYPE html>
<html>
<head>
<title>In Memory of Chuck Norris</title>
<style>
</style>
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
<script src="https://code.jquery.com/ui/1.13.3/jquery-ui.js"></script>
<script>
</script>
</head>
<body>
<div class="number"></div>
<br />
<div class="fact"></div>
<div class="rip">R.I.P 19<sup>th</sup> March 2026</div>
</body>
</html>
Let's add some PHP. This currently is just one line, declaring
fact as a string. The value is one of my favorite Chuck Norris "facts". In the div styled using the CSS class
fact, display the value of
fact. And in the div styled using the CSS class
number, let's have a random number to humorously display which number this "fact" is supposed to be.
<?php
$fact = "Chuck Norris can divide by zero";
?>
<!DOCTYPE html>
<html>
<head>
<title>In Memory of Chuck Norris</title>
<style>
</style>
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
<script src="https://code.jquery.com/ui/1.13.3/jquery-ui.js"></script>
<script>
</script>
</head>
<body>
<div class="number">Fact #<?php echo rand(100, 100000); ?>:</div>
<br />
<div class="fact"><?php echo $fact; ?></div>
<div class="rip">R.I.P 19<sup>th</sup> March 2026</div>
</body>
</html>
This is just text right now.
Now let's style the
body tag. We first want to use the image as a background.
<style>
body
{
background: url(chucknorris.jpg) left top no-repeat;
background-size: cover;
}
</style>
Then we want to style the text. I made it large font, with a
white outline using the
text-shadow property.
<style>
body
{
background: url(chucknorris.jpg) left top no-repeat;
background-size: cover;
font-size: 60px;
font-family: georgia;
text-shadow: -2px -2px 2px rgb(255, 255, 255), 2px -2px 2px rgb(255, 255, 255), -2px 2px 2px rgb(255, 255, 255), 2px 2px 2px rgb(255, 255, 255);
}
</style>
Nice contrast, eh?
Now let's focus on the CSS classes
number,
fact and
rip. It's mostly positional. I made
number bolder and floated it left.
fact is also floated left.
rip has
position property set to
fixed and is anchored to the bottom right of the screen via the
right and
bottom properties. I'ave also adjusted the font size.
<style>
body
{
background: url(chucknorris.jpg) left top no-repeat;
background-size: cover;
font-size: 60px;
font-family: georgia;
text-shadow: -2px -2px 2px rgb(255, 255, 255), 2px -2px 2px rgb(255, 255, 255), -2px 2px 2px rgb(255, 255, 255), 2px 2px 2px rgb(255, 255, 255);
}
.number
{
font-weight: bold;
width: 10em;
float: left;
}
.fact
{
width: 20em;
float: left;
}
.rip
{
font-size: 0.5em;
height: 1.5em;
position: fixed;
bottom: 0;
right: 0;
}
</style>
See what I mean?
OK, next up... animation! For this, we want to set the display property of the fact CSS class, to none. This effectively hides the "fact". That's because we want to use jQuery to make it fade in.
.fact
{
width: 20em;
float: left;
display: none;
}
In the
script tag, do this so that the code only runs once the HTML is loaded.
<script>
$(document).ready(function() {
});
</script>
This causes the "fact" to fade in over the course of 5 seconds.
<script>
$(document).ready(function() {
$(".fact").fadeIn(5000);
});
</script>
Then we use the
effect() method on this element. The "bounce" effect belongs to jQuery UI, and here we specify a 1 second duration.
<script>
$(document).ready(function() {
$(".number").effect("bounce", 1000);
$(".fact").fadeIn(5000);
});
</script>
We include an object with the
times property set to 5, so that it bounces 5 times in 1 second. (Sounds like a really lousy credit card, but there you go.)
<script>
$(document).ready(function() {
$(".number").effect("bounce", {times: 5}, 1000);
$(".fact").fadeIn(5000);
});
</script>
See how the "fact" fades in as the "number" bounces!
Now for the most exciting part... leveraging on OpenAI's
ChatGPT to generate a random Chuck Norris "fact". For this, we're leveraging on
ChatGPT's API. First, declare
key,
org and
url. These should already have been set up as a new project in
ChatGPT. Then create
headers as an array of strings. This is what we'll be sending to the URL defined at
url.
<?php
$key = "sk-xxx";
$org = "org-FUOhDblZb1pxvaY6YylF54gl";
$url = "https://api.openai.com/v1/chat/completions";
$headers = [
"Authorization: Bearer " . $key,
"OpenAI-Organization: " . $org,
"Content-Type: application/json"
];
$fact = "Chuck Norris can divide by zero";
?>
We then construct the prompt to send. Here. I specify the JSON object that
ChatGPT should give me, and explicitly specify the value. I want a Chuck Norris "fact", and I also want it to be tech-related. Because those are the ones I love. That's for
content.
role is set to "user". All this is in the array,
obj, which is in turn part of
messages.
<?php
$key = "sk-xxx";
$org = "org-FUOhDblZb1pxvaY6YylF54gl";
$url = "https://api.openai.com/v1/chat/completions";
$headers = [
"Authorization: Bearer " . $key,
"OpenAI-Organization: " . $org,
"Content-Type: application/json"
];
$messages = [];
$obj = [];
$obj["role"] = "user";
$obj["content"] = "Give me a JSON object with one property. The property should be named 'fact'. Its value should be a string. This should be a Chuck Norris 'fact', relating either to internet, email or software. An Example would be 'Chuck Norris can divide by zero.'.";
$messages[] = $obj;
$fact = "Chuck Norris can divide by zero";
?>
Then we create the parent,
data. Here we specify the
model. Then we set
messages, and
max_tokens. This one won't be text-heavy. I reckon 500 tokens should be enough.
<?php
$key = "sk-xxx";
$org = "org-FUOhDblZb1pxvaY6YylF54gl";
$url = "https://api.openai.com/v1/chat/completions";
$headers = [
"Authorization: Bearer " . $key,
"OpenAI-Organization: " . $org,
"Content-Type: application/json"
];
$messages = [];
$obj = [];
$obj["role"] = "user";
$obj["content"] = "Give me a JSON object with one property. The property should be named 'fact'. Its value should be a string. This should be a Chuck Norris 'fact', relating either to internet, email or software. An Example would be 'Chuck Norris can divide by zero.'.";
$messages[] = $obj;
$data = [];
$data["model"] = "gpt-3.5-turbo";
$data["messages"] = $messages;
$data["max_tokens"] = 500;
$fact = "Chuck Norris can divide by zero";
?>
And here's the final use of
cURL, to send data to the API endpoint.
<?php
$key = "sk-xxx";
$org = "org-FUOhDblZb1pxvaY6YylF54gl";
$url = "https://api.openai.com/v1/chat/completions";
$headers = [
"Authorization: Bearer " . $key,
"OpenAI-Organization: " . $org,
"Content-Type: application/json"
];
$messages = [];
$obj = [];
$obj["role"] = "user";
$obj["content"] = "Give me a JSON object with one property. The property should be named 'fact'. Its value should be a string. This should be a Chuck Norris 'fact', relating either to internet, email or software. An Example would be 'Chuck Norris can divide by zero.'.";
$messages[] = $obj;
$data = [];
$data["model"] = "gpt-3.5-turbo";
$data["messages"] = $messages;
$data["max_tokens"] = 500;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
if (curl_errno($curl))
{
echo 'Error:' . curl_error($curl);
}
curl_close($curl);
$fact = "Chuck Norris can divide by zero";
?>
We grab the response and extract the required value. And then we change
fact's value from a hard-coded string, to that extracted value.
<?php
$key = "sk-xxx";
$org = "org-FUOhDblZb1pxvaY6YylF54gl";
$url = "https://api.openai.com/v1/chat/completions";
$headers = [
"Authorization: Bearer " . $key,
"OpenAI-Organization: " . $org,
"Content-Type: application/json"
];
$messages = [];
$obj = [];
$obj["role"] = "user";
$obj["content"] = "Give me a JSON object with one property. The property should be named 'fact'. Its value should be a string. This should be a Chuck Norris 'fact', relating either to internet, email or software. An Example would be 'Chuck Norris can divide by zero.'.";
$messages[] = $obj;
$data = [];
$data["model"] = "gpt-3.5-turbo";
$data["messages"] = $messages;
$data["max_tokens"] = 500;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
if (curl_errno($curl))
{
echo 'Error:' . curl_error($curl);
}
curl_close($curl);
$data = [];
$data["model"] = "gpt-3.5-turbo";
$data["messages"] = $messages;
$data["max_tokens"] = 500;
$result = json_decode($result);
$content = $result->choices[0]->message->content;
$content = json_decode($content);
$fact = $content->fact;
?>
See? The facts change now.
Different fact.
Another different fact.
R.I.P, Mr Norris!
Rumour has it that you've been dead for years. Death just hasn't plucked up the courage to tell you.
Did you know that Chuck Norris can delete the Recycle Bin?
T___T