Skip to main content

TrackBuilder 0.9.5

This release must be the near-final one before the 1.0 Minimal Viable Product is there. The only thing that seems to be missing is loading and saving tracks. That won't be too hard to add. Could be really simple saving just the text-strings in a file... but that's nog flexible enough. It will be JSON, opening up the possibility of a web-service, who knows. I'm having fun.

New in this release are "nudgeable" Double Curved Tracks, but the biggest thing is that the curved switches can now be nudged as well, when rotated. This way you can add a curved switch... rotate it so that the switch track is at the front, and it can be nudged so that the curved switch track connects to the railroad instead of the straight track of the curved switch.

Download TrackBuilder 0.9.5

TrackBuilder 0.9

And again another release with some improvements. Version 0.9 meaning it's pretty much "feature" complete for the MVP that I envisioned at first.

I've tidied up the code and it should be a bit less fickle now. You should be able to paste in whole strings of tracks and they should render.

The tracks that got added in this release are:

  • Cross Track
  • Criss Cross Track
  • Turntable
  • Stop&Go Crossing
  • Double Straight Track

I also made some macOS specific code not run if the app launches on Windows.

Known issues:

  • Double Curved Tracks won't "nudge" yet
  • Switching Tracks don't rotate or nudge
  • The app does not "follow" the entered track out of view so some scrolling is needed

Here's the download link.

TrackBuilder 0.8, Switching It Up

Another update to the TrackBuilder. This time there is support for switches and more vintage types of tracks and the "control panel" should stay a fixed width when resizing the window.

The tracks that got added are:

  • Brio's elusive Middle Straight, a piece of track that is 72mm long
  • Outer Curve of a Short Double Curved Track
  • Outer Curve of Double Curved Track
  • Curved Switch
  • Parallel Switch
  • Short Curved Switch
  • Cross Track

I've added the the schematics of a track I built recently, you can see where some "vario" is needed. But it's minimal and nothing to worry about. I used TrackBuilder to tidy up the track I had laid down as much as possible.

Brio track layout schematics

Next up will be "actual" double track curves I think. Now you need to add the inner and outer track separately, that's not good :)

And finally, the download link. As before, run it (on macOS) with: java -jar TrackBuilder.jar

[Update: Released 0.8.1 fixing the long curve radius and 0.8.2 fixing short curved switches getting badly calculated when rotating them. The download now links to 0.8.2]

TrackBuilder 0.7

[Edit: It has come to my attention that the app only works if you have the latest Java installed, and probably only on a Mac as well. ]

I couldn't just leave it with a sloppy UI like that so read up on Java Swing Layouts a bit and made some minimal adustments.

Fixed in this version:

  • Better resizing behaviour
  • Better layout of control panel
  • Better scrollbar behaviour

 

Known issues:

  • TrackBuilder does not follow the end-point of the track to keep it "in view". This means you'll need to scroll manually.

 

Download: TrackBuilder 0.7

Trackuilder 0.6

Had some more time today so I thought I'd make TrackBuilde a little more user-friendly.

New in this release:

  • Input track in TrackBuilder window, not on the command line anymore.
  • Track gets drawn on the fly.
  • Program does not exit on invalid input.
  • Input gets filtered. Only A, B, C, D, E, F, E' and F' are allowed.

 

Fixed:

  • Track draws immediately, no need to scroll or resize the window first.

 

Download: TrackBuilder 0.6

TrackBuilder 0.5

This version of TrackBuilder adds scrollbars and does not "end" after having entered the first layout. It shows the prompt again and waits for input for a new layout.

Fixed in this version:

  • The window in which the track is laid out does not scroll so if your layout is big it will fall outside of the window.
  • It seems that if you start your track with a straight it does not get drawn. I do not know why.

Known issues:

  • The track only gets drawn after clicking in the window.  

Download: TrackBuilder 0.5

Rudimentary Wooden Railway Track Builder

When you have a kid there's a chance you might be building wooden railway layouts at some point. And when you do you can "force" the tracks a little bit in order to make them fit, making use of what they call the "Vario" system.

