WPSFO: Nginx

Yesterday was my third time attending the SF WordPress Meetup. The main presenter was Floyd Smith, who co-authored the book WordPress in Depth with Michael McCallister. With him is pre-sales engineer Kunai Pariani, product marketer Faisal Memon, and digital marketing manager Patrick Nommensen.

There is a lot of Nginx people in the room that day.

Several terms were repeated several time during the talk, including how Nginx works with WordPress, microservice, performance, and redirection. Floyd mentioned that htaccess is the greatest and worst thing ever invented, which was hilariously true in so many ways. Nginx is suppose to help with that, plus ops, which all sounded pretty neat. Prior to the talk, the only thing I know about Nginx is that it is some sort of server, and that Docker supports its deployment (They use it as an example practice in its tutorial, if I recall it correctly).

Ok, let’s hear about Nginx.

There are apparently 2 level of Nginx – open source and Plus. Most of the services are in the open source, though. The original developer started it for his website. He set out to solve a specific problem, and he wanted others to use his solution, so he made it open source. That practice have remained consistent to this day. The solution did took a while for the community to catch on, since he was from Russia and everything was typed in Russian! It had since greatly expanded, and now part of their office is just 2 blocks away from us at the Automattic HQ!

So what’s Nginx about and what problem does it solved?

It was designed originally to solve the mathematical problem C10K – how to handle large amount of web traffic all at one time. It is a web server that also have various other uses, including serving as reverse proxy server that handle communication between clients and web servers. Architected for high demand, over 48% of the top 10,000 most visited websites uses it. Even WordPress itself is powered by Nginx.

So, umm, what does does it do other than being a web server?

Performance was mentioned several time throughout the talk. Nginx’s features often relates to that. Floyd talked quite a bit about load balancing and caching. One action that Nginx does, for load balancing, is that it performs health check and distribute traffic to the least busy server. There are two type of caching. The first is static file caching where static files is saved into a separate server and display when needed. The second type is dynamic caching, which create a cache after a user access the site, and that cache are what other users sees for a certain amount of time. With the later, though less loading are used, the method is not suitable for sites where each seconds matter. One of the example Floyd provided is stock market.

Another matter that he discussed is security and access control. Nginx can also act as reverse proxy server. The reverse proxy server can then become the main location for configuration changes and security implementation instead of the app server, adding an additional layer of security. In particular, Nginx also heavily encourages SSL, providing multiple SSL features, including implementation of SSL between microservices.

For a stack system that uses Nginx, Floyd calls it the LEMP Solution. (For eNginx, since LNMP is not pronounceable).

A system that uses Nginx has four benefits:

  1. Use of permalink instead of .htacess: easier to change path
  2. Ngnix can be configured for FastCGI: better caching.
  3. Security on Ngnix: allow the use of revise proxy server as a place for configuration changes.
  4. Nginx works great with WordPress Multisite in setting up proper file structure.

We talked about history, features, and stack system. But, how do Nginx fair in a multi-server environment?

Floyd asked the room if anyone have a Hardware ADC, the immediate response was “Heh?”.

One person did raised his hand, then promptly answered “Yea, as a paperweight!”

Predictably, the whole room laughs. Turns out ADC stands for App Delivery Controller. From the talk, it sounds like its some sort of device that allocates overflow of network traffic. A quick google reveals a wiki page that states ADC:

is a computer network device in a datacenter, often part of an application delivery network (ADN), that helps perform common tasks such as those done by web sites to remove load from the web servers themselves. Many also provide load balancing. ADCs are often placed in the DMZ, between the firewall or router and a web farm.

Tom’s IT Pro also have a detailed and more technical article on it: A Guide to Application Delivery Controller (ADC) Solutions.

Alas, the conclusion is that Hardware ADC is not exactly the most popular method. Most people prefer to use Software ADC so they can immediately get the service instead of waiting for a physical hardware to be mailed over.

This is where Nginx comes into play – it provides Software ADC services. For those who uses Microservices, that can be very useful.

