Powered by Blogger.

Contact

Popular Posts

Saturday 31 August 2013

PHP Tip: Encode & Decode Data URLs

Converting small images to data-URLs is a great way to eliminate HTTP requests and decrease loading time for your pages. Using PHP‘s base64_encode() and base64_decode() functions, we have the power to convert images to data-URLs and vice-versa.

Decoding Data URL Images

So we start with a small image named, say, “feed-icon.gif”:

[ RSS Feed Icon ]

We then convert to data-URL format by encoding with base64_encode()1:
<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>
This will output the image as a string of base64-encoded gibberish, which I will not utter here. It begins and ends with these characters:
R0lGODlhEAAQAPcAAP+JAP+LAP+vWf ... ceZECFAtPbhAkijCBVUAAOw==
And just keeps going for about 4KB-worth of code, which is actually larger than the original image. But that’s okay because saving an extra HTTP request is better for performance than a few extra kilobytes of code. Now that we’ve encoded the image, we can display it in our web pages like so:
<img src="data:image/gif;base64,<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>">
Or display in our dynamic CSS.php file:
background: url("data:image/gif;base64,<?php echo base64_encode(file_get_contents("feed-icon.gif")); ?>");
1 That’s sort of a “quick-n-dirty” technique but it works. Here is another encoding method usingfopen() instead of file_get_contents():
<?php // convert image to dataURL
$img_source = "feed-icon.gif"; // image path/name
$img_binary = fread(fopen($img_source, "r"), filesize($img_source));
$img_string = base64_encode($img_binary);
?>
Then to display in your web page, use something like this:
<img src="data:image/gif;base64,<?php echo $img_string; ?>">

Decoding Data URL Images

The easiest way to decode a base64-encoded image is to just do a “Save as…” somewhere on your machine. Of course, you can also use PHP’s base64_decode function to convert encoded gibberish back into original shape. This works great for text content, but for images we need to include the proper header when displaying as web content:
<?php header("Content-type: image/gif");
echo base64_decode($img_string); ?>

From : http://perishablepress.com

Display Latest Tweet with Show/Hide Cookies


[ Twitter Bird ]
Update (2013/08/03): This simple technique no longer works thanks to the 2013 Twitter API, which makes it much more complicated to grab your latest tweet. For WordPress, check out the Latest Tweets Widget.</update>
My previous theme displays my latest tweet at the top of every page. It turned out to be an excellent technique for getting more followers – visitors see the tweet, click the link, and possibly follow me on Twitter. There is even a cookie-powered “Hide” link for uninterested visitors to hide the tweet for awhile. I received quite a few requests for a tutorial on the technique, so here is how to display your latest tweet with show/hide cookies. For this tutorial, we’ll be using HTMLCSS, jQuery and WordPress. Here is a Demo of the finished product.

Overview

Once implemented, this technique will display your latest tweet as a link on your web page(s). Visitors may click on the tweet to arrive at your Twitter page, and/or click on the “Hide” link to hide latest tweets for some period of time. By default, the tweet will remain hidden for one day, or until the cookie is removed from the browser cache. We’ll see how to specify a different “hide duration” in the jQuery part of the tutorial.
Where is the latest tweet displayed on the page? That depends on the CSS. By default, the tweet will appear exactly where you put the HTML/PHP code in your WordPress theme template. Then with a few additional CSS styles, we’ll see how to position the tweet in a fixed position at the top of your pages.

Step 1: WordPress

To begin, you need WordPress and the SimpleTwitter plugin, or some other way of caching and displaying your latest tweet. The SimpleTwitter plugin is lightweight and simple to use:
  1. Go to the SimpleTwitter Settings Page
  2. Enter your Twitter name and cache time
  3. Save Settings
You can use whatever cache time you like, but don’t go crazy in either direction. Base your decision on your tweet frequency. For heavy tweeters, something like 10 minutes, and for lighter tweeters maybe 120 minutes (2 hours). Once you save your settings, it’s time to add the HTML/PHP code to display the tweet on your pages.

Step 2: HTML/PHP

