Category: Web Development

VueJS and Django using them together

If you have been a web developer for some time, eventually you realise you have been wasting a lot of time and doing things wrong (or at least making your life difficult) if you have not been using Django and VueJS.

Django being the backend where the data is stored and where resources are maintained, deleted and created. VueJS being the frontend where relevant data is displayed in a concise and logical way. They both do there respective duties pretty well…in my opinion like a dream.

They also both benefit from a relatively shallow learning curve to start with.

Getting these 2 great frameworks to play well together is an important part of creating a web application that is versatile and a joy to work with.

So without further ado…how do we get them working together

VueJS and Django a quick overview

There is a great presentation given by Andrew McCracken on this topic and a lot of the info in this blog post is derived from that presentation.

Something to keep in mind when thinking in the MVC context: With django the view is really the controller and the template is really the view.

So django already has the template part and VueJS is also a templating library amongst other thing, so there is a bit of overlap. However, if we create a frontend agnostic backend (An API) then they will work together much like how they were designed.

So Django can be used with the Django Rest Framework (DRF) to provide the API and Vue can be used with vue-resource to interact with the API.

Django, Vue and the template

One aspect which jumps right at you is that when displaying a variable from data in a template…both django and vue uses the {{ my_var }}double braces (for a reference on brackets, braces and parenthesis)

Django’s variables will be resolved first and it will break your intended template.

There is a horrible way to get around this that I have used:


{% templatetag openvariable %} build.fields.description {% templatetag closevariable %}

But there is a nicer way to do this by just changing the configuration in vue to use the square brackets instead of braces

In the global configuration add:

Vue.config.delimiters = ["[[", "]]"];

So Vue template tags can now be easily distinguished from django ones.

Other aspects

I am building out a project with a bit more than just including the pre-packaged Vue file and am using webpack to bring in Vue so a few issues will no doubt come up and I will post them

 

Getting Started VueJS

To bootstrap the project execute the following commands


sudo npm install -g vue-init
vue init webpack frontend
cd frontend/
npm install
npm run dev

This install vue-init so you can bootstrap your project which in this case I have called frontend

But now you must be thinking…well node is serving the site wouldn’t django be serving the site in my case. And yes, I think the same way but then maybe we won’t have access to the auto-reload and other features

Now after doing this I was Unsure…

About how to wire up Django and Vue with webpack, so I reached out to the community and Jarrod Hobbs suggested looking at django-webpack-loader

Why is Laravel 5 So Bad?

Coming from Zend 1 and Yii 1, I find Laravel has made things complicated for itself. It has also tried to be too much of a unique item. Let me explain why Laravel 5 is so bad.

why-is-laravel-5-so-bad

Who am I to Comment

Well I’ve used Yii 1 and Zend Framework extensively. You can take a look at my Yii share trading site. I have also dabbled, gone through a video tutorial and built a simple site and API with it, with Ruby on Rails 4. I have also worked with Magento (Sigh) and the Django Rest Framework.

So pretty much the best non-js server-side frameworks. So with decent standing I thought I would take a look at Taylor Otwells master piece, Laravel 5, before I check out Yii 2. Unfortunately in some respects I am disappointed (take note I’m only about 20% through an ebook teaching laravel)

The Good of Laravel 5

  • It leverages off other new and cool stuff: embracing npm, task runners, dev environments
  • It uses the best (not just the easiest or most popular) out of the “new and cool stuff”
  • Homestead A great development environment and cli tool

The Bad of Laravel 5

  • You have to manually create a view and action, no generator
  • laravel and php artisan command line utilities could be combined into a single laravel command
  • The directory structure is strange to the point of complexity. Controllers for example are not found in the app folder but in the app/Http folder. Views are not in the app/Http directory next to controllers, they are in a separate top level folder Resources/view

The Ugly of Laravel 5

    • It wraps everything as its own special thing: homestead is a wrapper for vagrant, elixir is a wrapper for gulp. Just use the tools as they are because it will allow php devs to work on a host of other frameworks and technologies.
    • Strange View and layout directives (maybe I need to get used to them): @yield, @extends, @section, @show, @parent. It can get rather complicated.
    • The Blade templating system, as above, declaring variables in views makes it seem like you are using angular, react or meteor. Sometimes I think php short tags make things simpler than: @foreach, @endforeach, @if, @else, @elseif, endif.
    • No generic route for Controller/Action/Id

Update (26-10-2015)

Another thing to notice is the caching of views. This feature is on by default and you have to hack it to turn off view caching. What this means is you can’t pinpoint in what file an error has occurred (usually a typo). So you end up with a crap error like:

Crap-Laravel-View-Caching-Errors

Summing it Up

Laravel 5 is probably the best PHP Framework. It’s still not great though but it a massive step in the right direction. I can’t help but think that yii2 may have got the rails to PHP conversion done a bit better. You will have to know Laravel 5 though because of this report, so might as well start linking it.