I have been hearing a lot more about Microservices since I first learned about it during Devweek. It is definitely something that seems to be catching on, which makes sense. With the web expending, going microservices instead of monolith would give an large organization a much easier time of expending. According to Floyd, he believe that while WordPress and Automatic are not there yet, the two can make a blended approach of their existing monolith with microservice, especially since WordPress was designed to be opposite of a monolith approach to begin with. He then points to an Nginx article on microservices: Introduction to Microservices. He recommended WordPress users to read the last article there because we tend to be expert of modifying existing app, which is quite true in my case – my first job for WP is about working with existing site and plugins, after all. I’ve got Building Microservices by Sam Newman on Safari Online in my reading list (suppose to be pretty good), but for a quick read, this set of article seems good.


Things that caught my interest during Q&A:

  • For learning Nginx, in addition to Googling (the most useful skill for any self-learners!), Nginx’s mailing list are great. They also have official training for those whom prefer official things.
  • An attendee added that Apache and Ngnix are actually very similar, so learning it with an existing background in Apache would help.
  • WordPress approach tends to be more experimental, while Ngnix tends to be more strict. If there are users who wants to experiment it, containerized them may be a good idea.
  • Nginx does not intent to support htaccess – it is oriented to larger site.
  • Nginx is also not intended for real time, End-to-End Optimization. An attendee added – pretending to be whispering loudly – that if real time is needed, WordPress wouldn’t be used. Generally, people would use something like WebSocket.

Well, that concludes a quick basic info session on Nginx!


Reflection of DeveloperWeek Hackathon 2016

I haven’t took the Muni for a while. I totally underestimated the time, missed a bus, and ended up way too late.

Not a good start.

By the time I was there, there is only about 10 minute before the main stage kickoff starts – wait, I mean I was late for breakfast.

What? Breakfast is a very important part of hackathon. Especially if you are a coffeeholic. Oh, coffee, my precious coffee.


The point is that everyone is there, chatting among themselves or the booth host, and I am still didn’t had my morning joe… wait, the booth is already set up this year!?

Well, at least I didn’t missed the food.

The main stage kickoff was late this year, and there were some momentary confusion about when and where it was to happen. It didn’t help that the attendees are split into 3 stories, with the lower story being the actual place for the main stage. I stalked checked up frequently on DeveloperWeek’s Facebook and Twitter account. Finally, someone came in to inform us that the kickoff is about to start. It was pretty much just each company introducing themselves and their Challenges, which was posted at Accelerate.im, DeveloperWeek’s website for the hackathon event.

The companies involved this year that caught my attention because they were either on Opening stage or holds one of the booth includes Galvanize, Codeanywhere, Concierge, Flowroute, HP, CapitalOne, Cortical.io, IBM, Intuit, Magnet, NetApp, RedisLabs, SparkPost, CloudBees, Weebly, and Shippo.

It would be way too long to go over each company. I may go over them in a later post?

The decision to come to the Hackathon was last minute, so I didn’t really know what Challenges there were or had a team. I met up with a friend, but she was in a team that uses Ruby, which I know nothing about other than the fact my favorite and very awesome food subscription box uses it for their website (Yep, I checked their job page. What? An internship with a food company would be awesome! Except they use Ruby on Rails. And they don’t need interns. *Sighs* By the way, the company is Love With Food. Great snacks, fun preview video, and they donate a meal for each box purchased. Did I mentioned that they are awesome?).

So, first task. Read Challenges and existing Projects. The Challenge from Shippo caught my attention quickly. I thought of the multiple subscriptions of magazines and boxes I have, and how nice it would be to view them on one site. But then, no one seemed to have similar Challenge, so I decided to wonder around the booth, attend the workshops, and learned more about the available tools. After all, learning was my objective this time. While several were interesting, none of them materialized into a web app idea in my mind like Shippo did. In the end, I posted my own Project online onto Accelerate.im. However, I think I might had been too late, and no one is looking to team up anymore.

Lesson of the day, start and decide quick in a Hackathon.

One of the workshop, IBM’s Bluemix, did caught my interest. It seemed like I could use it to build web app, where I could input my code for Shippo. However, in the end, it was in vain. There were several errors that I came across, and it wasn’t friendly enough for me to create a login system in 24 hours. In the end, I became too obsessed with it and wasted time.

Another lesson learned. In hackathon, do not obsess over non-essential problem.