With the SimpleTwitter plugin configured, we now want to add the HTML and PHP code required to display your latest tweet. This code may be placed anywhere in your theme template, but is designed to be placed in the footer.php file, and then absolutely positioned with CSS to display at the top of your pages.
<div id="tweet-link">
<div>
<a id="tweet-latest" rel="nofollow" href="http://twitter.com/perishable">
<?php if (function_exists('get_twitter_msg')) { get_twitter_msg(); } ?>
</a>
<span><a id="tweet-hide" href="#">hide</a></span>
</div>
</div>
The only edit to make here is changing my Twitter name, “perishable”, with that of your own. This is basically just a little HTML markup with the requisite SimpleTwitter template tag. Nothing fancy. Once this code is in place, it’s time to style it up with a little CSS.

Step 3: CSS

In your stylesheet, include the following CSS:
div#tweet-link {
background: url(http://example.com/images/twitter-bird.png) no-repeat 0 8px;
display: none; overflow: hidden; line-height: 1.6;
}
div#tweet-link div {
padding: 5px 5px 5px 45px;
}
a#tweet-hide {
background-color: #ebebe3;
text-transform: uppercase;
border: 1px solid #827960;
-webkit-border-radius: 5px;
-khtml-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
padding: 2px 3px;
}
For the twitter-bird background, just grab a copy of the image appearing at the beginning of this tutorial and place it into your theme’s /images/ directory. If you’re using the default WordPress stylesheet, style.css, the background image should display just fine. If it doesn’t, make sure the image at the specified location.
Update: I changed the image path to include “http://example.com/”, so remove that bit to get just “images/twitter-bird.png” for the background url() value.</update>
Notice also that with div#tweet-link{display:none;}, we’re hiding the latest tweet by default. Once the jQuery kicks in, the tweet will be displayed, so if you don’t see it, don’t panic – we’ll get there in just a minute. The last thing to note about this CSS code is the use of proprietary browser-specific prefixes for the rounded corners on the button. Feel free to remove this fluff and restyle the “Hide” button however you wish.
Positioning the tweet: To fix the position of your tweet at the top of your web pages, two additional lines of CSS are required. First, add the following to the div#tweet-link selector:
position: fixed; width: 100%; right: 0; top: 0;
And then add this line to the div#tweet-link div selector:
text-align: right; float: right; clear: none;
Refresh your page and you should see the tweet displayed in the upper-right corner. You may need to tweak the CSS a little to get everything so arranged with your design, but the real trick here is keeping that Latest Tweet displayed at the top of the window regardless of where the user is scrolling on the page. Again, check out my previous theme to see an example of the tweet displayed with fixed positioning. I have found that displaying a persistent tweet at the top of my pages is an excellent way to attract new followers. And with the handy Hide button, everyone’s a winner.

Step 4: jQuery

Last step involves two jQuery scripts. The first part of the following code is the excellent Cookie plugin, which enables the “show/hide-cookie” part of the technique. No changes should be made to the Cookie plugin. It is included here without comments for convenience, but you can learn more here.
The second jQuery snippet displays the tweet, and then sets a “perishableLatestTweet” cookie with a “hide” value of one day. To change this to a different hide duration, edit the “1” in the line commented with “// 1 day”. Other than possibly that, nothing needs changed/edited – this code is good to go.
// Cookie plugin - Copyright (c) 2006 Klaus Hartl (stilbuero.de)
jQuery.cookie = function(name, value, options) {
if (typeof value != 'undefined') {
options = options || {};
if (value === null) { value = ''; options.expires = -1; }
var expires = '';
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
var date;
if (typeof options.expires == 'number') {
date = new Date();
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
} else {
date = options.expires;
}
expires = '; expires=' + date.toUTCString();
}
var path = options.path ? '; path=' + (options.path) : '';
var domain = options.domain ? '; domain=' + (options.domain) : '';
var secure = options.secure ? '; secure' : '';
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
} else {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
};
// Hide Latest Tweet with Cookies
$(document).ready(function(){
$('#tweet-link').attr('style','display:block;');
var remember = $.cookie('perishableLatestTweet');
if (remember == 'hide'){
$('#tweet-link').attr('style','display:none;');
}
$('a#tweet-hide').click(function(){
$('#tweet-link').slideToggle('normal');
return false;
})
$('a#tweet-hide').click(function(){
$.cookie('perishableLatestTweet','hide',{expires:1}); // 1 day
return false;
})
});
Include this jQuery at some point after including the jQuery library. Everything should be working at this point. If not, see the next section.

Troubleshooting Tips

