├── README.md ├── content.php ├── index.php ├── mobile-mustard.js ├── screen-large.php ├── screen-small.php ├── style-large.css ├── style-small.css └── style.css /README.md: -------------------------------------------------------------------------------- 1 | # server-side-mustard-cut 2 | 3 | JavaScript, cookies, and a possible reload to get a server-side choice of documents. 4 | 5 | This is what we're currently doing for the [CodePen Editor](http://codepen.io/pen/) so I wanted to document it, since it seems to be working pretty well. 6 | 7 | Here's a demo. -------------------------------------------------------------------------------- /content.php: -------------------------------------------------------------------------------- 1 |
2 |

Server Side Mustard Cutting

3 |

For simplicities sake, our mustard-cut here will be a measuring of the screen width. But it could test for anything client-side. We're also using PHP here because easy, but it could be any server side language.

4 |

GitHub Repo

5 |
6 | 7 |

The Problem

8 | 9 | 17 | 18 |

Caveat

19 | 20 |

I'm not saying this is the best possible solution. I am saying this seems reasonable to me and I'm using it in production.

21 | 22 |

This kind of thing has been approached before. These things aren't necessarily mutually exclusive.

23 | 24 |

The Plan

25 | 26 | 41 | 42 |

Possible Scenarios

43 | 44 | 51 | 52 |

The Code

53 | 54 |

Server side:

55 | 56 |
<?php
 57 | 
 58 |   // This is just a FAKE ROUTER
 59 |   // Do this however your site does routing
 60 | 
 61 |   if (isset($_COOKIE["screen-width"])) {
 62 | 
 63 |     // Large screen
 64 |     if ($_COOKIE["screen-width"] > 700) {
 65 | 
 66 |       include_once("screen-large.php");
 67 | 
 68 |     // Small screen
 69 |     } else {
 70 | 
 71 |       include_once("screen-small.php");
 72 | 
 73 |     }
 74 | 
 75 |   // Choose a default
 76 |   } else {
 77 | 
 78 |     include_once("screen-small.php");
 79 | 
 80 |   }
 81 | 
 82 | ?>
83 | 84 |

In the document that gets served, if the cookie isn't already present, run the mustard cutting script:

85 | 86 |
<?php
 87 |   // Run this script as high up the page as you can,
 88 |   // but only if the cookie isn't already present.
 89 |   if (!isset($_COOKIE["screen-width"])) { ?>
 90 |     <script src="mobile-mustard.js"></script>
 91 | <?php } ?>
92 | 93 |

The script is:

94 | 95 |
(function() {
 96 | 
 97 |   // If the browser supports cookies and they are enabled
 98 |   if (navigator.cookieEnabled) {
 99 | 
100 |     // Set the cookie for 3 days
101 |     var date = new Date();
102 |     date.setTime(date.getTime() + (3 * 24 * 60 * 60 * 1000));
103 |     var expires = "; expires=" + date.toGMTString();
104 | 
105 |     // This is where we're setting the mustard cutting information.
106 |     // In this case we're just setting screen width, but it could
107 |     // be anything. Think http://modernizr.com/
108 |     document.cookie = "screen-width=" + screen.width + expires + "; path=/";
109 | 
110 |     /*
111 |       Only refresh if the WRONG template loads.
112 | 
113 |       Since we're defaulting to a small screen,
114 |       and we know if this script is running the
115 |       cookie wasn't present on this page load,
116 |       we should refresh if the screen is wider
117 |       than 700.
118 | 
119 |       This needs to be kept in sync with the server
120 |       side distinction
121 |     */
122 |     if (screen.width > 700) {
123 | 
124 |       // Halt the browser from loading/doing anything else.
125 |       window.stop();
126 | 
127 |       // Reload the page, because the cookie will now be
128 |       // set and the server can use it.
129 |       location.reload(true);
130 | 
131 |     }
132 | 
133 |   }
134 | 
135 | }());
136 | 137 |

୧༼ʘ̆ںʘ̆༽୨