Now, I like to build layouts with as little vario as possible. After a while the track has a lot of different track pieces, especially the short and long curve combinations skew things. With all these tracks on the ground you're never really quite sure if they make a perfect fit or not. You can of course hold down each track and line up the next one perfectly and work your way along thet track like that but I thought, what if I'd come up with a little tool that would let me add the tracks that I've added to the layout and let the computer tell me whether they make a perfect fit (or near fit) or not. A near fit is what I call a fit that is within 1cm of where the start and end of the track should meet and I consider that fine as well.

The tool is a Java .jar so you need the Java Runtime Engine (JRE) installed on your computer. When you download TrackBuilder it you can start it from the command line with java -jar TrackBuilder.jar

Go add the tracks you've added to your layout at home and see if they make a perfect fit.

Issues:

  • The window in which the track is laid out does not scroll so if your layout is big it will fall outside of the window.
  • It seems that if you start your track with a straight it does not get drawn. I do not know why.  

Download: TrackBuilder

Bensch on Drupal 8

Recently I quit working at the company I had been with for 7 years and decided to become self-employed. This, as it turns out, gives me quite a bit of free time... so I decided to migrate my very simple Drupal 7 website to Drupal 8.

Hosting Drupal 8

Before I could start the migration I had to get Drupal 8 running on the server. This did not go easily. Both the hosting company that I use, DreamHost, as well as Drupal 8 and Drush's insistance on using composer are to blame.

Composer's memory usage is crazy. It seems to easily use up to 1.5GB of memory if you let it do its thing. Shared hosting never gives you this much memory so having a Drupal 8 website actually got more expensive than having a Drupal 7 one. On DreamHost the PHP memory limit is 90MB as far as I can tell, I even had them up it temporarily to 512MB but my composer process would get killed time after time.

After 1 day of stop-motioning my way through a Drupal 8 install I opted for DreamHost's more expensive Virtual Private Server (VPS). I suppose they are happy.

Migrating to Drupal 8

The migration didn't go smoothly. I tried it with the built-in drupal_migration, drupal_upgrade and drupal_tools modules but it gave me errors with url aliases and comment bundles... but I didn't care too much. I do also notice that I have duplicate text formats because Drupal 8 has CKEditor turned on by default. I tried disabling the text formats that I assume got migrated but now I can't change anything to the left-over CKEditor ones because it complains about a "Full HTML" text format already existing and two text formats can't have the same name... whatever. I'll maybe do another migration to figure that out, I don't care too much yet.

Starting a theme

Other than that I did a very simple theme. I am not a front-end developer so this took me two days. Mainly because I had never started a theme from scratch and also because I have only little CSS knowledge.

But here we are, all fresh and up to date. Let 2019 begin!

TicketTouch is a horrible application

[Update: TicketTouch does not exist anymore]

In the Summer of 2016 De Lijn announced a new way of paying for your ride on their busses and trams in Flanders, Belgium. They proposed TicketTouch as an easier and cheaper way of buying tickets. The application leaves a lot to be desired however. Here are some of my complaints.

Why isn’t the application native iOS?

This is the first and foremost question. As soon as you launch the app, it feels cheap and "off". TicketTouch is a very simple application with hardly any UI or graphical elements. The application would be easy to create as a native iOS application and feel much more responsive and at home on people’s phones. I think most of the problems would also be solved by making it native iOS.

Allow for passwords to be pasted.

This is a user-hostile “feature”. There is no security gained whatsoever from having password fields that don’t accept pasting passwords. I thought this was established for quite a while now. What it leads to is to users using simple passwords that they can remember by heart because they have to type them in. Users of password-generating applications such as 1Password who care about their security are baffled by this kind of thing. The password here is maybe especially important as it is the PayPal password that is being used. PayPal, obviously, is used for financial transactions.

PayPal only? Why not add other payment methods?

