Accelerated Mobile Pages

March 4, 2017, 1:03 p.m.

Over the last week I have been messing around with adding Structured Data to my pages so that Google can display Rich Cards. Google hasn't yet indexed my pages with structured data so there's not much I can say about that so far. I have also been playing with Accelerated Mobile Pages (AMP), which are lightweight pages designed specifically for mobile devices.

The two resources for AMP which I've found to be useful are AMP Project and AMP By Example. Unfortunately neither of them goes into a whole lot of detail about how to implement this stuff and I haven't been able to find very good explanations online. However I've been able to solve most of the issues I've encountered by trial and error.

The biggest difference between AMP and normal HTML is that AMP does not allow Javascript, nor does it allow linked CSS. All CSS must be inline, must total less than 50kB, and the only Javascript you can use is special Javascript from AMP Project. All images must have sizes defined and forms work a bit differently. The reason for this is to avoid any blocking resources that could slow the load of the page. I have been using Bootstrap CSS which I thought would be compatible as it is responsive and displays great on mobile devices, but it's too big and uses Javascript. I ended up using Bootstrap's Customizer to only output the elements I needed and then minified that and included it into my page. At some point I will clean out unused styles from the CSS to trim it down even more, but I was able to get my CSS to just barely fit the maximum size requirements by only using the bare minimum.

AMP isn't really all that complicated - it really just restricts what you can use in the page, but there were a couple things that I really struggled with. Those were, in order of difficulty:

  1. Creating a menu bar - my Bootstrap nav uses drop-downs which use Javascript so would not work. I had to create a simplified menu bar, but luckily amp has specific tags for this which were pretty easy to figure out.
  2. Creating a comments form on my blog - AMP does not support normal forms. You can use GET forms as usual, but for post you need to use XHR. 
  3. Forcing the user to login before they can post a comment - AMP has very specific requirements for validation which requires you to make XML requests to certain pages and which requires the pages to return certain responses. I have this working right now, but there are still some kinks I need to iron out.

I will post more articles on each of these three issues and my solutions to them over the next few days, as I get the kinks worked out.

Labels: coding , laravel , amp

1 comment

Many years ago, before cloud servers existed, I worked for an ISP. We were running Linux servers and we had way more problems with them than one would think possible. It seemed like every other month the servers would crash and we would lost most of the data on them. Back then we had a tape backup system, which seemed almost as failure prone as the servers, so when the crashes happened there was rarely any recoverable data.

As a result of that experience I am meticulous about always having my important data backed up. All my code is either on GitHub or BitBucket, so the only thing that exists only on my servers is my databases. A couple of months ago I decided I needed to have that data backed up regularly and after considering a few options I decided to back it up to Amazon S3. I wrote a two piece solution consisting of:

  1. A shell script to dump the databases to files, and then executes...
  2. A Laravel command to upload the dump to my S3 bucket.

Since the PHP part was a command I could just call it from my shell script and schedule that as a cron job. Yesterday I decided to turn the Laravel piece of that into a package called escuccim/s3backup. The code was originally written specifically to upload my DB dumps to S3 and had most parameters hard-coded in, so I added a few options to the command and updated my shell script to pass them in.

The package currently only works for a single file at a time, as that is all I need it to do, but I may add support for directories at some point in the future. The package is available through packagist although to use it you currently need to specify version dev-master.

Labels: coding , laravel

No comments

Laravel Socialite

March 1, 2017, noon

When I worked on this site I implemented a "login with Google" feature for which I used Google's Authentication API. But I used it manually. I used Google's Javascript function and wrote a controller to handle the data the API returns. It works, but it's a bit clunky and far from ideal.

Just today I used Laravel's Socialite package for the first time. It can handle Oauth requests for Google, LinkedIn, Twitter, Facebook, GitHub and BitBucket - and it's much, much easier to use than it was doing it myself. When I was looking into using Oauth I found a Laravel package to integrate Oauth logins, but it was very complicated to use. It created about a dozen tables and I ended up abandoning it to write my own code for integrating with Google.

With Socialite all you do is put the Client ID and the Secret's into a config file and add two functions into your LoginController - one to handle the login attempt and one to handle the callback. The login function just directs the attempt to the appropriate provider:

return Socialite::driver($provider)->redirect();

And the callback function gets the information returned by the provider:

$user = Socialite::driver($provider)->user();

In the callback function I also handle adding the user to my database and logging them in. Next chance I get I'm going to take out all of my Google Javascript code from this site and replace it with Socialite. I couldn't believe how simple it was.

Labels: coding , laravel

No comments

New Localization Package

Feb. 28, 2017, 5:09 p.m.

As a result of figuring out what was going on with the session and the middleware yesterday I was able to rewrite my localization code and greatly simplify the whole project. Previously I had been calling a function to set the language in every single controller action that returned a view, I was able to eliminate all of that and consolidate everything in the middleware.

I made another package - escuccim/translate - that has two parts:

First is the middleware which does two things:

   a. Checks the subdomain to see if the subdomain corresponds to a language. If so it sets the app locale to the appropriate language.

   b. Checks to see if there is a session variable with the language in it, if so it sets the app locale accordingly.

The key for me here is that if there is a locale specified by both the subdomain and the session, the session takes precedence, thus allowing the user to display the page in whatever language they desire, irregardless of the subdomain.

The second component of the package is a route which accepts a locale as a parameter and sets a session variable to that locale, so that the middleware can then access that information.

This package is available on my GitHub and my Packagist. When I am done testing it you can install it via composer.

I'm glad I took the time to investigate the session/middleware issues because figuring that out allowed me to replace code that was unneccessary and ugly to look at with a nice, simple, elegant solution.

Labels: coding , laravel , localization

No comments

Archives