138 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 700) { 9 | 10 | include_once("screen-large.php"); 11 | 12 | // Small screen 13 | } else { 14 | 15 | include_once("screen-small.php"); 16 | 17 | } 18 | 19 | // Choose a default 20 | } else { 21 | 22 | include_once("screen-small.php"); 23 | 24 | } 25 | 26 | ?> -------------------------------------------------------------------------------- /mobile-mustard.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | (function() { 4 | 5 | // If the browser supports cookies and they are enabled 6 | if (navigator.cookieEnabled) { 7 | 8 | // Set the cookie for 3 days 9 | var date = new Date(); 10 | date.setTime(date.getTime() + (3 * 24 * 60 * 60 * 1000)); 11 | var expires = "; expires=" + date.toGMTString(); 12 | 13 | // This is where we're setting the mustard cutting information. 14 | // In this case we're just setting screen width, but it could 15 | // be anything. Think http://modernizr.com/ 16 | document.cookie = "screen-width=" + window.outerWidth + expires + "; path=/"; 17 | 18 | /* 19 | Only refresh if the WRONG template loads. 20 | 21 | Since we're defaulting to a small screen, 22 | and we know if this script is running the 23 | cookie wasn't present on this page load, 24 | we should refresh if the screen is wider 25 | than 700. 26 | 27 | This needs to be kept in sync with the server 28 | side distinction 29 | */ 30 | if (window.outerWidth > 700) { 31 | 32 | // Halt the browser from loading/doing anything else. 33 | window.stop(); 34 | 35 | // Reload the page, because the cookie will now be 36 | // set and the server can use it. 37 | location.reload(true); 38 | 39 | } 40 | 41 | } 42 | 43 | }()); 44 | -------------------------------------------------------------------------------- /screen-large.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | Server Side Mustard Cutting 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | You got the large screen document. 27 | 28 |
29 | Your screen looks smaller though... 30 | clear cookies and refresh? 31 |
32 |
33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /screen-small.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | Server Side Mustard Cutting 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | You got the small screen document. 29 | 30 | 31 |
32 | Your screen looks bigger though... 33 | clear cookies and refresh? 34 |
35 |
36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /style-large.css: -------------------------------------------------------------------------------- 1 | .which { 2 | background: #cd5607; 3 | } 4 | 5 | @media (max-width: 700px) { 6 | .which-warning { 7 | display: block; 8 | } 9 | } -------------------------------------------------------------------------------- /style-small.css: -------------------------------------------------------------------------------- 1 | .which { 2 | background: #04acca; 3 | } 4 | 5 | @media (min-width: 701px) { 6 | .which-warning { 7 | display: block; 8 | } 9 | } -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @import url(//fonts.googleapis.com/css?family=Lato:400,700,900); 2 | 3 | html { 4 | background: #FCD53A; 5 | } 6 | 7 | body { 8 | font-family: 'Lato', sans-serif; 9 | line-height: 1.4; 10 | font-size: 18px; 11 | max-width: 600px; 12 | margin: 0 auto; 13 | padding: 0.5rem; 14 | } 15 | 16 | h1, h2 { 17 | font-weight: 900; 18 | color: #414066; 19 | margin: 2rem 0 0 0; 20 | line-height: 1.1; 21 | } 22 | li { 23 | margin: 0 0 0.5rem 0; 24 | } 25 | ul ul, ol ol, ul ol, ol ul { 26 | margin-top: 0.5rem; 27 | } 28 | pre code { 29 | display: block; 30 | background: #222; 31 | font: 12px Monaco; 32 | color: white; 33 | padding: 1rem; 34 | overflow: auto; 35 | } 36 | pre code span { 37 | color: #888; 38 | } 39 | 40 | header { 41 | background: rgba(255, 255, 255, 0.25); 42 | padding: 2rem; 43 | margin: 0 0 1rem 0; 44 | } 45 | header p { 46 | font-size: 0.9rem; 47 | } 48 | header :last-child { 49 | margin-bottom: 0; 50 | } 51 | header h1 { 52 | margin: 0 0 0.5rem 0; 53 | } 54 | 55 | .final { 56 | text-align: center; 57 | padding: 5rem 0; 58 | } 59 | 60 | .which { 61 | text-align: center; 62 | background: #222; 63 | padding: 0.5rem 1rem; 64 | color: white; 65 | margin: 0 0 1rem 0; 66 | } 67 | .which-warning { 68 | display: none; 69 | } --------------------------------------------------------------------------------