Why force users to create a PayPal account to which they will then link their credit card? What is the business model here? Was some deal made with PayPal to have them as exclusive payment partner? I can't believe De Lijn accepts this as their interface with the customer. It makes users jump through extra hoops. De Lijn should offer more payment methods. Let people choose whether to pay with credit card or PayPal.

The support section of the app can’t be exited.

This is a glaring bug. When a user enters the Settings section of the app and selects Help/FAQ he is lead to a web view of https://www.tickettouch.be/faq. This would be fine if it weren’t so that you can’t get back to the using the app from there. The only way to go back is to quit the app and open it again. There are other inconsistencies. When choosing Introduction in Settings a Start button has to be tapped in order to go back. Tapping T&C or Travelling T&C has a user tap an ‘X’ to go back. None of these send you back to the Settings section but rather to the main screen of the app.

Buying a ticket cannot fail.

The best gets saved for last. I’ve had a case where I chose “Purchase 60 minutes M-Ticket” and I didn’t get a ticket. It showed the off-center “Purchasing” for a while and then showed the main screen again with no ticket purchased. I tried again by tapping “Purchase 60 minutes M-Ticket” and then it worked. A minute later I get two PayPal emails charging me for 1 ticket each. This is a major usability problem. We are talking about customers being charged for tickets they are not receiving. You can see the screenshots I took and compare the time of the tickets. 2 mails from PayPal, 1 valid ticket.

TicketTouch UI Paypal mail

TicketTouch needs a lesson in how they should make a user-friendly application. When a customer made the intention to purchase a ticket he _has_ a valid ticket. Instantly. He tapped “Buy”, he cannot in any way be faulted for any software bugs that happen after that. What happens now is that the user does not have a ticket until the long processing of the purchase has completed. In urban areas with spotty reception or on moving trams and busses this can prove difficult. But this should not be the user’s problem. What should happen is that the user has a valid ticket as soon as he hits “Buy”. There are 2 ways to do this:

  • Either TicketTouch figures out a way to make payments go faster. I don’t know what they’re doing now but in areas with perfect reception making a payment takes 20 seconds. There is a whole lot of computing that can be done and traffic that can be sent over the network in 20 seconds.
  • Or TicketTouch delivers a valid ticket and then has the backend figure out the payment if it takes too long to give the user instant feedback. If the payment comes back OK then nothing needs to be done. If an error occurs during the payment the user should be notified and the valid ticket will be invalidated.

When a timeout occurs in the TicketTouch backend or when communicating with the customer’s phone this can't be an error that invalidates the ticket. That is not the customer’s problem. In case of a timeout, keep trying. If in the end TicketTouch can't get the payment to complete due to timeouts or bugs, that's a free ticket for the customer. It will save TicketTouch and De Lijn a lot more effort missing out on these tickets than it costs in support and time dealing with false payments that go through. Hopefully the customers of De Lijn will get a better mobile experience soon. They deserve it. An app like this is simple enough and the complexity is very low. It should be top notch if De Lijn wants to keep its customers happy, and paying.

How To Export Fields & Display Suite View Modes

One thing that's often forgotten when I see tutorials about exporting view modes the variable that ties it all together, the field bundle settings for a content type.

This has cost me hours to figure out, after which I forgot it and it cost me hours again, frustratingly trying to figure out why, with seemingly everything exported well, the content types would just not have the view modes that I configured in Drupal's UI.

I don't like to work with Features. Features are fine until they're not. Features generate conflicts and remain in an overridden state after a while. I don't like it. Features are a black box, but the black box does not "just work". Raise your hand if you've heard this before when working on a Drupal project in a team:

"Hey, I reverted the features but it remains overridden."
-- "Ahh yes, I don't know why. It's fine though."

So often everybody assumes it's fine but basically nobody has a clue anymore about what's going on with that feature in a website.

That's why with the last project I did I said, no features. We do everything in code. Which, admittedly, is a bit crazy too. You burn more time, and thus money, on the project putting all the field bases, field instances, Display Suite field info and Display Suite view layouts into code.

Panels and views on the other hand are easier when working in code. Adjust anything in a panel or view, export it. Copy and paste the whole thing into the panel or view's code file and you're good to go. Way faster than working with features.