If everything went well, your latest tweet should be displayed in the specified location on your web page(s). If you don’t see it, check the following:
  • WordPress/plugin – is the SimpleTwitter plugin active and properly configured?
  • HTML/PHP – is the required code somewhere in your active theme template?
  • CSS – is the CSS included somewhere in your theme (e.g., the style.css file)?
  • jQuery – is the jQuery script included after jQuery?
Everything should work great, but if not check these things first. The only thing that may require some thought is fine-tuning the CSS positioning and general styling to match your design. Depending on existing styles, the CSS may require some tweaking.

Demo

For convenience, here again are two places to demo the technique:
Comments, questions, and suggestions always welcome! :)

From : http://perishablepress.com

HTTP Headers for ZIP File Downloads

You know when you you’re working on a project and get stuck on something, so you scour the Web for solutions only to find that everyone else seems to be experiencing the exact same thing. Then, after many hours trying everything possible, you finally stumble onto something that seems to work. This time, the project was setting up a secure downloads area for Digging into WordPress. And when I finally discovered a solution, I told myself that it was definitely something I had to share here at Perishable Press.
Apparently, there is much to be desired when it comes to sending proper HTTP headers for file downloads. Different browsers (and not just IE) require different headers, and will error if not present exactly the way they expected. Confounding that equation is the fact that different file types also require specific headers. Then there are issues with sending an accurate (or should I say “acceptable”?) Content-Length headers when file compression is involved. Needless to say, finding a set of headers that works for all file types in all browsers is next to impossible. And I won’t even get into the issues involved with readfile() and large-download file-sizes.

Download Headers that actually work

After trying hundreds of different headers and combinations, I hit upon a set that works great forZIP downloads (and other file types as well) in all tested browsers. Here’s what they look like using PHP:
<?php // HTTP Headers for ZIP File Downloads
// http://perishablepress.com/press/2010/11/17/http-headers-file-downloads/

// set example variables
$filename = "Inferno.zip";
$filepath = "/var/www/domain/httpdocs/download/path/";

// http headers for zip downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath.$filename));
ob_end_flush();
@readfile($filepath.$filename);
?>
This PHP script is known to work under the following conditions:
  • Operating System: Linux
  • Server: Apache/2.2.3 (CentOS)
  • MYSQL Version: 5.0.77-log
  • PHP Version: 5.2.6
  • PHP Safe Mode: Off
  • PHP Allow URL fopen: On
  • PHP Memory Limit: 256M
  • PHP Max Upload Size: 2M
  • PHP Max Post Size: 8M
  • PHP Max Script Execute Time: 30s
With this code, the downloads work in the following tested browsers:
  • Firefox 3.0, 3.5 (Mac & PC)
  • Opera 8, 9, 10 (Mac & PC)
  • Internet Explorer 7, 8
  • Chrome 7.0.517
  • Camino 2
  • Safari 5 (PC)
  • Safari 3 (Mac)
The downloads work for the following types of files (including small and large file types):
  • .zip
  • .txt
  • .pdf
  • .jpg
Obviously, I didn’t test every file type in every browser, but the positive results from those listed here suggest a much wider range of files and browsers that will work. For the file sizes, I tested small files only a few bytes in length, and also large files up to around 20MB or so. Also would like to give a shout to the Live HTTP Headers extension for Firefox. It proved indispensable throughout the troubleshooting/testing/pulling-my-hair-out process.
As always, if you can contribute to the content of this post with further information about sending proper HTTP Headers for file downloads, you may just save a life ;)

From : http://perishablepress.com

Friday 30 August 2013


PUBLISHED BY CHRIS COYIER
Here is the basic markup for the progress element:
<progress></progress>
As per the standard defined by W3C, the progress element represents the completion progress of a task. A progress element must have both a start tag (i.e. <progress>) and an end tag (i.e. </progress>), even though it looks like a replaced element (like an input). This is good though, as it helps with fallback content as we'll cover later.
Apart from the global attributes, it can have two more attributes:
  • max - Indicates how much task needs to be done before it can be considered as complete. If not specified the default value is 1.0.
  • value - Indicates the current status of the progress bar. It must be greater than or equal to 0.0 and less than or equal to 1.0 or the value of the max attribute (if present).

States of progress bar

A progress bar can be in two states - indeterminate and determinate.

1. Indeterminate