I did created a PHP class to extract the information given by Shippo’s API. I used WordPress and its numerous plugin for user registration. But by then, I realized I wouldn’t finish on time. I took too much time with IBM’s Bluemix, and there were also some issues with the WordPress plugins. I could do an all-nighter to make up for the time – except I had a volunteer project due and a dinner party for my dad the day when the Hackathon ends. I did not want to fall asleep for either of them for a project that I will either not finish or finished very roughly. Promised responsibilities comes first.

In the end, I turn of my laptop and went to bed. The idea is there now. Even if the hackathon had passed, I still got a project started that I plan to finished after my current EduGarden app, so not all is lost. Plus, this way, I get to make a much more complete project, which is much more satisfying for my perfectionist side. My current EduGarden app is being done with a focus on secure programming practices and an aim of learning PHP MVC. While EduGarden is made to work fine in both mobile screen and even without Javascript, my second app – now title SubscribeTrack – will probably focus completely on mobile usability with an aim to learn css3 media queries.

The current project of SubscribeTrack is now on Github without the WordPress codes, temporary placed on hiatus until EduGarden is done.

Winter Break Activities, 2015-16

So far, during this break I have:

  • Went to Japan with my family (Hooray!)
  • Started to volunteer for a non-profit that help local youth by teaching tech named Bayview Boom. Currently I am just discussing how to organize the page with the director, who is also a developer. Should be a good experience that we will let me both learn from a working developer and use my skills in front-end (the webpage is switching from Yola to WordPress.org) for a good, local cause.
  • Reading through the HTML & CSS3 For The Real World by Alexis Goldstein, Louis Lazaris, Estelle Weyl.
  • Reading through the C++ Primer by by Stanley B. Lippman, Josee Lajoie, Barbara E. Moo. I am taking CCSF’s C++ Fundamentals coming semester, even though I have never taken the C++  intro class! I had, however, taken the Java intro class, whose professor emphasized that if we took the Java intro, we should take the C++ intro. I hope he is right, but I am going to make sure that I am well-prepare.
  • Reading articles and books on mobile responsive design.
  • Random reading about random programming subject.
  • Tried Eclipse to do C++. Can’t do Ctrl C and Ctrl D, which is part of the book exercises. Prefers and went back to command line.
  • Added to my PHP class project from last semester. During last semester, I already finish the basic functions for the login, inventory, and cart page. I want to finish the shop and about page during break.

Coming semester:

  • I am taking 3 classes: Programming Fundamentals: C++, WordPress & Drupal CMS Development, Linux Administration Projects.
  • Be more active with Meetup.
  • Continue volunteering at Rebuilding Together in data entry, phone screening, Cantonese interpretation, and Traditional Chinese translation.
  • Start volunteering at Bayview Boom with their website. Seems like it will focus on WordPress plugin and related codes. My WordPress class in CCSF starts just at the right semester!
  • In progress of inquiring about a possible web/media internship with a non-profit. No email reply yet.
  • For the PHP class project, finished the home and product page. If possible, include an event page.
  • Add my current work to my portfolio page. Everything is just on Github now, which only have the code, not the images.
  • Really want to learn C so I can program my Pebble Watch, but that may be too heavy of a work load this semester with the C++ class.
  • I would complete all the Linux courses in CCSF. Should I take the Redhat exam even though my aim is front-end? I have enjoyed the classes very much. I should look more into that…
  • Speaking of which, I should work on changing my Nexus tablet’s OS to Linux. Totally forgot about that!
  • And last but not least, look for a job or internship.

Building my PHP Session Handler

My homework recently consisted of building my session handler, which confused me greatly – what on earth is session handler? At first glance, I wondered why would one use session handler? How is different from, say, calling the method by $session->getData()? Took me a while, but I finally got a working code that I have now recorded on Github, and I got some basic idea on What, How, and Why.

Note that this is really a blog where I store my notes for future references and to type out information so my mind can wrap around things. There is a lot of “typing whatever comes to mind” and cherry-picking only things that interest me. If you somehow wandered here looking for organized info on Session Handler, I suggest the tutorial on Sitepoint, which is way more organized and correct.

