In 2016, quarterback
Colin Kaepernick made waves when he
opted to take a knee while the United States national anthem was being played before the start of NFL games. There were some who felt this was disrespectful, though, coming from a country where you can literally
wear the flag next to your crotch, I'm really not seeing the problem.
Others saw it as a brave protest against racial injustice. I may be overly cynical here, but all I saw was an aging athlete trying his darnedest to stay relevant. Still... good-looking guy. Great shoulders. Build to die for. And the dramatic shots of him bravely enduring the jeers and abuse to "stand up for his beliefs" sure didn't hurt the narrative.
Fast forward to 2018, and Kaepernick has been made the
new face of
Nike, ostensibly because they were interested in his message. Methinks they were a wee bit more interested in milking the controversy surrounding Kaepernick and turning it into cash, but anyways. The first ad to be displayed was this.
Conservatives started
losing their shit, but I'm not gonna go into that black hole of inanity. Suffice to say, a whole new wave of spoofed memes have been made off this. Brilliant, I say.
Brilliant!
Therefore, today, I'll walk you through how to make your very own Nike Meme Generator!
What you'll need
This will be done in PHP (cue the groans from purist snobs. Bite me, dipshits.) and you'll need an Apache server to run your code. First, create a folder called
uploads and put this picture of Kaepernick in there. It'll be called, quite appropriately,
colinkaepernick.jpg.
Then create
index.php in the main folder. And place this tiny white Nike swoosh in the main folder as well, and call it...
nikelogo.png? It has a transparent background, and we're going to need that transparency.
You may want to refer to a previous web tutorial,
The Asynchronous File Upload, also done in PHP. We'll be copying a fair bit of code from the
repository.
Let's Begin!
This is the HTML we start with.
<!DOCTYPE html>
<html>
<head>
<title>Nike Meme Generator</title>
<style>
</style>
</head>
<body>
</body>
</html>
In the body, we have three divs, ids
pnlMessage,
formContainer and
memeContainer.
pnlMessage is meant to provide user feedback (sucess or failure) while
formContainer will contain the controls.
memeContainer will contain the resulting meme!
<!DOCTYPE html>
<html>
<head>
<title>Nike Meme Generator</title>
<style>
</style>
</head>
<body>
<div id="pnlMessage"></div>
<div id="formContainer">
</div>
<div id="memeContainer">
</div>
</body>
</html>
Got all that? Good. Now here's some styling.
pnlMessage will take up the top. Its text will be
red, it will take up the entire screen's width, and have a height of 50 pixels.
formContainer will have its width, but not height, specified. I've given it and
memeContainer widths, paddings and margins, and the
float property of
left.
Not to mention a
grey outline for all three divs so you can visualize what we're doing here.
memeContainer's width and height will be equal to each other, because it's square.
<!DOCTYPE html>
<html>
<head>
<title>Nike Meme Generator</title>
<style>
#pnlMessage
{
width: 100%;
height: 50px;
color: #FF0000;
outline: 1px solid #DDDDDD;
}
#formContainer
{
width: 400px;
padding: 5px;
margin: 5px;
float: left;
outline: 1px solid #DDDDDD;
}
#memeContainer
{
width: 500px;
height: 500px;
padding: 5px;
margin: 5px;
float: left;
outline: 1px solid #DDDDDD;
}
</style>
</head>
<body>
<div id="pnlMessage"></div>
<div id="formContainer">
</div>
<div id="memeContainer">
</div>
</body>
</html>
Looking right? Now you have a good idea where everything is going to be.
Now do this so that only the outline remains for
memeContainer. The other divs don't need it.
#pnlMessage
{
width: 100%;
height: 50px;
color: #FF0000;
outline: 0px solid #DDDDDD;
}
#formContainer
{
width: 400px;
padding: 5px;
margin: 5px;
float: left;
outline: 0px solid #DDDDDD;
}
#memeContainer
{
width: 500px;
height: 500px;
padding: 5px;
margin: 5px;
float: left;
outline: 1px solid #DDDDDD;
}
Now, within
formContainer, we'll have a form tag. It points to this page itself, and the
enctype attribute needs to be set to "multipart/form-data" because we're using the form to upload an image file. We have three text boxes (for the first and second line of the meme, and the Nike slogan), a file input object, and a submit button. And of course, their respective labels.
As per
The Asynchronous File Upload web tutorial, there's also a hidden field, id
hidUploadSize, that will be used to restrict the size of the file being uploaded. Not
absolutely necessary, but I'm paranoid like that.
<div id="formContainer">
<form id="frmUpload" name="frmUpload" action="" method="POST" enctype="multipart/form-data">
<label for="flUpload">File</label>
<input type="file" name="flUpload" id="flUpload">
<input type="hidden" name="hidUploadSize" id="hidUploadSize" value="50000000">
<br /><br />
<label for="txtLine1">Line 1</label>
<input name="txtLine1" id="txtLine1" maxlength="50" value="" />
<br /><br />
<label for="txtLine2">Line 2</label>
<input name="txtLine2" id="txtLine2" maxlength="50" value="" />
<br /><br />
<label for="txtSlogan">Slogan</label>
<input name="txtSlogan" id="txtSlogan" maxlength="20" value="" />
<br /><br />
<input type="submit" name="btSubmit" id="btSubmit" value="Create your Meme!">
</form>
</div>
This is not a very pretty form, but it's functional and that's all we really need.
Now for some PHP!
At the top of the file, before the doctype declaration, declare a PHP block, then the following variables as defaults. So the default meme will use
colinkaepernick.jpg and the default text will be "Believe in something. Even if it means sacrificing everything.", followed by the slogan "Just Do It.". By default,
strmessage will be an empty string.
<?php
$filecode = "colinkaepernick";
$filetype = "jpg";
$line1 = "Believe in something.";
$line2 = "Even if it means sacrificing everything.";
$slogan = "Just Do It.";
$strmessage="";
?>
<!DOCTYPE html>
Next, we use an
If block to check if a form has been submitted. If so, replace the current values of
line1,
line2 and
slogan with the values POSTed from the form.
$filecode = "colinkaepernick";
$filetype = "jpg";
$line1 = "Believe in something.";
$line2 = "Even if it means sacrificing everything.";
$slogan = "Just Do It.";
$strmessage="";
if (isset($_POST["btSubmit"]))
{
$line1 = $_POST["txtLine1"];
$line2 = $_POST["txtLine2"];
$slogan = $_POST["txtSlogan"];
}
Then check if there's been a file upload. If not, set an error message to
strmessage.
line1,
line2 and
slogan are optional.
if (isset($_POST["btSubmit"]))
{
$line1 = $_POST["txtLine1"];
$line2 = $_POST["txtLine2"];
$slogan = $_POST["txtSlogan"];
if (basename($_FILES["flUpload"]["name"]) != "")
{
}
else
{
$strmessage="No file selected.";
}
}
If there has been an upload, verify that the size of the upload doesn't exceed the size you specified in
hidUploadSize. I don't want to repeat myself; all these steps can be found in the earlier web tutorial.
if (isset($_POST["btSubmit"]))
{
$line1 = $_POST["txtLine1"];
$line2 = $_POST["txtLine2"];
$slogan = $_POST["txtSlogan"];
if (basename($_FILES["flUpload"]["name"]) != "")
{
$uploadsize = intval($_POST["hidUploadSize"]);
$filetype = pathinfo($_FILES["flUpload"]["name"],PATHINFO_EXTENSION);
$filetype = strtolower($filetype);
if ($_FILES["flUpload"]["size"] > $uploadsize)
{
$strmessage = "Error was encountered while uploading file. File cannot exceed " . ($uploadsize/1000) . "kb";
}
else
{
}
}
else
{
$strmessage="No file selected.";
}
}
The next step, however, is
not in the previous web tutorial. Here, we check if the file uploaded is a valid image file. If not, we set the value of
strmessage to an error message.
How, exactly, do we check if it's a valid image file? We certainly can't simply go by the extension. That's one of the easiest things to fake. So what we do, is use the
getimagesize() function in PHP. Pass in the temporary filepath from the
$_FILES["flUpload"] array. If the file is an image, the function should return you an array. Thus, if we use the
is_array() function on the result and it comes back
false, the uploaded file is
not an image file.
if (isset($_POST["btSubmit"]))
{
$line1 = $_POST["txtLine1"];
$line2 = $_POST["txtLine2"];
$slogan = $_POST["txtSlogan"];
if (basename($_FILES["flUpload"]["name"]) != "")
{
$uploadsize = intval($_POST["hidUploadSize"]);
$filetype = pathinfo($_FILES["flUpload"]["name"],PATHINFO_EXTENSION);
$filetype = strtolower($filetype);
if ($_FILES["flUpload"]["size"] > $uploadsize)
{
$strmessage = "Error was encountered while uploading file. File cannot exceed " . ($uploadsize/1000) . "kb";
}
else
{
if (!is_array(getimagesize($_FILES["flUpload"]["tmp_name"])))
{
$strmessage = "File type invalid";
}
else
{
}
}
}
else
{
$strmessage="No file selected.";
}
}
And at this point, you upload the file.
if (isset($_POST["btSubmit"]))
{
$line1 = $_POST["txtLine1"];
$line2 = $_POST["txtLine2"];
$slogan = $_POST["txtSlogan"];
if (basename($_FILES["flUpload"]["name"]) != "")
{
$uploadsize = intval($_POST["hidUploadSize"]);
$filetype = pathinfo($_FILES["flUpload"]["name"],PATHINFO_EXTENSION);
$filetype = strtolower($filetype);
if ($_FILES["flUpload"]["size"] > $uploadsize)
{
$strmessage = "Error was encountered while uploading file. File cannot exceed " . ($uploadsize/1000) . "kb";
}
else
{
if (!is_array(getimagesize($_FILES["flUpload"]["tmp_name"])))
{
$strmessage = "File type invalid";
}
else
{
$filecode=strtotime("now").rand();
if (move_uploaded_file($_FILES["flUpload"]["tmp_name"], "uploads/" . $filecode . "." . $filetype))
{
$strmessage = "File uploaded.";
}
else
{
$strmessage = "Error was encountered while uploading file.";
}
}
}
}
else
{
$strmessage="No file selected.";
}
}
Alter the HTML to show the variable
strmessage.
<div id="pnlMessage"><?php echo $strmessage; ?></div>
Try uploading invalid files, or files that are too big. In this example, I tried to upload a PDF.
And after that, let's add the default variables into the form. Just for the users' convenience.
<form id="frmUpload" name="frmUpload" action="" method="POST" enctype="multipart/form-data">
<label for="flUpload">File</label>
<input type="file" name="flUpload" id="flUpload">
<input type="hidden" name="hidUploadSize" id="hidUploadSize" value="50000000">
<br /><br />
<label for="txtLine1">Line 1</label>
<input name="txtLine1" id="txtLine1" maxlength="50" value="<?php echo $line1; ?>" />
<br /><br />
<label for="txtLine2">Line 2</label>
<input name="txtLine2" id="txtLine2" maxlength="50" value="<?php echo $line2; ?>" />
<br /><br />
<label for="txtSlogan">Slogan</label>
<input name="txtSlogan" id="txtSlogan" maxlength="20" value="<?php echo $slogan; ?>" />
<br /><br />
<input type="submit" name="btSubmit" id="btSubmit" value="Create your Meme!">
</form>
Let's modify the CSS a bit. The
memeContainer div needs to have a background image specified, and in this case, we use
colinkaepernick.jpg as a default (that's what
filecode and
filetype are set to). Make sure it covers the entire square by setting
background-size to
cover. Do whatever you want with the font, but I'd recommend
white. The
filter property is important here. It shows images in greyscale.
#memeContainer
{
width: 500px;
height: 500px;
padding: 5px;
margin: 5px;
float: left;
outline: 1px solid #DDDDDD;
background: url(<?php echo "uploads/" . $filecode . "." . $filetype; ?>) center center no-repeat;
background-size: cover;
font-family: georgia;
color: #FFFFFF;
font-size: 25px;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
text-align: center;
}
Oooh.
Now, for the text within the meme, I can't be arsed to create a new CSS class for this, so I'll just go with two paragraph tags, one of which is set in the middle of the box, and the other at the bottom. The first paragraph will display
line1 and
line2. The second paragraph will display the Nike swoosh and the string
slogan.
<div id="memeContainer">
<p style="margin-top:50%"><?php echo $line1;?><br /><?php echo $line2;?></p>
<p style="margin-top:30%"><img src="nikelogo.png"> <?php echo $slogan;?></p>
</div>
There's your meme! Well, the default anyway.
Let's try something here... well now we have a
Serena Williams meme! If you're wondering if I'm mocking her for
her recent display at the US Open... yes, I really fucking am.
One last thing...
Let's add a bit of CSS so we can print.
formContainer and
pnlMessage will be totally invisible, while
memeContainer will have the
float property set to
none, and then aligned center of the screen.
#memeContainer
{
width: 500px;
height: 500px;
padding: 5px;
margin: 5px;
float: left;
outline: 1px solid #DDDDDD;
background: url(<?php echo "uploads/" . $filecode . "." . $filetype; ?>) center center no-repeat;
background-size: cover;
font-family: georgia;
color: #FFFFFF;
font-size: 25px;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
text-align: center;
}
@media print
{
#formContainer, #pnlMessage
{
display: none;
}
#memeContainer
{
margin: 10% auto 0 auto;
float: none;
}
}
Do a Ctrl-P. Beautiful, isn't it.
Last words...
Well, I certainly enjoyed myself. Remember to sanitize your inputs (I didn't do it here because it's out of scope) to prevent a nasty XSS attack. And... have fun. Go crazy.
#justdoit
T___T