Indeterminate state of the progress bar in Chrome 29 on Mac OS 10.8
Based on your combination of browser and operating system, the progress bar can look different. Zoltan "Du Lac" Hawryluk covers the cross browser behavior of progress element in great depth in his article on HTML5 progress bars (which is definitely worth reading). Wufoo has some screenshots of how it looks on other operating systems on their support page for progress.
It's pretty easy to target and style an indeterminate progress bar because we know that it doesn't contain the value attribute. We can make use of CSS negation clause :not() to style it:
progress:not([value]) {
/* Styling here */
}

2. Determinate

Throughout this article, we'll only focus on styling the determinate state of the progress bar. So let's change the state by adding the max and value attribute.
<progress max="100" value="80"></progress>
Without applying any CSS, the progress bar looks like this in Chrome 29 on Mac OS 10.8.
Determinate state of the progress bar in Chrome 29 on Mac OS 10.8
Note that only adding the max attribute doesn't change the state of the progress bar because the browser still doesn't know what value to represent.
This is pretty much all that we can do in HTML as rest of the work is done by CSS. At this stage let's not worry about the fallback techniques for supporting older browsers that don't understand the progress element.

Styling progress bars

We can target determinate progress bars using the progress[value] selector. Usingprogress only is fine as long as you know that you do not have any indeterminate progress bars in your markup. I tend to use the former because it provides clear distinction between the two states. Just like any other element we can add dimensions to our progress bar using width and height:
progress[value] {
width: 250px;
height: 20px;
}
This is where the fun part ends and things get complicated because each category of browsers provide separate pseudo classes to style the progress bar. To simplify things, we don't really care about which versions of each browser support the progress element, because our fallback technique will take care of the rest. We classify them as follows:
  • WebKit/Blink Browsers
  • Firefox
  • Internet Explorer

WebKit/Blink (Chrome/Safari/Opera)

Google Chrome, Apple Safari and the latest version of Opera (16+) falls into this category. It is evident from the user agent stylesheet of webkit browsers, that they rely on -webkit-appearence: progress-bar to style the appearance of progress element.
User-agent stylesheet of webkit browsers
To reset the default styles, we simply set -webkit-appearence to none.
progress[value] {
/* Reset the default appearence */
-webkit-appearance: none;
appearance: none;

width: 250px;
height: 20px;
}
Progress bar appearance after reset
On further inspecting the progress element in Chrome Developer Tools, we can see how the spec is implemented.
Chrome Developer Tools Snapshot
WebKit/Blink provides two pseudo classes to style the progress element:
  • -webkit-progress-bar is the pseudo class that can be used to style the progress element container. In this demo we'll change the background color, border-radius and then apply inset box shadow to the progress element container.
  • -webkit-progress-value is the pseudo class to style the value inside the progress bar. The background-color of this element by default is green which can be verified by inspecting the user-agent stylesheet. For this demo we will create a candystrip effect using linear-gradient on background-image property.
