Webflow API bindings

In the beginning of this year, I’ve started into a new direction, exploring unknown territory. Exciting times are lying ahead and I already learned a lot in the past month:

In march I joined forces with some amazing people and we founded a company called “Penseo”:https://www.penseo.de.

Working in such an early phase of a startup gives me a lot of freedom. There is room for experiments and I can decide myself what I like and want to try out! For sure, there are a lot of things, that need to be done. Luckily, I can try to find the best tool for the job.

One thing that I was investigating right in the beginning were Rails based CMS solutions. To make it short, none of them are amazing…

This is why we went with “Webflow”:https://www.webflow.com (special thx to Paul for the recommendation)!

It’s composed of 3 main elements:

* The Webflow-Designer, which is kind of a Photoshop for the Web, embracing Web-technologies at it’s core.
* The Webflow-Editor, a WYSIWYG, inline on site, content manager.
* The Webflow-CMS itself, where one can define collections and relationships similar to a RDBMS.

On top of that you get a “proper RESTful API”:https://developers.webflow.com/ which is actually really useful!

Since there were no Ruby API bindings, I “created a thin wrapper”:https://github.com/penseo/webflow-ruby in order to make my life a little easier.

I hope that someone else might find it useful too. I’d also love to get your feedback, or even better, pull-requests!

Burn-Notice, this message will self-destruct!

I recently put a pet-project of mine “called Burn-Notice”:https://www.burn-notice.me/ into public βeta.

bq. Burn-Notice: Simple, Secure, Encrypted one-time Information

It’s like messages for “Inspector Gadget”:http://en.wikipedia.org/wiki/Inspector_Gadget, everything will self-destruct! So if you happen to send sensitive information over the web, you can use this tool to exchange passwords, credit-card numbers, key-codes, voucher-codes etc… After the recipient got the message, the information get’s deleted right away.

All information is stored encrypted on the server and can only be decrypted with knowledge of a passphrase that is entered by the sender. The recipient of a message can only decrypt the message with knowledge of the passphrase – _the shared secret_!

I would love to get feedback from you, please check out “burn-notice.me”:https://www.burn-notice.me/

using domainFACTORY with heroku and SSL

I’m working on a small side project that requires proper SSL configuration. Since I like using “heroku”:http://nofail.de/category/heroku/ to bootstrap my projects, I thought it would also be a great idea to do that in this case… As it turns out, it was quite a hassle to get it up and running the way I want it to be.

When you create a new app on “the cedar stack”:http://nofail.de/tag/cedar/ you get “SSL for fee”:https://devcenter.heroku.com/articles/ssl-endpoint#piggyback_ssl_myappherokucom_and_myappherokuappcom_only. The only downside here is that this is only true for the your-app.herokuapp.com subdomain that hosts your application. If you want to add SSL to “your custom domain”:http://nofail.de/2010/01/using-heroku/ it get’s a bit hairy.

h2. Custom Domain SSL

Once you have added your domain to heroku and delegated the the “name-server lookup via CNAME”:http://www.df.eu/de/feature-info/serverpower-h/domainverwaltung/, you need to “provision a SSL addon”:https://devcenter.heroku.com/articles/ssl-endpoint#provision-the-add-on that costs $20 per month. This is just for the addon, no batteries included! So you also need to buy a SSL-certificate from the authority of your choice.

This setup is unfortunately not working with my “hosting provider domainFACTORY”:http://www.df.eu/ as they allow _only_ subdomains to be aliased via CNAME, the root-domain is not configurable. So you can forward www.yourdomain.de but not yourdomain.de.

h2. CloudFlare to the rescue

The “CDN provider CloudFlare”:https://www.cloudflare.com/ has free SSL support when using the “Pro Plan”:https://www.cloudflare.com/plans that also costs $20. This is a bargain compared to the heroku SSL-plugin as CloudFlare has way more use-cases than just SSL.

Configuring the DNS on domainFACTORY is quite simple. Just go to _Für Profis > Nameserver-Einstellungen_ in your admin setup and remove all the DNS entries. Add the CloudFlare name-server settings to the bottom:

53b2316ec38aa55143368943

DNS + SSL made simple!

structuring your RSpec project

it is an established convention to put all your rails tests or spec in the test/spec folder. “even jasmine javascript files”:https://github.com/pivotal/jasmine-gem/pull/172 go in spec/javascripts… seriously, wtf?

“cucumber features”:https://github.com/cucumber/cucumber-rails on the other hand go in the features folder… so?

