Navigate in Twig namespaces in PhpStorm

| Comments

I've gotten so used to have everything be clickable or navigable in PhpStorm. "I wonder what that function deep in the vendor folder looks like?" - I command click on Mac or ctrl click on Linux (or command+b/ctrl+b), and boom I go to the function definition. I don't know how I lived without it in the past.

But when I was writing a lot of Twig this spring I was sad that the file in Twig was not navigable like this: Add Twig namespace in PhpStorm

It took me forever to find out how to set it up. You need to install the Symfony plugin and either manually add the namespace under "Languages & Frameworks" -> "PHP" -> "Symfony" -> "Twig/Template": Add Twig namespace in PhpStorm - or even better, you can add a file called ide-twig.json where you tell the editor where to find files from a namespace. If you namespace was called "mynamespace" your file could look like this:

  "namespaces": [
      "namespace": "mynamespace",
      "path": "templates/stuff"

where the path is relative to your Twig templates.

The feature with the ide-twig.json file was added in the Symfony Plugin in version 0.11.110 years ago, but I've not come across much documentation for it. So now it's in this blog post.

Going back to a new job

| Comments

It seems I'm one to like going back and forth between jobs, so now I'm going back to work for Reload. I've loved working for Information and I'm going to miss the people there a lot, but I decided it was time to try something new (and old I guess) again.

Like last time I changed jobs I know some people already where I'm going, but a lot has also happened in the almost 4 years I've been away, so I'm looking forward to getting to know new people, do more drupal, and learn some shiny new technologies too.

Mexican street art as pixel art

| Comments

I'm slowly working my way through ES6 for Everyone by Wes Bos. It's been almost 6 months since I did the #javascript30 thing and I have been trying to do little projects every now and then to keep what I learned a little current.

The ES6 course has a lot of things that I already know now - and that feels great actually. I understand it much better when I get it explained again and when I get to play with it a little.

Today I had the perfect combination of no plans all day, dreary weather, and acute lazyness, so I stayed on the couch all day playing around with arrays in ES6 and some pixel art. I have loved geometric art since I was a kid, so when I stubmled upon this photo I took of some street art in Oaxaca in the spring, I decided to recreate it for the browser with JavaScript. I am aware that there are libraries out there that lets you do this — or even editors, but I wanted to make sure I played with some good ole vanilla JS.

So here is a pen with my browser version of the street art frieze from Oaxaca that inspired me. The street artist was likely inspiered by the unique friezes at the Zapotec archaeological site Mitla.

See the Pen Copying street art frieze in pixel art by Camilla Krag Jensen (@naxoc) on CodePen.

It was good fun to write code for the fun of it and doing "art". I might stick with pixel art and friezes from Mitla for a while. This one just begs to be done with box shadows:

12-05oaxaca077.jpgBy en:User:Bobak Ha'Eri - English Wikipedia, CC BY 2.0, Link

JavaScript30 - Day 30

| Comments

The final day of #javascript30 is a whack a mole game. I'm not going to write about that, but just do a little bit of evaluation on the #javascript30 month.

For whatever reason, it took me forever to get to doing the last day of #javascript30. I have really enjoyed the course and I was going on 25 days streaks of publishing a blog post with it, and then suddenly it took me over 2 weeks to write the last blog post.

#javascript30 was really great. I learned at ton that I might have known already to some degree, but I had never used to make something where I got to put the things together. It felt great to admit that while I have been making a living as a (backend) programmer for well over 10 years, I was bad at Javascript. Admitting that made it easier for me to choose to follow a "simpler" course on JS instead of tripping myself up with trying to use a framework while pretending that I understood ES6, Webpack, and tons of other things at once. The course is really well put together and I enjoyed the tasks very much. It seems trivial, but I find that it can be really hard to come up with ideas for small projects to work on when learning, but the projects in the course were really useful and fun.

My favorites things about the course were:

  • The array workouts
  • The speech recognition stuff
  • Learning ES6 syntax (wow, I really like that).
  • Really understanding the events the browser fires.
  • Doing cool shit that looks cool.
  • Felling like I have something to blog about again.

So thank you very, very much for an awesome free course, @wesbos. I would recommend it to everybody that is either learning Javascript or someone like me who has been using frameworks that kinda hid the real understanding of the language. Doge recommends

JavaScript30 - Day 29

| Comments

Day 29 of #javascript30 creates a countdown timer in the browser.


This exercise has some clever use of setInterval(). Understanding timers is a little more tricky than it seems, so take a good look at the examples in the docs too.

Select with

This one is so cool! I did not know you could do that. If you have an element that has a name like an input element, a link anchor, or even an image, you can "select" it by it's name. The name is a property on the document and will give you the same as if you used a querySelector:


Is the same as:

const myForm = document.querySelector('.form-class');

Pretty cool!


It the exercise, the minutes in the timer are padded with zero using a small ternary if. That might be the tersest way to do it, but I just wanted to mention string.padStart(). It doesn't have great browser support yet, but I like functions like this. Just give it the length you are shooting for and what you want the string padded with. It needs to be called on a string, so I had to "cast" to string first like this:

const minutes = Math.floor(seconds / 60);
const remainderSecs = (seconds % 60).toString().padStart(2, '0');
const display = `${minutes}:${remainderSecs}`;
endTime.textContent = `Be back at ${hour}:${minutes}`;

Where Wes' solution is like this:

const end = new Date(timestamp);
const hour = end.getHours();
const adjustedHour = hour > 12 ? hour - 12 : hour;
const minutes = end.getMinutes();
endTime.textContent = `Be Back At ${adjustedHour}:${minutes < 10 ? '0' : ''}${minutes}`;

Both are perfectly readable, but I do like the pad functions. There is a padEnd() too.

JavaScript30 - Day 28

| Comments

Day 28 of #javascript30 is a UI for controlling the playback speed on a video.

There is a bit of math to calculate where the mouse is moved over a bar that will control the video speed. It is a good idea to practice lots of things that use this recording of where the mouse is or where something is clicked. The math is not rocket science, but understanding the tools that are needed to get positions are important. I have read the docs for MouseEvent.pageY, Element.offsetTop, and Element.offsetHeight quite a number of times now and while they are also not complicated, I feel like I can do with even more practice with this. I'll cook up some codepen at some point where I illustrate what they do so I can use that as reference.

JavaScript30 - Day 27

| Comments

Day 27 of #javascript30 makes a neat horizontal scroll click and drag accordion or carousel.

There are a number of event listeners in use to achieve this. mousedown, mouseleave, mouseup, and mousemove. They keep a boolean that keeps track of whether the mouse is down or up, and they set the Element.scrollLeft property to the number of pixels the user dragged the element.

let vs var

I understand const completely now, but I was fuzzy on let vs var. They are quite similar, but they differ in scope. Once again, MDN's docs has a great explanation and example:

function varTest() {
  var x = 1;
  if (true) {
    var x = 2;  // same variable!
    console.log(x);  // 2
  console.log(x);  // 2

function letTest() {
  let x = 1;
  if (true) {
    let x = 2;  // different variable
    console.log(x);  // 2
  console.log(x);  // 1

So var has scope in the entire function, while let has function in the block it is in (and all sub-blocks in that block).

JavaScript30 - Day 26

| Comments

Day 26 of #javascript30 is making a dropdown menu that follows you along.

This lesson takes what I learned on day 22 about getBoundingClientRect() and uses it to move around a box behind the contents in a dropdown menu. We use mouseenter and mouseleave to react to the items hovered over.

Using opacity for "animation"

I learned a really cool trick from this lesson. To get a cool "animated" feel, first add a class that displays block on the hovered item, and then a setTimeout() with about 150 ms delay that adds another class that sets opacity to 1. The item should have a transition set in CSS too to make it really look good.

A gotcha when using this approach is that on mouseleave, when you remove classes that keeps a list item open — you might get there "early" because of the timeout in the mouseenter function. So in the mouseenter function, you can simply check if the other classes that don't use the timeout are present before adding it.

JavaScript30 - Day 25

| Comments

Day 25 of #javascript30 explains what happens when (DOM) events are triggered.

I made a pen based on the lesson to try to illustrate and understand better. It's at the bottom of this post.


Is when an event "bubbles" up the DOM. In the example with 3 nested divs with an event listener on all of them, a click on the inner one will trigger the click listener on all of them. Note that this is the item the listener is on, but is always the item that was clicked.


In JS this means that the event will keep bubbling up (or capturing). If you call e.stopPropagation() the propagation stops.

Event listener parameters

The addEventListener() function takes an optional options object. Of these, capture and once are interesting.


Will allow the event to fire once and then remove the event listener.


I think the easiest way for me to understand this is that when this is true, the events bubble backwards. Try playing around with the pen example to try and make sense of it :)

See the Pen Event options and propagation by Camilla Krag Jensen (@naxoc) on CodePen.

JavaScript30 - Day 24

| Comments

Day 24 of #javascript30 is making a navigation bar that sticks to the top of the window.

This is something I have done more than once before. With some frustration, though. The same effect can be achieved with CSS's position: fixed, but you still need JS to slap on the class or property at the right time.

scrollX and scrollY

Keep in mind that that IE does not supprt these two at all. Edge does, but to be safe, use pageYOffset or pageXOffset - these are aliases for scrollX and scrollY. See the docs for scrollY for an explanation.