 I'm going to be speaking about a dashboard I created a while ago using Laravel, Vue and Pusher. I'm Friek van der Herten. I'm a partner and a developer at an Antwerp company called Spassie. Like many of you, I'm active on Twitter. My handle is Friek Merse and I have got a blog Merse.be where I talk about modern PHP and Laravel development. Now I do a couple of other things as well. I run the local PHP user group in Antwerp together with my buddies Dries and Frederik. If you're ever in the vicinity of our beautiful city, I want to speak at our user group. Let us know. We are looking for speakers of any level and the talks of any length. So get in touch. I also have a site project called ODEAR app, which is a SaaS that can monitor your websites to see if they're up, if they're not containing mixed content. It will send you notifications if there are broken links around. It's my first SaaS app, which I launched like a month ago. But my main gig is Spassie. That's my company. It's been around since 2003 with your eight websites, applications and web shops. Our team is quite small. We're only seven developers and one manager and we specialize in Laravel development. Now before heading into the wonderful world of dashboards itself, I want to say a few words about open source software. At our company, we create a lot of open source software and we have a big list on our company website of all the packages that we've created. We currently have 160 public repositories on GitHub. Our packages have been downloaded now for nine million times and they are being downloaded now for one million times a month, which is quite nice for a company that is small of size. And we see that creating packages has a lot of benefits for us. Of course, we learn a lot by just solving the problem the package tries to tackle. We have to write quality documentation because without documentation, nobody will know how to use our stuff. We have to write very good tests because without tests, nobody is going to trust our packages. If you take a look at the code, then I hope you'll conclude that we know our way around PHP and Laravel. And of course, we're also using those packages in our own projects. And if you're in a place in your company where you can advocate the development of open source software, I highly encourage you to do so because there are really nothing but benefits. Now, I get asked a lot how does our company manage creating and maintaining so much open source software. That's really a talk of its own, but I've blogged about that and that's that last link on the slide here. Now, all those packages, I should have mentioned that they're not entirely free. There's a special license on them called postcardware. And if any of our stuff makes it into your production environment, you are required to send us a postcard. This is our address, currently missing 9 million postcards. So get your license in order. We have a magnetic wall in our office where every postcard gets its place. Now, let's turn around in our office. This is our actual office. And what you see there on the other side of the wall is a dashboard. Let's step in a little bit closer. There we are. That's our dashboard. Now, before taking a technical dive into it, let's first discuss what's being displayed here. Now, the first tile here is a Twitter tile. It shows in real time each tweet where our company is mentioned in. Now, the next one is our calendar tile. It shows all the events that are important for our company. Each member of our team is quite passionate about music. So we want to know which music is playing in our office. And that tile displays that here. We were listening to an excellent number by Sonic Cute. This tile really needs no explanation. That's just the weather and the time. You can see that I took this screenshot on a particularly hot day in the summer. It was 27 degrees at half past 10. So that was nice. I've talked a little bit about our open source stuff. We're quite proud of that. So we display some statistics of the downloads. These numbers we fetch via the packages. I call this one the happy tile. This is the unhappy tile. So it shows how many issues and PRs are open. In the middle, there's a tile for each member of our team. And it displays the tasks of the things they should be working on. And we have here a tile that says if our sites are up, if any of our sites are down, then this tile will become yellow and we will immediately see, hey, we should take a look at this site. And that is what is being displayed at our dashboard. The dashboard itself is also completely open source. In this repo on GitHub, you'll find the actual code that's being deployed on our server. So feel free to fork it. After this talk, you'll be able to set up and customize a dashboard of your own. Okay. Let's get a little bit technical and start off with a high-level overview. So in short, the dashboard is a single HTML page. It's being displayed, full screen in a browser. And once we load that page, we will never reload it again because otherwise you see it build up. And we want our dashboard to be very, very calm. We don't want to attract much attention to it. That's why we don't reload it. So what do we do to keep it up to date? Well, we update the dashboard with the Ava skipped. And every tile has its own update frequency. So the packages tile, we update that once an hour. And the clock is being updated once a second. Which technologies did we use for this? Laravel, Pusher and Vue.js. That are the three big ones. Now, a quick show of hands who here is familiarity with Laravel uses that. Okay. Quite some people. Nice. Pusher. Not so many. A few hands. And Vue.js. All right. Also a few hands. Now, if you don't know Laravel, Pusher or Vue.js, no problem. I'm going to take it slow so you can follow. So first one, Laravel. It really needs no introduction these days anymore. I think everybody has at least heard of it. It's a PHP framework. For this project, we use the latest version, which is Laravel 5.6. And what it must do in our project is it will render that initial page. And it also will fetch data from all the APIs that the dashboard uses. So for that list of events that's being displayed, we use a Google calendar for that. So Laravel will reach out to the Google calendar API to fetch the data. For the current music that's playing in our office, we use a service called lastevm for that, which has an API where you can let iTunes or Spotify send your current track to and you have an API where you can fetch that back from. Laravel is also responsible in this project for broadcasting an event when new data arrives. And that event that's going to be picked up by the client side. Yeah, I've already said a little bit about this. So yeah, we use a few APIs to get data. I searched around for a few packages to work with the Google calendar API and with Twitter and with lastevm, but I found none. So we created a few packages of our own. And we also use the excellent KNP Labs GitHub API package to get the statistics out of GitHub. Pusher. Pusher is a service and they describe themselves as a service that provides full duplex communications channel over a single TCP connection. Now, that's a mouthful. We tend to call this web sockets, but I like to call it magic because it is so fast and it is so reliable. And we use this to transport events from the server to the browser. So Laravel will send a signal to Pusher and Pusher will send it over to the client side. It happens in real time. It's really, really fast. It does it also in a secure way because there isn't really highly sensitive information being displayed on a dashboard, but the current tasks each member of our team should be working on. We like that to be a little bit private. I should also mention that Pusher is a paid service, but they have a free tier where we can, I think, send 100,000 events a day for free. And the dashboard currently uses 4,000 events. So you're pretty good in the free tier. Sorry. Last technology, Vue.js. Vue.js is a very easy to pick up JavaScript framework. And it makes it easy to make reusable components. And in our dashboard, each tile that you see on the dashboard is its own Vue component. Now, each tile will listen for incoming events. And when it sees an event coming in that is targeted at it, it will update itself with the new information contained in the event. Now, this is the whole flow in the little schema. So we have the external services on the left here. Laravel will fetch new information. And when it has new information, it sends an HTTP request to Pusher. And Pusher will send it out to the browser via WebSockets. That's in a bird's-eye view how the dashboard is working. Now, I can talk a lot about this dashboard. But yeah, it's more fun that you get a little bit of a feel of it. And yeah, I'd like to just demonstrate some code to you. What are we going to cover? The grid system. How can we position things on the dashboard? Spoiler. It's really easy. We're going to see how the clock tile works. That's for the people that don't know Vue.js as well. It's really a crash course in Vue. Then we are going to see how the packages tile works, because we are using the APIs. Then we see the entire flow. And then we'll have a little bit of fun with the Twitter tile. So there will be some live coding. There we'll use an internet connection. Lots of things can go wrong. People said to me, don't do this. But we're going to do it. Okay. Let's do it. Moment of glory. Let's minimize key note here for a sec. And here, I hope you can see this all. Yeah. This is a local version of the dashboard. Slightly adapted that just runs on my Mac here. So you can see there's not a lot of information being displayed. We have just a clock here. Now, let's switch over to PHP Storm. Is this readable in the back? Yeah. Okay. Cool. So people that have experience with Laravel, they immediately recognize, hey, this is a structure of a Laravel application. There is only one Vue in this dashboard being used, namely the Vue that you see. And in Laravel, Vue lives in the resources folder, Vue's dashboard. And we see this. It's not much HTML here. You can see that we have some weird tags here going on. Those are the Vue components. We'll dive into that later. What I want to show you first is that every tile here has a position thing going on. E1 here for the time weather. You should think of the dashboard a little bit like an Excel spreadsheet where every row has a number and every column has a letter. So if I put this in A1, this will go into the top. Let me clear out all this garbage here first. Oh, a little bit too much. Only this should go. And this should go as well. So we have a very Spartan dashboard going on here. Let's switch to the browser. And sure enough, we have that clock here running. Now, if you want to, you can make it a little bit bigger, your tile. The positioning system supports ranges. So if I want to make this a little bit wider, I just put the right range here. And you can see it's a little bit wider. What you can also do, of course, is if you want to have multiple clocks, maybe for some reason you want to display another clock. You can put this on the second row, another clock. Now, for a clock, this doesn't really make sense. But remember those tasks being displayed for each member of our team. That's actually the same tile with just another parameter on it. So yeah, you can see positioning things is very easy. If you want to have your dashboard have an extra row or column, just add another one here. And you have an extra row. So that's how that works. Cool? Yeah, yeah. We at Sparcy, we have one employee who is in a different time zone. And so yeah, we display his time as well on it. So that's a good use case for multiple clocks. Okay, let's restore everything here. So we're back to the original dashboard here. Okay. Oh, still that positioning thing back. Okay. Let's take a look at how that clock works. So this is the little view crash course that I'm going to give. So I've said that yeah, we have some really funny HTML tags here. Those are actual view components. View will scan the DOM and it will replace the HTML in the strange tags by the HTML that's defined into that component. So we have that time weather thing here going on. Let's take a look at that component itself. Now in Laravel, all Javascript lives in resources, assets, Javascript. And I've created a folder here called components. You can see that for each style, we have a file here. Now let's take a look at that time weather component thing. And this is a view component. So in a component, there can be three sections, namely a templating section where HTML lives. And this is the HTML that will actually be replaced or that will replace this tag here. We have a script section here where all the behavior of the component is. And we don't use it in this project, but you could also have a style section where you can put CSS that this component uses in. But for this project, we've done it in a little bit more traditional way where we have all the CSS in separate files. Now let's take a look at the HTML here. So this is what this HTML will end up in the DOM eventually. And you can see here that we have a few parameters here. We have here date and the time. And each view component has a thing in it called state. So that's the information where that's most important for rendering this component. If I go to the behavior here, then you can see here, yeah, the data function contains the initial values of that state of daytime. It's an empty string. A view component also has a created method which you can compare to a constructor in a PHP class. And what are we going to do here? We are going to call a function called refresh time. That function refresh time, what's it going to do? It's going to use a popular JavaScript library called moment to parse dates and times. And it's going to set the actual date and the actual time into that date and time state of this component. And what you should know is whenever you update the state of a component, the component will re-render itself. So as soon as I put another thing in the time variable here, the component will re-render. Now that refresh time method, we also tell to JavaScript, hey, run this function every second. So every second that time variable and that date and time variable are being updated. And that's how you get this in the HTML. That's very basic few things. I hope I've explained it a little bit correctly. Okay. Let's delve a little bit deeper and take a look at the packages component. Because that date time component is just JavaScript, there isn't anything server-related going on. Okay. Let's close some folders. And let's see how the dashboard fetches the data from packages. So if you use Laravel, then you know that every command is in the console folder here. And I've created a components folder here. And you can see that I have a subfolder here for each tile that fetches data from APIs. So I have got here a package, a packages task called fetch totals. Now again, if you use Laravel, you immediately recognize, hey, this is a command. I can run it from the terminal like this. But you can also schedule those components. I've said that the dashboard will fetch data periodically. We just use Laravel's built-in scheduler for that. And in Laravel, you can schedule commands in the so-called console kernel. And this is that kernel. And when I scroll a little bit down, you can see here that we have a schedule command. And for the fetch packages total, you can see here that Laravel will just execute this every hour. And that's how we automatically fetch a new data. Now, let's go to the packages task itself. What do we do here? Yeah, we spin up a new instance of our packages API. And then we are going to do some mumbo jumbo here to fetch all the statistics of our packages. And we are going to sum it up. And the most important bit is that the total daily downloads, monthly downloads, and total downloads, they will be returned as an array in this total's variable. So here we have an array with these keys in it. How are we going to transport it to push it? Well, Laravel has a built-in system for that as well. You can say in Laravel, hey, fire off this event and broadcast it to the broadcasting service that's being configured. Now, that broadcasting service for this project is push it. Let's see how we can fire off an event to push it. So it's very easy. We have a helper function called event. And we have a class here, total's fetched, which represents that event. And we pass it to total's variable. If I open up that event here, you can see here that's a simple class. And what we do here in the constructor is we get that array. And then we set every key in that array to a public property on that class. Why do we do that? Because in Laravel, if you are going to broadcast an event, then the data being broadcasted, that are the public properties. So Laravel will just see, hey, these are the public properties of the event class. I'm going to broadcast that. That's why we put the public properties here. Now, if I delve a little bit deeper here, you can see here that the total's fetched class extends the dashboard event class. And if I open up that, then you can see here that this class implements an interface called should broadcast. And should broadcast, that's the hint that you give to Laravel, hey, this event should really be broadcasted. It also has a single method called broadcast on. And we use a private channel called dashboard. Now, pusher, you can use different channels to push things to pusher. It's a little bit like a radio. I transmit something on this channel. And only the ones listening on that channel will receive it. We're using one single channel in this project called dashboard. Okay. Before heading over to the client side to see how we capture that event, let's just see that it's actually working this part. Okay. So if I go to Chrome again, you can see here that we have zeros here all around. I have also here opened a second tab on the pusher service. Let me clear this out. This is the debug console of pusher. It shows everything that pusher receives from our Laravel application and what information is being pushed. Okay. I'm in the wrong directory here. It should be dashboard demo. Sorry about that. If I just run that command manually now that you've seen, it's called fetch packages totals. Let's run it. I should explain this. I have a command A here and that's just alias to PHP artisan so that I don't have to type that the whole time. So A dashboard fetch packages totals. And with any luck, we should see some numbers popping here up. And yeah, this is the live count of our packages starts. So it has worked. And if I go to pusher here, you can see here that there was an event on the private dashboard channel and the event was totals fetched and this data was being transferred. Now that starts thing, yeah, that sucks a little bit. That's from a previous version. I should clean that up. So don't mind that. But you see that the public properties of that event are being transmitted. Okay. Let's take a look at the client side at how we catch the event. So that's back into the resources folder, assets, JavaScript components. And we have a packages component here. It's a view component. So it also has that HTML section and it has that behavior section, a little bit of JavaScript going on here. You can see here that we have that daily monthly total thing here going on. And if I go here into the behavior of it, there are a few methods in it. And one is get event handlers. And one of the event handlers here is packages totals fetched. So this function will be executed whenever we see this event coming in. And that function gets a response. And what are we going to do? We are going to take off the daily, monthly and total variables of the response and we'll put it into the internal state of the component. And remember, whenever we update the internal state of the component, the component will re-render itself. And that's why you see these numbers coming in. Okay. Let's delve a little bit deeper into that get event handlers function. How does it work? And this, if you don't know your way around JavaScript very well, it might prove a little bit tricky. But if you don't understand the things, that's no problem at all. We won't build further up on it. So how does this work? I should first say that there is a special key on this few component called mixins. And a mixin is very comparable to a trait in PHP. You put a few functions in there that you want to have multiple classes or in this case components use. So in the echo mixin, everything with pusher handling is being defined. Now why is it called echo? Because under the hood it uses another framework called Laravel echo, which is a framework to easily handle web socket connections. Let's take a look at that echo mixin. So this is the contents of that mixin. And you can see that it only has that created method here. So this created method, it's being applied to the packages component. And what does it do? So whenever this component is created, we will execute the function getEvent handlers, which is this function. And what will it do? It will register what's being returned from getEvent handlers with the echo instance on the root application. So here we use Laravel echo itself. And here you can see we listen to the private channel. And whenever an event name comes in, which is this part, we are going to give the response to the handler and execute that. So this function will be executed. So that's what we do here. So when the component is created, we are just registering everything, this method returns with Laravel echo. So that's a little bit deep. If you have some questions about this, just hit me up after the talk. And I'll explain it to you a little bit more. But that's how we handle things coming in from the webhooks. Okay, let's do one more thing. Let's have a little bit of fun with a Twitter tile. So actually let's do one other thing first. Now that I'm in the packages component, I've said that all data is coming in via WebSockets. So what do you think would happen if I just refresh the dashboard? It will have no contents, right? Because there are no events coming in. But if I refresh here, you can see these numbers stay. And how is that working? Because every time an event comes in and we change the state of it, we are going to write a copy of the state to local storage. And whenever we reload the dashboard, we are just reading the local storage to set up the internal state of the component. So if I go to the application here, the local storage one, you can see here the packages here are the numbers that are in there. If I remove that, then we have no numbers anymore. How does that work internally? It's also a mix-in. Because remember I've said mix-in is a little bit like a trait. So we use this mix-in for every component that we want to let it save its state. And I'm not going to go fully in this, but in view, you can define a watcher, which is a function that will be executed whenever a certain key in our state is changed. And here we say, yeah, just call this whenever the state changes. We are going to call save state. And let me close this up. Save state is here a function that just gets our internal state and saves it to the local storage. And this mix-in also will add a function at the created level. So whenever the component is created, we are going to call load state. And we're just going to get the save state and set it into the internal data of the component itself. So that's how that's working. If you want to have save state behavior to your view components, I'm happy to say that we've extracted that mix-in to its own package. So you can use it in your own projects. The package is called view save state. So that's how that works. Okay, let's have a little bit of fun with the Twitter component here. So the Twitter component is a little bit special one. It leverages the Twitter streaming APIs. So Twitter exposes a few real-time APIs where you can listen for every event that's happening on Twitter. You can really crash your machine with this if you listen for popular subjects then you get like a million events coming in your computer or your process at least will just crash. Now handling the Twitter real-time streams is a little bit nasty in PHP. That's why I created the package above it to make it easier to work with. And here you can see that we are using the Twitter streaming API. We're going to listen to the public stream which are all events. And when we hear one of those keywords here, we are going to send an event called mentioned with the properties of that of that tweet. And remember when we fire off that event and that whole dance with pusher will start over again. The information will be broadcast to pusher, the dashboard tile will listen for it and will display it. Now normally we use our company name here to listen for it. But I think it might be fun if we just do PHP UK conference here. And I hope that some of you are subscribed to Twitter and can send a few tweets so we can test this. This is the handle of the conference, right? PHP UK conference. And let's open the floodgates. So I'm going to start listening for things here. And now I await your tweets and I hope this will work. And yeah, I think so too. So you can have your moment of glory now on the dashboard. Very good, Martin. And yeah, those trying it out, they will see that it's really instant. Probably your tweet will be faster on our dashboard than the application on your smartphone will confirm that it is there. So yeah, that's how that works. And you can see it's really not that hard to do. Cool. I'm on the dashboard. Yeah. Maybe I should leave this open for a little bit. Well, I've done that at a few conferences and then it got a little bit nasty. So then I had to cheat it down. Okay. That's everything I had technical to say about the dashboard. Let's go back to the presentation. So I'm quite happy that that worked a little bit. Now, one thing that I want to touch upon is how we are displaying this on a TV set in our office. Well, behind our TV screen, there lives a little Raspberry Pi, and it's quite cool, because it is powered by the USB port of the TV itself. So you don't need any extra power cord for that. The Raspberry Pi is a Raspberry Pi 2. It uses Raspbian Jesse, which is the default operating system. And when it boots up, it will just show you Chromium 56, and it will go into full screen mode. Now, this is a very exciting part of the presentation for me. I have here a clone of our dashboard on this Raspberry Pi. This Raspberry Pi gets its Internet connection from my Mac. We will hopefully see the output soon on the TV screen. And it also will get its power from my Mac. So if I put it in, it should boot up and just show you the dashboard after it has booted up. So I hope we can switch to our little Raspberry Pi, okay, here it is, booting up. That's the boot sequence. Fingers crossed here. Everything is good here. So it will power up its graphical user interface. And you'll see that Chromium will display once, and you'll see it having a nasty restore tabs dialog. I don't know how to remove it. So I just quit Chromium again and booted up again. So that's how I do it. So it's gone now, and now we do it again. Ah, damn, and it didn't work. It still is there. Sometimes it does that. But hopefully the dashboard will at least come on. Yeah, that's the dashboard. That's the actual dashboard now. So if you treat something too sparsely, it will come there. So that's that. Okay, let's power that down again. And we're back at the slides, hopefully. Okay, cool. So you can try out this dashboard yourself. I have already mentioned that the source code is publicly available on GitHub. I've also written quite an extensive blog post about this, where I say mostly the same things that I've said during this talk, but I explained a few other components. Now, I've been babbling about this dashboard the whole time, so you might think, hey, this guy really knows this stuff. But the truth is that like most things that we do in our company, it was teamwork. And the other team members involved in this project were my colleague Wilm, who is responsible for the great looks of the dashboard. He designed the looks. And my colleague Sebastian, he scrutinized all my crap and made the JavaScript code look much, much nicer. Here are a few more packages that are of interest. I've demonstrated these dashboards with Pusher, but you can actually use a local node server on your machine, if you don't like using a service like Pusher. And the Laravel Echo server package, it will just mimic Pusher on your server, so you don't need to install Pusher. And it works really, really great. And I've touched upon our view safe state thing to easily save state from your view components. So that's all I had to say about this dashboard. I really want to improve this talk a little bit, so please, please give me feedback, good or bad on joint in. I've also uploaded the slides there. It's the wrong URL, but I'll tweet out the right URL later. Also, take a look at our company website. Probably we have made something, a package that can be used for use of you in the next project. Yeah, take a look at my blog if you want to stay current with PHP, and try out, oh dear, if you need a monitoring solution. That's it. Thank you.