mojoliciousblog
mojoliciousblog
The Mojolicious Blog
50 posts
Don't wanna be here? Send us removal request.
mojoliciousblog · 8 years ago
Text
Let’s make browser testing fun again
Introduction
Tonight at the monthly Oslo.pm meetup, I gave a talk about how to test your web application in a real browser. This blog entry is a collection of the steps I went through while running live demos showcasing my module Test::Mojo::Role::Selenium.
My module uses Selenium::Remote::Driver which is a library that communicates with desktop browsers, such as Google Chrome, Firefox or even Internet Explorer. It comes bundled with test modules, but I wanted an interface that looks and feels like Mojolicious's test module Test::Mojo, since that module really makes testing fun.
Even if the module is a Test::Mojo role, it is not restricted to the Mojolicious web framework. The module can test any web site, as long as you have a web server running.
Why do you want to use this module?
Testing the HTTP messages for headers and body is great, but as soon as you make something other than an API or very simple web page, you should also test the user experience of the web app. Testing the JavaScript for dynamic web pages is the first that comes to mind, but responsive web pages also need testing, to see how elements are laid out on different screen sizes.
Test::Mojo::Role::Selenium allows you to write and run user experience tests in the browser of your selection. The syntax is very simple and it has sane defaults to avoid boilerplate in each test.
Prerequisites
To get started, you need to install the module and some executables that act as a glue between your test script and the browser of your selection.
# Install the test module $ cpanm Test::Mojo::Role::Selenium # Install Google Chrome, Firefox and PhantomJS drivers $ brew install chromedriver $ brew install geckodriver $ brew install phantomjs # Install the Selenium driver (requires jdk8) # brew install selenium-server-standalone
There are probably similar packages for your favorite operating system. The brew commands above are simply a cheat sheet for the presentation.
While preparing this article I wanted to get the demos running with Firefox, but I was not able to get the Selenium::Firefox module to work together with the geckodriver executable. Seems like the integration between firefox and geckodriver are under heavy development. Please let me know if I'm wrong. I did however manage to get Firefox running using the selenium-server. (I had to install Java though...)
You can change between the different backends using the MOJO_SELENIUM_DRIVER. environment variable. Note that Selenium::Chrome and Selenium::Firefox will start and stop the browser together with the test script, while Selenium::Remote::Driver (which uses selenium-server) require an external Selenium service to run.
Testing against a live web server
The first demo was to show that you can use the module to test any web site. The test mojolicious.t connects to mojolicious.org, checks for certain elements and fills in the search form, runs some JavaScript commands and then checks if the search result page was loaded.
Here are the commands I went through to run the demo:
$ mkdir -p test-selenium/t $ cd test-selenium $ vim t/mojolicious.t # copy/paste from t/mojolicious.t below # Test with Google chrome $ TEST_SELENIUM=http://mojolicious.org prove -vl t/mojolicious.t # Test with Firefox $ MOJO_SELENIUM_DRIVER=Selenium::Firefox \ TEST_SELENIUM=http://mojolicious.org \ prove -vl t/mojolicious.t # or... $ MOJO_SELENIUM_DRIVER=Selenium::Remote::Driver \ TEST_SELENIUM=http://mojolicious.org \ prove -vl t/mojolicious.t
The commands above should run the test script in various browser and result in a successful test run. Note that the environment variable TEST_SELENIUM need to be set, or the tests will be skipped. The reason for this is that I think in most cases the Selenium tests should not be run when installing a cpan module, nor being run on services such as Travis CI.
Testing against a local Mojolicious application
The next demo, internal.t, run tests agains a Mojolicious application. Using a Mojo app gives you some more features: In addition to test what is shown inside the browser, you can test headers and other "hidden" information that is exchanged over the HTTP protocol.
$ vim t/internal.t # copy/paste from t/internal.t below # Test with PhantomJS $ TEST_SELENIUM=1 prove -vl t/internal.t
Since the test script does not set MOJO_SELENIUM_DRIVER, it will use the default browser which is the headless browser PhantomJS. This browser is quite fast to start up, but might miss some features that is only available in Chrome, Firefox or Internet Explorer.
The headless version also takes screenshots which are saved to the operating system's temp directory. This can be changed by specifying screenshot_directory.
A more complex real life example
The last demo was to look at some tests for the Convos chat web application. The web app is a Mojolicious server that allows you to be persistently conected to IRC servers and communicate with other IRC users through your web browser. The frontend is powered by Vuejs, which is a reactive JavaScript library that can only be tested through the web browser.
The test suite feature many browser tests, (Look for the tests starting with selenium-) but the two tests that was demoed was selenium-url.t and selenium-register.t.
selenium-url.t
selenium-url.t simply tests the URL library url.js which is a URL parser and generator.
It does that by calling $t->driver->execute_script(...) which is a Selenium::Remote::Driver method for running JavaScript code inside the browser. The result from the method is then tested with normal Test::More functions.
selenium-register.t
selenium-register.t is a bit more complicated test that uses more features from Test::Mojo::Role::Selenium.
It uses wait_for to wait for elements that are injected dynamically to the document. wait_for() is a simple version of the more complex wait_until method that runs a function until the function returns a true value or a timeout runs out.
The end
I hope this introduction gave you an idea of what Test::Mojo::Role::Selenium can do, and makes testing fun again.
Resources
Links
Test::Mojo::Role::Selenium: API documentation.
Selenium::Remote::Driver: Holds information about what you can do with the driver.
Selenium::Remote::WebElement: Holds information about what you can do with an element.
Selenium::Remote::WDKeys: Check the source code for actual keys you can send to html elements.
t/mojolicious.t
use Mojo::Base -strict; use Test::Mojo::WithRoles "Selenium"; use Test::More; $ENV{MOJO_SELENIUM_DRIVER} ||= 'Selenium::Chrome'; my $t = Test::Mojo::WithRoles->new->setup_or_skip_all; $t->set_window_size([1024, 768]); $t->navigate_ok('/perldoc'); $t->current_url_is("http://mojolicious.org/perldoc"); $t->live_text_is('a[href="#GUIDES"]' => 'GUIDES'); $t->driver->execute_script( qq[document.querySelector("form")] .qq[.removeAttribute("target")]); $t->element_is_displayed("input[name=q]") ->send_keys_ok("input[name=q]", ["render", \"return"]); $t->wait_until(sub { $_->get_current_url =~ qr{q=render} }); $t->live_value_is("input[name=search]", "render"); done_testing;
t/internal.t
use Mojo::Base -strict; use Test::Mojo::WithRoles "Selenium"; use Test::More; use Mojolicious::Lite; get "/home" => "index"; my $t = Test::Mojo::WithRoles->new->setup_or_skip_all; $t->navigate_ok("/home") ->status_is(200) ->capture_screenshot ->header_is("Server" => "Mojolicious (Perl)") ->text_is("p" => "Hello!") ->live_text_is("p" => "Hello!") ->element_is_displayed("input") ->active_element_is("input[name=test]") ->send_keys_ok("input[name=test]", ["Yikes", \"enter"]); $t->current_url_like(qr{/home\?test=Yikes}) ->status_is(200) ->capture_screenshot ->live_element_exists("input[name=test][value=Yikes]"); done_testing; __DATA__ @@ index.html.ep <!DOCTYPE html> Test <p>Hello!</p> %= form_for "index", begin %= text_field 'test', autofocus => 1 %= submit_button % end
1 note · View note
mojoliciousblog · 8 years ago
Text
Posted by Mojolicious Core Team member Joel Berger
Configuring NGINX for SSL with Let’s Encrypt
Mojolicious apps can use Mojo::ACME to help issue a certificate for a single appplication. It registers routes which handle the challenges and adds commands which requests new certificates. That said, once you have more than on application and/or multiple sites in the same nginx virtual host, having that capability as a per-application plugin becomes a hinderance not a help.
In this article I will show how you can use a dummy Mojolicious app to issue certs for all of your virtual hosts.
The Dummy Application
At least until I modify Mojo::ACME to provide a built-in dummy application server, you still need a very simple application which only loads the plugin.
# mojo-acme.pl use Mojolicious::Lite; plugin 'ACME'; app->start;
This application only needs to be running when issuing certificates. Start it on an unpriviledged port (say 8000) by running $ perl mojo-acme.pl -l 'http://*:8000'.
Then add a virtual-host for it in your nginx configuration. Since the other applications it needs to load early, so lets call it 01-mojo-acme.
# /etc/nginx/sites-available/01-mojo-acme upstream mojo-acme { server 127.0.0.1:8000; }
Application Virtual-Host Files
Now for your other applications, start with a skeleton like the following:
# /etc/nginx/sites-available/myapp upstream myapp { server 127.0.0.1:8080; } server { listen 80; server_name myapp.myhost.com; include /etc/nginx/common/http-redirects; } server { listen 443 ssl; server_name myapp.myhost.com; location / { proxy_pass http://myapp; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 3600s; } include /etc/nginx/common/ssl-settings; }
Each application should be named differently (this one is called myapp) and should use its own server_name (where this one is myapp.myhost.com. The bulk of this configuration is the standard Mojolicious NGINX configuration. There are a few major differences. The first is that it defines handlers both for port 80 (http) and port 443 (https). Each section includes a file from /etc/nginx/common/ which is a folder you’ll need to create.
In the port 80 section it includes a file which contains the following:
# /etc/nginx/common/http-redirects location /.well-known/ { proxy_pass http://mojo-acme; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location / { return 301 https://$server_name$request_uri; }
This file does two things. It siphons http traffic bound for certificate challenges and it directs it to the dummy app we defined earlier. Then it takes all other http traffic and responds to requests with a redirect to https. This protects users from forgetting to type https:// before your site name, their browser will take them to the SSL protected service automatically.
The port 443 section of the virtual-host file also includes a second file which should contain something like the following:
# /etc/nginx/common/ssl-settings ssl_certificate /path/to/cert.crt; ssl_certificate_key /path/to/cert.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_dhparam /path/to/dhparams.pem; ssl_session_cache shared:SSL:10m; ssl_prefer_server_ciphers on;
This file tells the application where to find your certificate and key files as well as a file defining a set of Diffie-Hellman parameters. You can generate the latter by running $ openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 which will take a while. The certificate and key are generated by the ACME plugin, which will be explained soon.
The rest of the parameters configure the site to use recommended modern security practices. As of the writing of this post, that configuration earns an A rating from for the author’s own sites.
Finally, there is no requirement that the target of the virtual-host application be a Mojolicious application. The author of this article has 5 virtual hosts in his current configuration. 3 are Mojolicious applications, one is a PHP application and one is a simple file-based NGINX service. The other two virtual-host configurations have difference of course, but they still include the two files and are identical in the port 80 configuration and ssl configuration.
Issuing the Certificate
If you haven’t started the dummy app as shown above, do so now. Also be sure that all of your desired vitual hosts are configured as shown above and are enabled in nginx.
NOTE! Before you continue, know that on all of these commands you can pass a -t flag to use a testing server provided by Let’s Encrypt. In this way you can try out the service without affecting your certificate issuance rate-limit. The test servers generate valid certificates but aren’t signed, so they aren’t very useful other than testing.
Now if you don’t already have an account key with Let’s Encrypt you can create one by running $ perl mojo-acme.pl acme account register. This will create a file called account.key. Keep this file safe, you will need it for issuing certificates and all other actions you ever take for these domains.
Finally to issue the certificates, run the command $ perl mojo-acme.pl acme cert generate -a account.key -n mydomain mydomain.com myapp.mydomain.com myotherapp.mydomain.com. The -a flag tells it where to find your account key file (where account.key in the working directory is the default). The -n flag tells it what to name the generated files; which is completely arbitrary. Finally pass all the domains that you want to issue the cert for. Customarily you would pass the toplevel domain first if you are including that one.
Once the certificates are generated, move the certs to the paths you listed in /etc/nginx/common/ssl-settings, or else change those paths to where you want those cerificate files to remain.
Finally, once you reload your nginx configuration (when using upstart this is $ sudo service nginx reload), your sites should all be available using the new certificates!
In 3 months you will need to reissue the certificates, but now you only need to run that same certificate issuance command and the new files will be generated! Indeed the remaining steps are simple enough that they could be a cron job that runs periodically (say every 2 months) to keep your certificates valid indefinitely.
For future reference, the example files are collected in a gist for ease of access at https://gist.github.com/jberger/d04cbfa20d3a269eb1f7868e2b1f432c.
4 notes · View notes
mojoliciousblog · 8 years ago
Text
Manipulating the file system with Mojo::File
The Mojo toolkit has long had various utility functions for file manipulation, but recently in version 7.15 they were collected in a new class, Mojo::File. This class gives a very convenient and easy API for cross-platform file manipulation. It's also used across the entire Mojolicious framework, from Mojo::Home (now a Mojo::File subclass) to Mojo::Asset::File and Mojo::UserAgent::Transactor.
In addition to the object constructor, Mojo::File exports some neat functions for creating new objects; path() is equivalent to new, or you can use tempdir() and tempfile() to get a object representing a temporary file or directory.
use Mojo::File qw(path tempfile); my $passwords = path('/etc/passwd')->slurp; my $tmpfile = tempfile->spurt('This is her file')->move_to('/home/her/file');
Mojo::File is also supported by the ojo module, for quick oneliners. (If you don't know ojo, it's a conveniently named class to allow perl to take the -Mojo flag, and expose a bunch of single letter functions).
$ perl -Mojo -E 'say r j f("geo.json")   ->spurt(g("freegeoip.net/json/mojolicious.org")->body)->slurp'
This might look a bit intimidating at first, but it’s actually quite easy. We fetch a JSON structure using g, and write it to geo.json on the disk, then read it back in, and parse the JSON into perl, then print it using dump from Mojo::Util.
Mojo::File also has some useful methods for iterating over a directory or even a full tree of files. The list() method lets you get all the files, and optionally directories and hidden files in a given directory, and manipulate the results with all the power of Mojo::Collection, while list_tree() does the same recursively.
$ perl -Mojo -E 'say for f("/tmp")->list_tree->map(sub { uc })->each'
Finally, Mojo::File supports some simple overloading. Just interpolate it in a string, and it will do the right thing. Or let's say you want to iterate over each path part of the current directory:
$ perl -Mojo -E 'say $_ for f->@*'
So easy! The module is also optimized for our use, and quite fast.
$ perl -MMojo::File -MPath::Tiny -Mojo -E 'n { Path::Tiny::path("/foo", "bar", "baz") } 1000000; n { Mojo::File::path("/foo", "bar", "baz") } 1000000' 2.27757 wallclock secs ( 2.26 usr +  0.01 sys =  2.27 CPU) @ 440528.63/s (n=1000000) 1.43132 wallclock secs ( 1.42 usr +  0.01 sys =  1.43 CPU) @ 699300.70/s (n=1000000)
Check out the documentation to learn more.
0 notes
mojoliciousblog · 8 years ago
Text
Mojolicious 7.0 released: Perl real-time web framework
Tumblr media
I’m excited to announce the release of Mojolicious 7.0 (Doughnut).
While the community around Mojolicious keeps growing, you might be surprised to hear that the distribution itself has actually been shrinking. This is a very good thing, even with all the features we added over the years, we’ve managed to reduce the code size from 11247 lines in 2010, to 8490 lines today.
Tumblr media
As you can see, it’s not a new trend, we put a lot of emphasis on iterative improvements, and that includes finding more efficient solutions to already solved problems. At the same time the number of tests has grown with every release, and we have now reached a very comfortable test coverage score of 95% with 11245 tests.
Tumblr media
With every release so far, we’ve also seen significant performance improvements. This is once again the case in 7.0, even though it keeps getting harder to find opportunities for optimizations. And especially ones that would show up on the “requests per second” benchmarks we run regularly.
Tumblr media
Additionally, we’ve refactored a few internals, to make sure that our built-in HTTP and WebSocket servers can scale efficiently with large numbers of CPU cores, which have become much more commonly available.
While the main focus this year has been on stability, there are also a few new features, here’s a list of the highlights:
Named variables in all templates: Mojo::Template now supports named variables natively. (example)
HTTP methods: An “_method” query parameter can now be used to override the request method. (example)
SNI: Now also on the server-side. (example)
Windows: Full support for Ubuntu on Windows, including zero downtime software upgrades.
Validation filters: Parameters can now be filtered before validation. (example)
WebSocket subprotocols: We now support WebSocket subprotocol negotiation. (example)
Minion: Our little job queue got much faster and now has support for parallel processing, multiple named queues, retrying failed jobs automatically and job dependencies.
Code of conduct: Diversity matters a lot to us, and therefore we have decided to adopt a code of conduct.
And as usual there is a lot more to discover, see Changes on GitHub for the full list of improvements.
P.S.: We now have stickers.
Tumblr media
Have fun!
8 notes · View notes
mojoliciousblog · 8 years ago
Text
Mojolicious 6.0 released: Perl real-time web framework
Tumblr media
It fills me with great joy to announce the release of Mojolicious 6.0 (Clinking Beer Mugs).
This has been the first major release for the newest member of our core team, please welcome Jan Henning Thorsen. It would appear that 2015 will be remembered as the year of the 6.0 releases, but the year is still young and there’s a lot more for us to look forward to. The IETF has just approved HTTP/2, which may, for better or worse, change completely how we develop web applications, and we can’t wait to see where this will lead us. There will also be a Mojoconf this year, in New York, preparations have already begun and we should be able to share more details very soon.
As real-time web technologies are becoming more and more mainstream, the community has matured, but kept up a steady growth rate. We have been able to reinforce our position as the most starred Perl project on GitHub, and every day there are now hundreds of users browsing through the official documentation. The mailing-list is actually just about to reach 1000 subscribers, thanks everyone!
The main focus this year has been performance, pretty much everything got faster and/or scales better. But there are also quite a few new features, here’s a list of the highlights:
Nested helpers: Organize your helpers into namespaces, like the new built-in helper reply->asset. (example)
SOCKS5 support: Through IO::Socket::Socks. (example)
Non-blocking name resolution support: Through Net::DNS::Native.
New Mojo::DOM: Completely redesigned API and experimental support for case-insensitive attribute selectors like [foo=“bar” i].
RFC 3339 support: Almost every new REST API uses it. (example)
Content negotiation: Now with If-None-Match and If-Modified-Since. (example)
IPv6 everywhere: IO::Socket::IP has become so reliable that we now use it for everything, all the time.
No more “wantarray()”: To prevent security vulnerabilities, it is gone from the entire code base.
Mojo::Pg and Minion: Had stable 1.0 releases and have since become official spin-off projects.
And as usual there is a lot more to discover, see Changes on GitHub for the full list of improvements.
Have fun!
11 notes · View notes
mojoliciousblog · 8 years ago
Text
Mojolicious 5.0 released: Perl real-time web framework
Tumblr media
I’m excited to announce the release of Mojolicious 5.0 (Tiger Face).
It is named after the location of our very first Mojoconf, which has been a huge success and ended just a few days ago. The Oslo Perl Mongers have really done an amazing job putting it all together, and we would love to see this turn into a yearly event, so if you’d like to host the next Mojoconf in 2015, please get in touch!
The community keeps growing fast, and just a few months ago we’ve actually been the very first Perl project on GitHub to be starred more than 1000 times. On IRC we now see about 170 regulars and the mailing-list has grown to over 800 subscribers, thanks everyone!
There are many new features this year, for a quick overview you can take a look at the slides from my Mojoconf talk. Here’s a list of the highlights:
Redesigned: All new exception and not_found pages. (usage example)
Form validation: Simple and extensible. (example)
CSRF protection: You can’t have form validation without it. (example)
Template variants: When responsive web design is not enough. (example)
All new Mojo::DOM: With support for many different node types and new ways to manipulate HTML. (example)
New hooks: The framework got a lot more extensible with hooks like around_action and before_render.
SO_REUSEPORT: A new way to do zero downtime restarts and high performance web servers. (example)
Rotating secrets: More security without having to invalidate existing sessions. (example)
Non-blocking bridges: A new way to reuse non-blocking code. (example)
Cheap helpers: You can now have as many as you like.
Optional placeholders everywhere: Even at the beginning of your route pattern.
RFC 7159: Support for the new JSON spec.
permessage-deflate: WebSocket compression.
Minion: A new spin-off project, because every full-stack framework needs a job queue. (example)
And as usual there is a lot more to discover, see Changes on GitHub for the full list of improvements.
Have fun!
17 notes · View notes
mojoliciousblog · 8 years ago
Text
Mojoconf 2014
Tumblr media
I’m very happy to announce that this year Mojolicious will be getting its very own conference, from the 23rd to 25th of May 2014 the Oslo Perl Mongers will be hosting the very first Mojoconf. And the whole core team will be there to talk about Perl and the Web!
6 notes · View notes
mojoliciousblog · 8 years ago
Text
Convos: Chatting in the cloud with Mojolicious
Tumblr media
If you like IRC and Perl, we’ve got a real treat for you! Our friends at Nordaaker have just open sourced Convos.
Convos is the simplest way to use IRC. It is always online, and accessible to your web browser, both on desktop and mobile. Run it on your home server, or cloud service easily.
Tumblr media
Have fun!
1 note · View note
mojoliciousblog · 8 years ago
Text
Mojolicious 4.0 released: Perl real-time web framework
Tumblr media
It fills me with great joy to announce our classiest release yet, Mojolicious 4.0 (Top Hat).
This is the first major release for the newest member of our core team, please welcome Dr. Joel Berger, he was responsible for many of the new features. It has only been 11 months since our 3.0 release and the new development process is working out very well for us so far. The community keeps growing fast, we’ve now been starred almost 900 times on GitHub and the IRC channel regularly reaches more than 150 visitors, thanks everyone!
While the main focus of this release has been on the removal of legacy APIs, there are also quite a few new features, here are the highlights:
Content generators: “json” and “form” generators are built right in. (example)
JSON WebSocket messages: Native serialization and deserialization support. (example)
JSON WebSocket tests: Just as easy to use as their HTTP equivalents. (example)
Event synchronization: Avoid callback spaghetti with delays. (example)
Scalability: The event loop got a lot better at managing more than 10k concurrent connections. (example)
Smooth restarting: The Morbo development web server does not have any noticeable downtime while restarting anymore.
Hooks: The framework got more extensible with new hooks. (example)
GZip: Compression is now transparently supported by the user agent.
HTML5 forms: Tag helpers have been added for many of the new form elements. (example)
Session expiration: Can now be controlled with a relative value that persists within the session. (example)
GET/POST parameters: Retrieve multiple values at once with the much more secure multi name form. (example)
JSON Pointers: Now fully RFC 6901 compliant. (example)
Monotonic clock support: All built-in web servers are now very resilient to time jumps.
And as usual there is a lot more to discover, see Changes on GitHub for the full list of improvements.
Have fun!
15 notes · View notes
mojoliciousblog · 8 years ago
Text
Mangolicious
Tumblr media
I’m very happy to announce the first alpha release of Mango, a new pure-Perl non-blocking I/O MongoDB driver, and the latest Mojolicious spin-off project.
If you’ve ever worked with the official MongoDB driver for Perl, you’re probably well aware of its many shortcomings, so i’m not gonna ramble on about it… it’s basically the only driver i could find that still defaults to unsafe writes.
While MongoDB itself can be a bit quirky as well, it is also a hell of a lot of fun to work with, especially for rapid prototyping HTML5 web applications. Now that real-time web technologies such as WebSockets are becoming more and more popular, there is a growing demand for versatile non-blocking datastores that work well with event loops. So Mango has been designed from the ground up with the same hybrid architecture as the popular Mojo::UserAgent, and both share the same general characteristics.
Some of the most important features are:
Clean blocking and non-blocking hybrid API.
All operations are safe by default, you have to work to lose data.
Fast and simple installation, no C compiler needed.
Optimized for use with Mojolicious.
And of course here’s the obligatory example application. ;)
https://gist.github.com/kraih/4756855
So, what are you waiting for? Get yourself a free account over at MongoHQ or MongoLab and start writing awesome web applications.
Have fun!
3 notes · View notes
mojoliciousblog · 8 years ago
Text
Mojolicious 3.0 released: Perl real-time web framework
Tumblr media
It fills me with great joy to announce the release of Mojolicious 3.0 (Rainbow).
This marks the first major release for our newly formed core team, consisting of Glen Hinkle, Marcus Ramberg, Abhijit Menon-Sen and yours truly. A lot has happened during the last 8 months since our 2.0 release, most design decisions are now made by majority vote. The core feature set is not changing much anymore, and we are in the process of refocusing our efforts on making Mojolicious more approachable for beginners and easier to extend. The community is still growing fast, and we’ve just passed 666 watchers on GitHub, thanks everyone! :)
There are many new features, here are the highlights:
TLS and IPv6: Support for both has been greatly improved.
Commands: The command system has been completely revamped. (example)
Plugins: Generator and CPAN upload commands make extending Mojolicious easier than ever. (example)
Event loops: Mojolicious no longer needs to control the event loop. (example)
Content negotiation: Write more RESTful web services. (example)
JSON Pointers: Many features dealing with JSON got a lot smarter. (example)
Flexible router: Routes can now be rearranged. (example)
Flexible renderer: Serve templates and static files from as many DATA sections and paths as you like. (example)
Asset plugins: Easily bundle assets such templates and static files with plugins. (example)
Not found page: Is now actually a development tool.
Hypnotoad: Doesn’t require a separate configuration file anymore. (example)
WebSockets: Fully RFC 6455 compliant. (example)
Relaxed placeholders: Now look like “/#foo” instead of “/(.foo)”. (example)
I18N plugin: Maintained as a separate distribution from now on.
And as usual there is a lot more to discover, see Changes on GitHub for the full list of improvements.
Have fun!
4 notes · View notes
mojoliciousblog · 8 years ago
Text
A new look for Mojolicious
You may remember last year when we introduced all-new not found and server error pages for Mojolicious. Well, it’s that time of the year again, and we’ve recently been modernizing some of them. While both raptor pages still pass with flying colors, the more artsy development mode not found page only got mixed reviews. So it has been redesigned from scratch, and turned into more of a development tool, listing all the routes of your application.
Tumblr media
The server error page only needed a few small refinements for both to have a similar look and feel, hope you like it.
Tumblr media
Have fun!
1 note · View note
mojoliciousblog · 8 years ago
Text
Mojolicious in the cloud: Hello Heroku!
A lot has changed in the world of cloud hosting since the last time i took a closer look at one of the providers. Almost all of them support Perl these days, directly or indirectly. One of the most prominent ones is Heroku, and today we are going to use their official tools and a custom buildpack to deploy a Mojolicious::Lite application into the cloud.
First of all you need to sign up for a free account and install the Heroku Toolbelt, the heroku command line client will be available afterwards and take care of the rest.
https://gist.github.com/kraih/2899489
Only three files are required to make an application deployable to Heroku, the application script itself, a “Makefile.PL” containing a list of CPAN dependencies, and an executable “Perloku” script telling Heroku how to start the Mojolicious web server.
https://gist.github.com/kraih/2899522
For our little experiment we will only be using a very minimalistic application.
https://gist.github.com/kraih/2899530
And the only dependency is Mojolicious, but any CPAN module you specify can be installed automatically.
https://gist.github.com/kraih/2899541
My favorite Heroku feature is that we are allowed to run our own web server, which enables many of those nifty real-time web features to just work. The port to be used for listening will simply be passed along via environment variable.
https://gist.github.com/kraih/2899544
And those were all the preparations required, now we can just deploy our application withgit.
https://gist.github.com/kraih/2899556
I’ve also heard rumors that Glen “tempire” Hinkle might be working on new Mojolicious commands to make the whole process even easier, but you’ll have to visit (or watch the live stream of) his talk at YAPC::NA 2012 to learn more about that. ;)
Tumblr media
Have fun!
2 notes · View notes
mojoliciousblog · 8 years ago
Video
vimeo
1 note · View note
mojoliciousblog · 8 years ago
Text
Mojolicious hack of the day: Mojolyst
Today i’ve got a real hack for you. We are going to hijack the Mojolicious router and turn it into a more Catalyst-ish decentralized one, just by using a plugin. Controllers are discovered on application startup and their routes composed automatically, even templates in the DATA sections of each controller are supported. :)
https://gist.github.com/kraih/2149176
Have fun! 
1 note · View note
mojoliciousblog · 8 years ago
Text
Mojolicious hack of the day: More AnyEvent, oh my
Ever since we added AnyEvent support to Mojolicious through EV, it has been a very popular feature. But so far it required Mojolicious to be in control of the event loop, which limited its usefulness quite a bit. That has changed now, both our web server and user agent have become pretty much indistiguishable from normal AnyEvent components. Today i’m going to demonstrate how you can non-blockingly search Twitter for Perl with the user agent, from a PSGI application running inside the AnyEvent based Twiggy web server. In fact, it should work with any non-blocking capable web framework, such as Catalyst.
https://gist.github.com/kraih/1868865
Have fun!
1 note · View note
mojoliciousblog · 8 years ago
Text
Mojolicious and DBIx::Class
If you’ve ever been wondering how a well designed DBIx::Class model for Mojolicious and Mojolicious::Lite applications would look like, Glen Hinkle got you covered with his latest release.
The example application demonstrates DBIx::Class integration, how to test your web app with Test::Mojo, as well as how to use EP templates with and without tag helpers. For those unfamiliar with testing in general, there are even examples of DBIC schema tests.
Have fun!
1 note · View note