So, I've been playing a little with Mojolicious::Lite, and here's what I came up with :-)
Tweetylicious is a small - but rather complete - microblogging web application in a single file! It is meant to demonstrate how easy and fun it is to create your own Web applications using modern Perl 5 and jQuery!
Some features:
- Multi-user, with homepages, search and list of followers/following
- Nice, clean, pretty interface (at least I think so :P)
- User avatar images provided by gravatar
- Unicode support
- Well structured, commented code, easy to expand and customize
- Encrypted online sessions
- Uses an actual database (SQLite) and stores encrypted user password
If you want it, the full code is in github. Removing just blank lines and comments, the Model has ~80 lines, the Controller ~110 lines, templates ~170 lines, plus ~90 lines of static css and ~60 of static javascript. And that's the whole app :D
How do you run it?
perl tweetylicious.pl daemon
You'll need Mojolicious and ORLite - two very lightweight modules - to run the app, and that's about it! A live Internet connection is also good, since it fetches jQuery on the fly.
Mind you, it's far from perfect (bug reports and patches always welcome!). I wrote it as a demo to show the kind of stuff you can quickly achieve with Perl. It's totally usable and might be a good fit for quick deployment and customization on internal networks, but if you're looking for a business ready microblogging solution, you might want to look at status.net (which powers identi.ca). But it's waaaay bigger ;-P
Tutorial...ish
I tried making the commits linear and modular, so newcomers can take a look at git log for a "tutorial":
- initial commit - diff, full file
- adding index page (and route) - diff, full file
- separating common html into a shareable 'layout' - diff, full file
- adding (all) css - sorry, this is not a css tutorial :P - diff, full file
- users will need to 'login' and 'join' (register)! - diff, full file
- first jQuery contact: turning links into buttons - diff, full file
- creating the 'User' model schema in our database - diff, full file
- registering users: the template - diff, full file
- registering users: the controller - diff, full file
- registering users: validating registration data - diff, full file
- registering users: prevent usernames that are part of a route - diff, full file
- user login: the template (and basic route) - diff, full file
- user login: the controller (handling form submission) - diff, full file
- user logout: controller, and option in template - diff, full file
- the user's homepage (template) - diff, full file
- the user's homepage (controller) - diff, full file
- adding a 'not found' page - diff, full file
- making 'login' and 'join' redirect to user's homepage - diff, full file
- updating our model: posts! - diff, full file
- making user's homepage show posts (but user can't create them just yet - diff, full file
- updating our controller: creating posts - diff, full file
- updating our controller: deleting posts - diff, full file
- updating our controller: turning common posting auth code into a ladder - diff, full file
- more jQuery: styling post submit into a button too - diff, full file
- more jQuery: showing how many characters are left in a post - diff, full file
- more jQuery: highlighting posts on hover - diff, full file
- more jQuery: formatting our content for RTs (@user) - diff, full file
- creating posts via Ajax (rather, Ajaj, since we're using JSON ;) - diff, full file
- deleting posts via Ajax (rather, Ajaj, since we're using JSON ;) - diff, full file
- searching posts: search form template - diff, full file
- searching posts: jQuery effects - diff, full file
- searching posts: model - diff, full file
- searching posts: controller - diff, full file
- searching posts: results template - diff, full file
- searching posts: jQuery (naive) formatting for topics (#topic) - diff, full file
- followers and following: the model - diff, full file
- followers and following: the controller - diff, full file
- followers and following: template changes - diff, full file
Newer commits will likely be not as organized, and mostly bugfixing, but this should get people going - hopefully :P
Well, that's it. Have fun!
if you hurry, you can see it in action here.
ReplyDeleteThanks vti for hosting a demo! You can find me there too =)
Well, it's a single file application only in the sense that you don't count all of the other files it requires as dependencies. That is, it's not a stand-alone application as you imply.
ReplyDelete@brian: If by "all of the other files it requires as dependencies" you mean Mojolicious, ORLite and jQuery, I did mention them. Sure enough, they also depend on other modules (and files), but fortunately they're all core, and bundled with perl. If you want to be thorough, perl itself is a dependency too, and you won't be able to take much advantage of it without a web browser client either.
ReplyDeleteIt *is* a single file application in the sense that the app itself is in tweetylicious.pl and nowhere else, so hopefully a beginner will be able to look at the app and not only understand what does what, but easily tweak things as he/she feels necessary - I did mention it is a demo, didn't I? - It's also pretty small without actually making any effort in so, which again is to show how much a beginner can achieve with Perl even using minimalistic frameworks such as Mojolicious::Lite and ORLite.
I'm sorry if it wasn't clear enough. Not only I'm not dismissing dependencies, I couldn't have done it like so without them. My point was the little dependencies Tweetylicious has are very lightweight and, as such, it should be very easy to install, run and fiddle with.
Eh, ignore the trolls, it's a single file :-)
ReplyDeleteI thought that your use of source control is a *really* cool way to do a tutorial. That would be an AWESOME way to show people how to develop really any kind of application or module. I hope to do something similar at some point. Thanks for the inspiration!
@fREW: Thanks! Actually, I got that idea from the Cat Book, which presents code change in a diff-like format and lets you download the resulting repository.
ReplyDeleteUsing git for that *really* helped, btw. Just do your regular development and then have fun with git rebase. You can do pretty much anything with your commits as long as you don't push them upstream, including merging, editing, deleting (I know you're a fan and know all this already, I'm just letting other people into the secret too ;P)
Excellent post, $full_examples_as_tutorials++, the git diffs are nice.
ReplyDeleteMaybe it just need another file (tests) and some POD in the code but it's nice this way too :-)
I've learned last years CGI, Catalyst and Dancer, this post (and the websocket support seen in other examples) is encouraging me, to learn mojolicious too.
Greetings
@poisonbit: thanks!
ReplyDeleteRegarding tests and Pod and whatnot, I did it this way just to cause a bigger impact on the occasional viewer. They'll open the repository, see only that single file and go "wow, this is for real" - one can hope at least :D
If people are interested, I might put it in CPAN after a couple updates, in which case it will include standard Makefile.PL and all that (which would in turn make it even easier to install using things like miyagawa's cpanm).
As for learning Mojolicious, do it! If you know Dancer, it has about the same structure and syntax, only Mojolicious has much more features - at this point at least :)
Check out the documentation for Mojolicious::Lite. It should have everything you need. You can also reach #mojo in irc.perl.org or the mailing list if you need help!
It is faster than the original Twitter written on Ruby.
ReplyDeleteIt doesn't work :-(
ReplyDeleteTue Jun 22 16:20:06 2010 debug Mojolicious::Plugin::EpRenderer:38 [39639]: Caching template "/usr/home/as/prg/perl/mojo/mojo/tweetylicious/templates/index.html.ep" with stash "callback, content, rendered, started".
Tue Jun 22 16:20:06 2010 debug Mojolicious::Plugin::EpRenderer:38 [39639]: Caching template "/usr/home/as/prg/perl/mojo/mojo/tweetylicious/templates/layouts/main.html.ep" with stash "callback, content, rendered, started".
String found where operator expected at (eval 292) line 15, near "session 'name'"
(Do you need to predeclare session?)
String found where operator expected at (eval 292) line 16, near "session 'name'"
(Do you need to predeclare session?)
Tue Jun 22 16:20:06 2010 error Mojolicious::Plugin::EplRenderer:84 [39639]: Template error in "layouts/main.html.ep": Error around line 15.
13: <div id="header"><a href="/"><div id="logo">Tweetylicious!</div></a>
14: <div class="options">
15: % if (session 'name') {
16: <a href="/<%= session 'name' %>">Home</a><a href="/logout">Sign-Out</a>
17: % } else {
But /static.css and /static.js served OK.
Не работает. Хотя статику (стили и скрипты) успешно выдаёт.
@Shoorick: that's very odd. Can you please make sure you have the latest CPAN version of Mojolicious?
ReplyDeletehttp://search.cpan.org/perldoc?Mojolicious
спасибо!
The username and bio display chinese as alien chars.
ReplyDeletePatch Orlite.pm as below:
my $dbh = DBI->connect( $dsn, undef, undef, {
PrintError => 0,
RaiseError => 1,
sqlite_unicode => 1, #patch enable default deflating utf8
} );
In tweetymojolicious.pl, find the fllowing in two places:
<%= b($post->{content})->decode('UTF-8')->to_string %>
change to:
<%= $post->{content} %>
Then non latin chars display normal in everywhere.
This is a good mojo example.
http://louboutinoutletmall.com
ReplyDeleteTop shop for christian louboutin intern crested velvet loafers Shoes,luxury French Shoes On Sale.The Christian Louboutin Asteroid 160mm Shoes professed goal is to make a woman look sexy, beautiful, to make her legs look as long as they can.As expected,we offers you this year's new collections of christian louboutin alfred flat Shoes,up to 90%% off,free delivery.free gifts.ggvgdfdsfcxcs
could federation be plugged into it?
ReplyDeleteeg ostatus, dfrn or any other suitable protocol?
would love to see something like Friendica or StatusNet for perl!
perl+sqlite might be more suitable for those little raspberry pi servers than php/mysql (which needs too much ram) .. and as a bonus sqlite has a quite good fulltext search capability if you set a couple of flags when compiling it (sqlite FTS 3/4)
Its a wonderful post and very helpful, thanks for all this information. You are including better information regarding this topic in an effective way.Thank you so much.
ReplyDeleteTwitter Clone App Script
Twitter Clone script
Best Twitter Clone script
Twitter Clone
Twitter Script
Best Twitter Script
Complete Twitter Script
Wonderful post..!! Want to know more about other clone scripts. Check it out here..
ReplyDeleteGojek Clone App Script
Dream11 Clone script
Tinder Clone script
instagram Clone Script
Great pieces. Keep posting such kind of info on your site. I'm really impressed by your blog.
ReplyDeleteGojek Clone APP
UberEats clone
ReplyDeleteUberEats clone app
ReplyDeleteUberEats clone script
ReplyDeleteApp like UberEats
ReplyDelete