Laravel 5.4

March 4, 2017, 2:04 p.m.

Yesterday, after playing around with Laravel 5.4 for a few days on my dev environment, I upgraded this site. The only issue I had was with the testing, which I addressed in the previous post. The PHPUnit issues were easily resolved by installing laravel/browser-kit-testing and updating my existing tests to reference the new BrowserKitTest.php class instead of the old TestCase.php. The issue of the naming of the test files was in fact due to autoloading, and I resolved it by adding the following to my composer.json under the "autoload-dev" classmap section:

"tests/BrowserKitTest.php"

After upgrading from 5.3 to 5.4 you need to clear your view cache, which you can do with:

php artisan view:clear

And the upgrade guide also suggests clearing the route cache with:

php artisan route:clear

I have never had an issue with the route cache, but I have often had issues with the view cache, so I personally clear my views after most of my updates.

The other thing to be aware of when upgrading to 5.4 is that tinker is no longer part of Laravel, so needs to be installed separately as laravel/tinker. I believe it is installed by default with a new installation of 5.4, but if you are upgrading you need to do this, especially if you use tinker as frequently as I do.

I haven't used any of the new features of 5.4 yet, from reading the upgrade guide there aren't really many features that jump out at me as something I would make a lot of use of, but I'm sure I will in the future.

Labels: coding , laravel

1 comment

Update to LaraBlog Package

March 4, 2017, 2:04 p.m.

I made an update the other day to the LaraBlog package. I added the ability to reply to comments and for users to delete their own comments. At first I had a hard time figuring out how to display the nested comments, as theoretically you can have an infinite number of replies to a comment, so how do you determine the inset when Bootstrap only has 12 columns?

This was easily resolved by two realizations:

  1. With Blade includes I can recursively include a template into itself.
  2. Bootstrap doesn't use 12 absolute size columns, but divides the available space into 12 columns.

So what I did was update my Blog model so that when getting the comments for a blog I only get the original comments, not replies. Then I added to my Comments model a function to get the replies to a specific comment. 

I already had my comments display in a separate view which displayed the form to leave a comment and then all of the comments for a specific post. I separated this out into multiple views:

  1. The old comment view - comments.blade.php - now has the formatting and then includes the _form.blade.php and the comments index view.
  2. The _form has just the form to submit a comment.
  3. The comments index loops through the comments and for each:
    1. Includes the comments show view and...
    2. Loops through the replies and includes the index for each
  4. The show.blade.php displays each comment and includes the _form which is hidden until the user clicks on reply.

The index, when including replies, leaves a blank column to the left of the replies, which, when recursively included in the levels of nested replies, will size itself to the available space, so that the indent gets smaller on every nested level of replies - but there could theoretically be an infinite level of nested replies without breaking anything.

I had never thought of recursive including of views until I came across the idea on stack overflow while looking for a solution as to how to address what looked to be a nightmare of infinite nested loops; but that idea provided a simple and elegant solution to what was looking to be a complete mess.

Labels: coding , laravel

1 comment

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

Archives