What is Session Handler: Like its name, it handles session. When a session starts, such as via session_start(), data are stored in $_SESSION with a configuration file php.ini, or at least that is my impression of how it works. Using those information and configuration settings, the handler manages database storage. Its basic, possible use includes opening database, reading the database and outputting the data, writing to the database with the values gain from $_SESSION, destroying selected data from database, performing garbage collect in the database, and closing the database.

How to do a Session Handler:

Class Session {   // Or whatever you name it as.

// I am using the constructor in PHP 5 style. Do not misspell it as constructor. Certain someone spent a whole night wonder what is wrong with her constrictor because of it…

function __construct() {

// The build-in function below “sets the user-level session storage functions” (via php.net), which pretty much means that it designates when the methods in this Class is invoked. Yes, the methods are invoked automatically basing on the condition! Most of the time anyway. Do not misplace the order of the arrays, or your function will be invoke in the wrong condition.

// Placing it inside the session class constructor is optional. However, placing it outside the class would mean you would type it out each time the class is invoked, plus “$this” will be change to the name of the object created by the Class, which is just annoyingly repetitive.


array($this, ‘open’),    // 2nd parameter’s name is personal preference, but pick something easy to understand. ‘Open’ is pretty standard.

array($this, ‘close’),

array($this, ‘read’),

array($this, ‘write’),

array($this, ‘destroy’),

array($this, ‘gc’)


session_start();   // though not required, it’s good idea to place session_start() her so you don’t to invoke every time you create an Object with this class.


function open() {

// Invoke condition: whenever session is starting, such as when session_start() is used.

// Typical content: call to database.


function close() {

// Invoke condition: after write() was called or when session_write_close() is called.

// Typical content: close database.


function read($sessionId) {   // all method’s parameter seems to be optional. Each method’s first parameter calls the value from $session_id(). You as the coder don’t have to do anything other than call the Class (or session_start() if it is not in the Class’s constructor. See, this is why its good to put session_start in the constructor) unless you want to change the default session id. You should not have to type read(1234) or something like that.

// Invoke condition: whenever session starts or when session_start is called() – but after open().

// Typical content: what you want to display from the database.


function write($sessionId, $data) {   // like read(), $sessionId will call the value from $session_start(), while $data will call the value from $_SESSION[‘data’]. Again, you don’t have to do anything other than calling the class unless you want to change the default value. I change the $data in my handler to take in the input value, but I did it by reassigning the value in $_SESSION[data] outside of the class ($_SESSION[‘data’] = $_POST[‘something’]) and not by $data = something.

// Invoke condition: whenever the PHP shuts down or when session_write_close() is called, but after the output stream is closed. close() is executed after this.

// Typical content: writing to database. Note that $_SESSION[‘data’] is automatically serialized. This means you have do some unserializing and serializing, plus you have to make sure to prevent SQL injection. In my own code, I:
(1) Copy the serialized session $_SESSION in a different variable, $original.
(2) Unserialized $_SESSION. Note that after PHP 5.3, using unserialize() on a SimpleXML_Load_String() will result in an error message, which is what will happen with $_SESSION. Use session_decode() instead.
(3) Store the unserialized content in a variable $output, then real_escape_string() it to prevent SQL injection.
(4) Restore $_SESSION with the variable containing the serialized session ($_SESSION = $original).
There are other methods, but this is the quickest one I can understand – I am working on a deadline after all.


function destroy($sessionId) {

// Invoke condition: whenever the session is destroy, either via session_destroy() or with session_regenerate_id() set to parameter TRUE.

// Typical content: what happens if a session is destroy. In my case, I set my codes to do a session_destroy if a submit button “Logout” is press (AKA, check if a $_POST[‘logout’] exist, if so, call session_destroy() ). When the destroy() is invoked as a result of that, it remove the entry in my database associated with the current session id.


function gc($lifetime) {   // $lifetime calls the value store in session.gc_maxlifetime.

// Invoke condition: called periodically by PHP, with the frequency based by session.gc_probability and session.gc_divisor.

// Typical content: what happens if a session is garbage collected. In my case, in my construct(), I set the session.gc_maxlifetime to 15 minutes. My database contains a column, ‘time’, that stores the time the entry was first written. When gc() is invoked, if any rows have a ‘time’ cell older than 15 minutes ago, the row is removed from the database. In another word, a user is automatically logged out after 15 minutes with its session id and data removed.


Why use Session Handler: It is probably because it (1) reduces the amount of coding when you store session repetitively and (2) sets a lot of automation.

When I first started building the code and my constructor wasn’t working, I placed session_start() outside of the class. I also attempted to invoke the methods manually:

$session = class Session();


$session ->open();

$session -> read();

$session -> close();

That is a lot of code to be typed each time you invoke a session class. With the session handler, all the methods are invoked automatically when conditions are met. Even the parameters, like $sessionId, $data, and $lifetime that I mentioned earlier, are automatically set. Coder can change them by change the values in $_SESSION[] or session.gc_maxlifetime, but it’s pretty automatic.

Summer 2015 So F ar

One of my goal this summer is work on my project, which ended up with me taking a long detour in both brushing up and learning new skills in JavaScript, JQuery, Ajax, PHP, MVC, and OOP. There was a lot of reading, online video/school, and coding. I have sadly ddiscovered that I have learned more about Ajax in a 2-days self-study using Treehouse video and books than I did a semester of class, but hey, some classes are better than other. It’s been good, although I ended up pushing back my C and Anduino learning.

IT network self-study has been going well. Since I am taking the same professor as I had in my Introduction to Networking for the next semester course in Network Security, I feel that I should brush up on my network knowledge. When I took my first network class over half year ago, I was new to CS and have no idea what is going on. I am half-way through re-reading my books and notes. Now that I have a lot more experience, it makes much more sense, and I feel more comfortable about jumping back to a networking class this Fall.

In term of Fedora, because of that fact that half of my self-study files are local, I lacked a reason to even turn on Virtualbox. But no more. Most of my learning files and even a good portion of my project files are now on Dropbox. I installed both Dropbox and Sublime Text on Fedora, so I can now do most of my coding and studies in Fedora!

Although, Fedora have problem waking up from its sleep in Virtualbox. It would either remain the black screen of death or refuse to let me type anything. In addition, I am consistently clicking on command-C instead of control-C. In Virtualbox, control-C actually exits the Virtualbox out of its full-screen mode instead of copying text. As someone who loves shortcut key and types pretty quick, it’s driving me a bit crazy. I pretty much do a command-key shortcut every 10 minutes when I started using Virtualbox, then when I do return to my Mac OS, I would do the opposite! (As in using control-key for shortcut every 10 minutes). For the first time in my life, I curse my ability to type so quickly…

jQuerySF 2015, Day One Reflection

A two day conference solely dedicated to a jQuery? I know jQuery is an extremely popular library, but I never expected a whole conference dedicated to it! I am still new to JS, especially since I have been taking more back-end language courses lately, but I really would like to brush up on my front-end skills.

Plus, there are lunch and coffee, those are always good incentive!

I had volunteer work that day, so I have to miss the morning. I don’t regret it though – turns out the Americorp people are leaving this week! I am so glad I didn’t missed my last chance to say goodbye. I really enjoyed working with the group this time! They are always so positive and cheerful!

At 12, I leave for the conference after a lot of hugs. I was just in time for the lunch time food truck. I grabbed a bite, settled down, and waited patiently for the next set of speakers.

In jQuerySF, the panels are divided by topics. First up at 2:30 is:

Why Empathize? The speakers are Amanda Glossom, John Resig, and Kelly King.

I like how Amanda began with an explanation of what empathy is: “Empathy is imagining what is like for them in their shoes”. It’s not imagining what is like for us be in their shoes, but what it is like for that individual to be in their shoes. Her ending of “End user isn’t the only one who deserve our empathy. We are people too. ” was also particularly memorable. Very often we get obsess with the end customer, we end up losing those people that are needed to make the whole thing work.

As a JS newbie, the name John Resig sounded familiar. Upon reading his bio, I realized why – he is the author of Secrets of the JavaScript Ninja, a book I have been eying at Barnes & Nobles. His panel did not disappoint. It drawn from his experience during the early days of jQuery. Having read various code language debates, I found it refreshing that John disagreed with the idea that certain code languages are better, and that things that aren’t code can be what differentiate between the different coding language. One of the things he pointed out is level of difficulty to get help from a language community, especially among people just starting to learn the language. His focus of how important community is in the development of a language made his panel particularly useful for those involved in building a language.

The last empathy panel is Kelly King, whom talked about A/B testing. One of the most memorable part for me was when she posted the top liked comment on Netflix, “The new Netflix interface is completely crap.” It sent the room into laughter. The irony though, Kelly revealed, was that A/B testing shows that the new interface actually created better result. As one of my science teacher once told me, science is not always common sense. With A/B testing, they can avoid situations where the decisions are determined based on HiPPO – High Paid Person (Nice name!).

The Importance of Accessibility: The next group of panel consisted of Karo Caran, Jon Kuperman, and Victor Tsaran.

In discussing about accessibility, Karo mentioned not only those who are born with low vision, but also elder and, most interestingly, the invisible audience who wouldn’t acknowledge that they have low vision. She presented 4 pictures of how a person with visual disability might view a laptop screen. The video about how she navigated a website was eye-opening. In the video, she mentioned that she can only see the colors of an app and must magnify for detail. She also mentioned several times how the stripes of color from the navigation bar makes it easier for her. Those seemed like such a small detail when designing a website, but for some people it really makes a difference in their experience of the site.

I like Jon Kuperman’s definition of what accessibility design is, especially the part about how it should create a way that everyone “can contribute to the Web”. His misunderstanding about text-reader was hilarious to read about but also kind of sad. It really does brought to the point of how little most people understand about accessibility. I was fortunate enough that one of my professor did taught us basic accessibility design. However, some of the tools and design considerations that Jon mentioned was never made aware to me before.

So far, all the panels has been inspiring and informational, but Victor Tsaran’s was most educational because I have never even heard of Aria. Turned out ARIA stands for Advanced Rich Internet Applications. It is created to deal with Ajax issues in term of accessibility. It was a short 20-minute, so Victor only got to brush the basic surface of what Aria do, but it is definitely something I hope to look up later.

The last is the keynote – and was it some keynote!

JavaScript State of the Union: The keynote was by Steve Newcomb.

There are times when video and reading can not make up for being in person. This is one of those moment. The combination of his charismatic speech and the presentation of the demo was just amazing. Steve Newcomb has sought to bring the JS language to the three-dimensional, to make browser language compatible with native. I never imagine that something like what the demo showed can be build by JS and jQuery. Listening to him made me wanted to code more projects right after the panel. He was a powerful speaker. His presentation is inspiring and made one look forward to the future of Javascript.

End of Day One

There was so much just on the first day, despite the fact that I have to miss the morning panel. I will try to post a second post later this week, but there are so many notes to process…

For those who missed, there is a video of the conferences at jquerysf.com!

Website planning 06/01/2015

Notes for website:

Need to create a portfolio image tile generator.

  1. Create a directory: largeTile
  2. Create a function that generate table with cell number based on number of image in largeTile.
  3. Generate the image with link. Variable $imgName.
  4. When hover in desktop/laptop, image becomes translucent with title stated.
  5. When tap in mobile, insert title above image within the table.

How to catalog?

  • Bookmarks image on top. Acts a navigator.
  • Clicked/Tap: Remove all cell holding images in according to bookmark selected.
    • Each cell has its own name.
    • Clicking the table means the whole page reloads.
  • Or, I can pre-catalog by directories beforehand. In normal view, the generator crawls through all sub-directories. In selected view, it crawls through only the sub-directories with name of bookmark.
  • Would need a flag. $bookmarked.

Final Fixes, or So I Hope. Feature Testing on Squarespace.

After a lot of Google and referring to my jQuery book (so glad that I got Beginning JavaScript and CSS Development with jQuery), I think the website I worked on is now successfully outputting error message for incompatible browser and lacking Javascript. To clarify issues involve, I would have to talk about the platform that my recent project website was built on: Squarespace.

Squarespace is fun for non-tech people to build their website on, especially since it boost its own CMS system with a drag-and-drop user experience. However, it also means customization via coding is limited, as documented by my previous post. In this post though, I am going to write about my experience with its browser compatibility, which is also extremely limited.

This poses a major problem: our client’s organization is a non-profit that target non-tech user. How many of them have an updated browser? More over, I found articles mentioning how Squarespace goes complete haywired in Android phones!

After an entire day (and night!) of research of which HTML/JS/DOM features are compatible with which browsers, my guess is that the issues lies in the platform’s drag-and-drop feature. Drag-and-drop, however common it seems nowadays, is a recent development even as a HTML5 features. At first, when I read Squarespace’s Supported Browser page, I am not sure how they came up with the version numbers:

Squarespace Supported BrowserAfter my research accompany by coffee and too many open browser, I realized that their version numbers matches drop-and-drop’s browser compatibility chart in w3schools. Ah, so that’s what that was about.

Talk about real-life demonstration of why feature testing is praised whenever I look up on browser testing, instead of the easier, no-research-needed User Agent testing. To summarized of the various article opened in my browsers, User Agent relied on information given by the client browser, which can be change by the client user. It is, therefore, susceptible to spoofing. In addition, Squarespace only shows 4 browsers in its chart. Opera, for example, is not listed. It’s why I took the time to look up on feature testing – totally worth it!

Currently, to solve the problem, I am using Modernizr. While Squarespace comes with its own Modernizr preloaded – no additional src code needed – after some tweaking, I realized its Modernizr has various problems. Most importantly, one of the testing, Modernizr.draganddrop, did not work! My guess is that Squarespace either used an outdated version or customized it and decided the dropanddrop testing was unnecessary. *Sigh*. In the end, I found a CDN that Modernizr recommended (CDNJS) and src link it instead. Now the code works.

Prior to that, I also used noscript and “if lte IE 8” tag to test for 1) if JS is enabled 2) if IE browser is 8 or higher. In all 3 testings, I made it so that a fixed, orange bar (website color theme is black and orange) would float on top, warning users that they will not get full viewing experience with disabled JS or outdated browser. That way, users can still access the website, but they would know what’s going on.

Finally Done!

The semester is finally over. I am quite satisfied with my web development class project this time. By the time final presentation is over, there are only few glitches – mostly personal pet-peeves – that needs to be fixed:

  • The floating social media bar uses margin top spacing in order to avoid overlapping itself on the header. With a static measurement like pixel, the spacing between floating bar (which stays fixed) and header (which changes) is not consistent when transferring to different screens. I cannot directly inject a code block below the header because only code block WITHIN the header and footer will appear on all pages with Squarespace. I would have to ask the client to manually inject a code block every time a new page is created. Um… not a good suggestion.
  • Social media bar sizes are not responsive.
  • Since Squarespace templates has multiple section blocks for users to insert text and personalized code blocks, the empty sections creates awkward spacing, particularly at footer where there is a large blank spacing below the contact info. It doesn’t help that I have to inject JS code block in the footer and hide it in the pages.
  • Squarespace is dependent on Javascript and upgraded browsers. It does not degrade gracefully or even throw up an error message.

So even though the class itself and project requirements are done, I instill want to work on it. Now that I am not taking 4 CS classes at the same time (never, never take both MySQL and Linux Administration at the same time while taking 4 classes at CCSF. You will die, painfully, several times during the course), I went on ahead and started fixing those little glitches:

I removed the margin top spacings. Instead, in the header code section, I linked the page to jQuery. Then I inspected the site’s source code for the header tag, which turned out to be an id instead of the <header> tag that I expected (no wonder my coding for the header didn’t work earlier!). I then appended div id for my social media bar to the header using insertAfter – all while the codes are all still within the header, The bar will now remain 0px below the header no matter what screen and what page!

For the footer issues, I started by making sure all the footer codes I want are within one single well-named id. I moved them to Squarespace’s Code Injection page (The path is: Setting => Advanced => Code Injection => Footer), so the code is not creating additional in-page code block. Then, once again, I started dissecting the template code. There appear to a div for the mobile ‘back to top’ – ok, I want my contact info beneath that.
By experimenting with inserting my footer div id in various Squarespace tag, it seems “.footer-inner” is the best one to insert my footer div id before. I decided to cluster the footer’s insertBefore codes with the social media bar’s insertAfter in one document.ready function in the header. Test. So far, so good.
The large spacing at the bottom is still here though, but the previous footer testing also gives me a sense of what tag is responsible for which section. “.footer-inner” seems to be the key here. In the Custom CSS page, I play with the padding and margin a bit a bit to make sure the spacing of the footer top and bottom looks proportionate… ok, spacing issue solved!

Now, while checking on the mobile, I realized another issue – the Mailchimp subscription box in the home page is not responsive! The code provided by the company sets a static width. In mobile, it does not shrink, and get cut off rather abruptly instead. Easy fix here. Max-width. Good to go! Next!

Next part is probably the hardest task. True, it was easy to throw up an error bar informing users that their Javascript is not enabled by using noscript – I even made the bar floating and orange by using fixed position and z-index (apparently, the template’s front image hides the background color. Here I was, struggling trying to find out why a simple background-color does not work. All I needed was z-index. *sighs*.). The problem is browser incompatibility. While I can use JS’s UserAgent to detect browser, it turns out that browser sniffing is a unreliable way to detect browser. There is always a way to detect via object capability by testing if a vide can be shown – but that’s for testing if the browser is HTML5 friendly. Thankfully, it is easy enough to test for IE, but Squarespace, annoyingly, is not compatible with various version of Safari, Chrome, and Firefox. So I will be going off to info research for that. Plus, I also want to the width of the social media bar responsive… but it be difficult to click on a mobile screen then, wouldn’t it? Damn, I can’t make the bar thinner then… There goes that idea.

Any how, I have now uploaded all my code on Github. My first repo there for an actual project, instead of book exercises or Project Euler. I feel strangely very satisfied!

Final Presentation

“Ah, I was wondering who changed the page at midnight!”

“Yea… That was me.”

Final Presentation day. Always leave such fond memories, like solving a code problem at 12th in midnight…

So, updates!

For final, I fixed the link for the mailbox subscription box that was originally linked to a testing account instead of client account.

Most importantly, per client’s requirement from our previous meeting, I added in a floating social media bar instead of having it located at the footer!
When I started on the site, I was surprised that my original social media footer was missing. Reading my inbox for any last minute email updates, it seemed that due to some miscommunication, one of my teammate that typically worked on another portion of the project tried to work with the social media section, though she was unsuccessful.
The main problem is probably because developers can’t place codes just anywhere they want in Squarespace, especially if they want their codes to persist throughout all the pages. There are typically 3 locations.

  1. In-page code block: You can place code in most location of a page that way. However, to persist through all pages instead of just one, the code block needs to be in the footer.
  2. Custom CSS page: Access by “Design”.
  3. Code Injection page: Access by “Settings” => “Advanced”. Useful for non-css coding such as html, script, etc. As indicated in the page, it holds jurisdiction over: Header, Footer, Lock Page, and Order Confirmation Page.

My codes previously had been placed mostly in the footer as in-page code blocks since I initially wanted to use the build-in social media features. The floating social media bar should be located at the top of the page, but the only place where in-page code block become persistent though all the pages instead of one is the footer at the bottom. Firstly, I need the bar outside of the footer div. Secondly, scattering invisible code blocks in the page is not exactly clean-code practice. It is even more confusing to place codes that are meant for the top of the page in the footer! I want the page to be maintainable by future developer, too.

In the end, I moved my codes over to Custom CSS and Code Injection – Header. The floating part was actually pretty easy. I just used position:fixed. I then used margin-top to place it below the header, since I didn’t want the bar to overlap the header. I turned on opacity, since I would have no idea what the floating objects would overlap as user scrolls through the page. I then upped its z-index so that even when it overlap, it still stays on top.

Most of the work was nudging the icons and background so it wouldn’t do anything funky like a really wide padding on one side or icons overlapping each other.

Thanks to our Visual Media team recommendation, I replaced my pixelated icons with Font Awesome‘s icon (which was truly awesome, pun intended). Font Awesome have its own code to make their icon stacked vertically. I played around with the placement of their tags for a while to make the best stacking, then I adjusted the margin and padding for the icons and bar. Success!

Digital Action Hub: Social Media Floating Bar