First we'll style the -webkit-progress-bar (the container):
progress[value]::-webkit-progress-bar {
background-color: #eee;
border-radius: 2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
}
Styling progress bar container
Next we'll style the -webkit-progress-value (the bar) with multiple gradient backgrounds. One for striping, one for top to bottom shadowing, and one for left to right color variation. We'll use the -webkit- prefix for the gradients since we're using it for the progress bar itself anyway.
progress[value]::-webkit-progress-value {
background-image:
-webkit-linear-gradient(-45deg,
transparent 33%, rgba(0, 0, 0, .1) 33%,
rgba(0,0, 0, .1) 66%, transparent 66%),
-webkit-linear-gradient(top,
rgba(255, 255, 255, .25),
rgba(0, 0, 0, .25)),
-webkit-linear-gradient(left, #09c, #f44);

border-radius: 2px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}
Styling progress bar value

Adding Animation

At the time of writing only WebKit/Blink browsers support animations on progress element. We'll animate the stripes on -webkit-progress-value by changing the background position.
@-webkit-keyframes animate-stripes {
100% { background-position: -100px 0px; }
}

@keyframes animate-stripes {
100% { background-position: -100px 0px; }
}
And use this animation on the -webkit-progress-value selector itself.
-webkit-animation: animate-stripes 5s linear infinite;
animation: animate-stripes 5s linear infinite;

Pseudo Elements

At the time of writing only WebKit/Blink browsers support pseudo elements ::beforeand ::after on progress bar. By simply looking at the progress bar, it is not possible to tell the actual value. We can solve this problem by displaying the actual value right at the tail-end of the progress bar using either ::before or ::after.
progress[value]::-webkit-progress-value::before {
content: '80%';
position: absolute;
right: 0;
top: -125%;
}
Pseudo elements in action
Interestingly, content: attr(value) doesn't work on progress bars. However, if you explicitly specify the text inside the content attribute, it works! I haven't been able to find out the reason behind this behavior. Since this works only on WebKit/Blink browsers, there is no good reason to embed content inside pseudo elements, at least for now.
Similarly, ::after is used to create nice little hinge effect at the end of the progress bar. These techniques are experimental and not really recommended to be used if you are aiming for cross-browser consistency.
progress[value]::-webkit-progress-value::after {
content: '';
width: 6px;
height: 6px;
position: absolute;
border-radius: 100%;
right: 7px;
top: 7px;
background-color: white;
}

2. Firefox

Similar to WebKit/Blink, Firefox also uses -moz-appearence: progressbar to paint the progress element.
Firebug screenshot
By using appearence: none we can get rid of the default bevel and emboss. This unfortunately leaves behind a faint border in Firefox which can be removed by usingborder: none. This also solves the border issue with Opera 12.
progress[value] {
/* Reset the default appearence */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;

/* Get rid of default border in Firefox. */
border: none;

/* Dimensions */
width: 250px;
height: 20px;
}
Faint border in Firefox and Opera
Firefox provides a single pseudo class (-moz-progress-bar) we can use to target the progress bar value. This means that we cannot style the background of the container in Firefox.
progress[value]::-moz-progress-bar { 
background-image:
-moz-linear-gradient(
135deg,
transparent 33%,
rgba(0, 0, 0, 0.1) 33%,
rgba(0, 0, 0, 0.1) 66%,
transparent 66%
),
-moz-linear-gradient(
top,
rgba(255, 255, 255, 0.25),
rgba(0, 0, 0, 0.25)
),
-moz-linear-gradient(
left,
#09c,
#f44
);

border-radius: 2px;
background-size: 35px 20px, 100% 100%, 100% 100%;
}
Firefox doesn't support ::before or ::after pseudo classes on progress bar, nor does it allow CSS3 keyframe animation on progress bar, which gives us a slightly reduced experience.

3. Internet Explorer

Only IE 10+ natively supports progress bar, and only partially. It only allows changing the color of the progress bar value. IE implements value of the progress bar as the colorattribute rather than the background-color.
progress[value]  {
/* Reset the default appearence */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;

/* Get rid of default border in Firefox. */
border: none;

/* Dimensions */
width: 250px;
height: 20px;

/* For IE10 */
color: blue;
}

What about browsers that don't support them?

The progress element is natively supported in: Firefox 16+, Opera 11+, Chrome, Safari 6+IE10+ is partially supports them. If you want to support older browsers, you've got two options.

1. Lea Verou's HTML5 progress polyfill

Lea Verou's excellent polyfill adds almost full support for Firefox 3.5-5, Opera 10.5-10.63, IE9-10. This also adds partial support in IE8. It involves including progress-polyfill.js file in your HTML and adding CSS selectors that the script file uses. To know more about its usage, check out the CSS source code of the project page.

2. HTML fallback

This is my preferred (no-js) approach. It makes use of a common technique that is also used by audio and video elements.
<progress max="100" value="80">
<div class="progress-bar">
<span style="width: 80%;">Progress: 80%</span>
</div>
</progress>
Simulate the look and feel of progress bar using div and span inside the progress tag. Modern browsers will ignore the content inside the progress tag. Older browsers that cannot identify progress element will ignore the tag and render the markup inside it.
.progress-bar {
background-color: whiteSmoke;
border-radius: 2px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.25) inset;

width: 250px;
height: 20px;

position: relative;
display: block;
}

.progress-bar > span {
background-color: blue;
border-radius: 2px;

display: block;
text-indent: -9999px;
}
It is fairly common to use both the techniques in conjunction and it is perfectly safe for production sites. Once you get hold of styling a single progress bar, then adding styles for multiple progress bars is merely an exercise which can be accomplished using classes.
The demo should run fine for all the browsers including Internet Explorer (up to IE 8). The progress bar color is blue in all the versions of Internet Explorer. Opera 11 and 12 doesn't permit changing the progress bar color. Hence, it shows the default green color. The demo uses additional markup to display some meta information about the progress bar and the percentage value.
For additional reading, check out the HTML5 Doctor article. It covers some similar ground but has some bits about a few additional attributes as well as how to update the bar with JavaScript if you need that.