while i don’t like cucumber (because of the additional complexity that comes with “gherkin”:https://github.com/cucumber/cucumber/wiki/Gherkin), i like the idea that they think about features as something different.

when writing acceptance tests i put them in the acceptance folder and have a different spec_helper file (usually called acceptance_spec_helper.rb as RSpec runners get confused with multiple spec_helper-files).

acceptance tests and normal rails tests have orthogonal requirements that should be handled in using different setups!

i like to have “use_transactional_fixtures”:https://relishapp.com/rspec/rspec-rails/docs/transactions and random test execution turned on for regular Rails tests because it’s super fast and each spec should be independent of other tests.

it’s a different thing when writing acceptance specifications with capybara and a real browser that cover a user-session on a separate rails process and runs arbitrary actions against the server, executing JavaScript code within that context.

those acceptance tests have a basic problem when it comes to database queries. changes in one process/thread might not be seen in another one because of transactional visibility. this is often times hard to debug and mind-boggling. there are some “hacks” to get rid of this problem by “sharing the same database connection”:https://github.com/jnicklas/capybara#transactions-and-database-setup, but they introduce other problems like race conditions.

long story short, i like to turn use_transactional_fixtures of and use fixtures (or hard-coded factory data) for running acceptance tests, as this fits more into the idea of acceptance tests. if you combine this approach with “state-full page-objects”:http://robots.thoughtbot.com/better-acceptance-tests-with-page-objects, than you can write pretty readable tests like LoginPage.new.login(:bob).

I like to run “DatabaseCleaner”:https://github.com/bmabey/database_cleaner between each group of specs and recreate the fixtures, so they are fresh for each capybara spec file.
This setup comes pretty close to how cucumber does it, without all the cucumber-world craziness.

Some benefits that come with this approach:

* faster spec runs for both suites
* easy to separate out suites for CI
* great for coverage reports
* simple spec_helpers
* separation of concerns via custom test modules

See the “example configurations”:https://gist.github.com/phoet/6683280 for more details.

monkey-patching Rails

I’ve been working a bit on a rails plugin for debugging html templates that we use at “Shopify”:http://www.shopify.com/ called “partially_useful”:https://github.com/phoet/partially_useful.

It’s a very simple helper that adds HTML-comments to the rendered source, so that you can inspect it easily in your browser’s developer toolbar. The comment hints look like this:

<-- start rendering 'some_partial' with locals '[:all, :assigned, :locals]'-->
[...]
<-- end rendering 'some_partial' with locals '[:all, :assigned, :locals]'-->

There are way more sophisticated plugins out there like “xray-rails”:https://github.com/brentd/xray-rails, but I prefer to have very simple tools that can be used without installing plugins or the like.

I used the plugin in various projects and ported it from “Rails 3”:https://gist.github.com/phoet/905286 to “Rails 4”:https://gist.github.com/phoet/1386152, but it has never been more than a GIST on GitHub. Taking the time to actually convert it into a “Railtie”:https://blog.engineyard.com/2010/extending-rails-3-with-railties/ did not take long and allows everyone to use this plugin in their Rails projects.

All it does is intercepting the ActionView::PartialRenderer#render method, taking the return value of the call and “wrapping it in HTML comments”:https://github.com/phoet/partially_useful/blob/c482c58ab87400f1b6cadaaed7f0c57003803a1c/lib/partially_useful/partial_renderer.rb#L8-L15.

The tricky bit is how to inject this functionality into the original Rails code…

h2. shoot yourself in the foot way

Just open up the ActionView::PartialRenderer class and overwrite the method!

While this might seem like the obvious way to do it, it makes everyones life worse, because it makes it much harder to find out where the f**** this new behavior is coming from…

h2. Module#prepend

The nicest solution is to use Module#prepend. It allows you to inject a Ruby module in the first position of the inheritance chain. By doing this, your new render-method will get called and you can just pass everything along to super aka the original method.

The big downsides here are that this is not compatible with Ruby 1.9 and JRuby.

h2. Module#alias_method_chain

This is a feature that “Rails adds to Module”:https://github.com/rails/rails/blob/fa03e37d31d7c69c90d41f0764c374318d8dced0/activesupport/lib/active_support/core_ext/module/aliasing.rb#L23-L43 and that allows you put another method in the call-chain by aliasing methods. I’m not a huge fan of it as I find the API rather confusing and it just works with Rails.

h2. bare metal

If you include a Module that has a method with the same name as the method in the target class, the method of the Module will not get called when you invoke it on the class. This is because the methods of the class take precedence in the method-dispatch over those of ancestors in the inheritance chain (hence the Module#prepend). Because of that, you have to make way for the new method so that it can be invoked properly when you include a Module to override a method.

A way to do that is to use the Module#included callback to alter the class and alias the old method and remove the original afterwards

  def self.included(klass)
    klass.send :alias_method, :original_rails_render, :render
    klass.send :remove_method, :render
  end

h2. conclusion

Meta-programming is hard, especially if you want to support multiple Ruby runtimes…