The best feature of Laravel is by far the Standard Local Development Environment: Homestead.
So instead of having to install all these crap PHP extensions and what not you can create a repeatable local laravel dev environment that just works. Furthermore if you use the homestead composer tool, creating shared folders and adding multiple sites to virtual host id a breeze. It makes development much better. Unfortunately frameworks like Django and Rails aren’t as Vagrant friendly and hence you have to create an ansible script to setup your boxes which is a bit of a schlep.

Update 2 (29-10-2015)

There is also the issue of the blade templating system. Which is awesome, except that it is not strict and allows any old crap to pass.

Such as ending a section with @endsection instead of @stop

or specifying a section with:

@section('title', 'Establishment Name')@stop

Instead of:


@section('title')
Establishment Name
@stop

No error messages, and nothing in the logs. However it creates a huge problem in that…the session cookie is not set correctly due to template errors.

So now you will never be able to maintain a logged in session and all forms will now fail with a:

TokenMismatchException in VerifyCsrfToken.php line 46

Crap-Laravel-View-Caching-Errors

laravel CSRF Token Mismatch Excpetion

Also you will find it is very hard to peruse the templates to find where the actual problem is and you will have to resort to deleting large portions of the template until the problem code is found.

So I’ve created this git repo, so you can lint the blade templates and find the issue. Why Laravel doesn’t have one built in with elixir is anyone’s guess.

Implement Testing on Yii Framework 1

How to Implement Testing on Yii Framework 1

So you’ve finally realised to verify the quality of the code in releases and make sure everything is working before you deploy to production you need to test.

First we’ll use phpunit for unit testing.

Installing PHPUnit with Composer

We will only handle installing the required packages with composer because PEAR and PHP Archives are old news. Check out composer first, if you haven’t used it.

Before we get going make sure your composer is updated


composer self-update

First of all it is easier to use the global composer and install phpunit globally:


composer global require "phpunit/phpunit=4.8.*"
composer global require "phpunit/phpunit-selenium": ">=1.2"

But make sure you update composer.json


 {
      "require": {
          "php": ">=5.3.2",
          "yiisoft/yii": "1.1.*",
          "yiiext/migrate-command": "*",
          "phpunit/phpunit": "4.8.*",
          "phpunit/phpunit-selenium": ">=1.2"
      }
  }

But you will still get warnings like:

PHP Warning:  include(PHP_Invoker.php): failed to open stream: No such file or directory in /var/www/site/vendor/yiisoft/yii/framework/YiiBase.php on line 432
PHP Warning:  include(): Failed opening 'PHP_Invoker.php' for inclusion in /var/www/site/vendor/yiisoft/yii/framework/YiiBase.php on line 432
PHP Warning:  include(PHPUnit_Extensions_Database_TestCase.php): failed to open stream: No such file or directory in /var/www/site/vendor/yiisoft/yii/framework/YiiBase.php on line 432
PHP Warning:  include(): Failed opening 'PHPUnit_Extensions_Database_TestCase.php' for inclusion in /var/www/site/vendor/yiisoft/yii/framework/YiiBase.php on line 432
PHP Warning:  include(PHPUnit_Extensions_Story_TestCase.php): failed to open stream: No such file or directory in /var/www/site/vendor/yiisoft/yii/framework/YiiBase.php on line 432
PHP Warning:  include(): Failed opening 'PHPUnit_Extensions_Story_TestCase.php' for inclusion in /var/www/site/vendor/yiisoft/yii/framework/YiiBase.php on line 432

So we actually need more stuff, namely dbunit, phpunit-story and php-invoker:
So add the following to composer.json


 "phpunit/php-invoker": "*",
 "phpunit/dbunit": ">=1.2",
 "phpunit/phpunit-story": "1.*"

If you installed globally you need to install using:

composer global require {package}

But when running the tests from a task runner or continuous integration like jenkins, it is best to use the path to the composer phpunit in vendor.

Installed, Now let us write our first unit test

The folder where the test suite (class consisting of test functions) is <code>/protected/tests/unit</code>.

The file name needs to end in Test.php so for a test class: DummyTest.php.

Now the contents of the file:

<?php
 class DummyTest extends CTestCase{
   public function testTrue(){
     $var = true;
     $this->assertTrue($var);
   }
 }
?>

Running the Test

To run the tests you need to be within the test folder:


cd protected/tests
//run all the tests
../../../vendor/bin/phpunit unit
//run the single test suite
../../../vendor/bin/phpunit unit/DummyTest.php

The test results (output) is not the best.
A single dot . means a test passed.
A letter F means the test failed.

Setting Things up and Tearing things Down

Usually you will need certain things to happen before running a test. Such as: instantiation of an object or a connection to a database. To this we use setUp(). Which is a method called once before each test. Often calling the parent setUp function is good practice. Conversely, callingtearDown() is run after a test is run to free up resources.

setUp() and tearDown()

are run before and after each test case whether or not the test succeeds.

There are also

setUpBeforeClass() and tearDownAfterCall()

which are only called once regardless of test cases.

Fixtures

What are Fixtures? They are a state of being of the test. They are mainly used when databases are involved.