Exporting fields

To export fields you can use Features, install the module and create a feature containing your content types' field bases and field instances. Of course you need to create your content type first which goes like this:

$my_content_type = array(
  'type' => 'my_content_type',
  'name' => $t('My content type'),
  'base' => 'node_content',
  'title_label' => $t('Title'),
  'description' => $t('My content type for my website.'),
  'custom' => TRUE,
);

$content_type = node_type_set_defaults($my_content_type);
node_add_body_field($content_type, $t('Body'));
node_type_save($content_type);

Exporting field bases

You take the field_base.inc file and copy paste each field base piece of code into a field_create_field() method in your own module's install file. I created a MY_MODULE.field_info.inc file because field bases are shared across content types. You can re-use them.

Exporting field instances

For the field instances I created a MY_MODULE.MY_CONTENT_TYPE.inc for each content type and, at first, copy/pasted each field instance bit of code into a field_create_instance() method in content type's file. Field instances are not shared and it's nice to keep them separate. Beware that when you modify the body field in a content type you don't field_create_instance but field_update_instance for that.

Because you don't do everything right the first time around and you'll be adding or shuffling fields throughout the development of the project I got tired of copy/pasting each section, seeing which field I've already done, afraid of having missed one. The output of MY_FEATURE.field_instance.inc is almost exactly what has to be copy pasted into MY_MODULE.MY_CONTENT_TYPE.inc so I've created a little sed command file that roughly whips *.field_instance.inc into shape.

If you put these lines in a separate file and then call: sed -f command_file MY_FEATURE.field_instance.inc you can almost copy and paste the whole output into your own file.

s/\$field_instances\['.*'\] = /field_create_instance(/
s/\/\/.*//
s/^\([ ]*\));/\1));/
s/^[ ]*return.*//

Exporting Display Suite view modules

To export view modes I use Bulk Export, which comes with Ctools. Just enable the module and you'll get a new item in the Structure menu of your Drupal website. Select which Display Suite view modes you'd like to export and it'll present you with code that you can copy paste into your code.

However, the field bundle settings, a variable that gets saved whenever you "add" a view mode to a content type does not get exported when exporting Display Suite view modes through Bulk Export. Nor does it get exported through Features, not unless you have an extra "Strongarm" module installed at least.

In Kristof De Jaeger (@swentel)'s YouTube video about exporting Display Suite view modes he also makes no mention of this. All he does there after having configured and exported his view modes is truncating the various ds_* tables in Drupal's database, but he forgets about the field_bundle_settings_* It "works" in his demo because he doesn't start from a clean database. But if you'd take the code and deploy it on a new website, that field_bundle_settings_* variable would be missing and the view mode would not be connected to the content type.

You can solve that nasty time-wasting problem by putting this piece of code into your install file for each view mode. In this case it's for the full view mode.

// Update view mode full mode for some content types
$bundles_full_view = array('my_content_type', my_content_type_2);
foreach ($bundles_full_view as $bundle) {
  $settings = variable_get('field_bundle_settings_node__' . $bundle, array());
  $settings['view_modes']['full']['custom_settings'] = TRUE;
  variable_set('field_bundle_settings_node__' . $bundle, $settings);
}

This adds a field_bundle_settings_node_* variable for each content type you want to use the "full view" Display Suite view mode for.

Install a module with _that_ variable defined in it on a clean database and everything _will_ work out of the box.

To recap, when you want to

  • export content types
  • export their fields and the fields' label settings
  • export the view modes used by the content type
  • export the Display Suite field settings

you have to

  • Add the content type through node_type_save()
  • Add each field base with field_create_field()
  • Add each field instance on the content type with field_create_instance(). This also contains the label settings (hidden, above, inline) and in which view mode they appear.
  • Add the field_bundle_settings variable with a variable_set() to tell Drupal which view modes a content type uses.
  • Export Display Suite settings and add the layouts and field info hooks to your code to tell Drupal about the layout in each view mode and the field attributes and extras that got added, if any.