Hi, I just put together a little mixin to provide pseudo-RESTful services in camping apps. Basically, it looks for a hidden _verb field in form posts, and sets the @method to the supplied value (e.g. put or delete - which browsers don''t support). This lets you define put and delete methods in your controllers. Groovy. Code: http://pastie.caboo.se/22613 Is there any permanent repo of little code snippets/mini-libraries for Camping? Is the wiki the best place? I think a lot of camping code could be re-used via mixins and it would be nice to have a Camping-forge type place to go find existing work. Cheers, -Mark
hey, that''s nice perhaps you could write up a page on the wiki ? http://code.whytheluckystiff.net/camping/wiki/LikeRails On 11/14/06, Mark Fredrickson <mark.m.fredrickson at gmail.com> wrote:> Hi, > > I just put together a little mixin to provide pseudo-RESTful services > in camping apps. Basically, it looks for a hidden _verb field in form > posts, and sets the @method to the supplied value (e.g. put or delete > - which browsers don''t support). This lets you define put and delete > methods in your controllers. Groovy. > > Code: > > http://pastie.caboo.se/22613 > > Is there any permanent repo of little code snippets/mini-libraries for > Camping? Is the wiki the best place? I think a lot of camping code > could be re-used via mixins and it would be nice to have a > Camping-forge type place to go find existing work. > > Cheers, > -Mark > _______________________________________________ > Camping-list mailing list > Camping-list at rubyforge.org > http://rubyforge.org/mailman/listinfo/camping-list >-- Rodney http://www.pinupgeek.com http://www.dutchrailers.org
Hi, Great ! I wanted to implement that for long time and never had it (the time). I''ve packages a set of Camping extensions in a package called "Equipment". Apparently I don''t have many followers but maybe you''re interested to contribute ? I think that my lib is a bit too complex and gets intimidating compared to the LOC of Camping. Let me know if you want to be introduced a little bit :) -- Cheers, zimbatm http://zimbatm.oree.ch
I''d be happy to include this on the wiki. Can some explain how to add a helper function into the including module''s namespace? eg. How do I get module Camping module REST module Helpers def form ... end end end end properly mixed in (so as to provide a form helper to override markaby) using ''include Camping::REST'' Thanks, -M On 11/14/06, Rodney Ramdas <rramdas at gmail.com> wrote:> hey, that''s nice > > perhaps you could write up a page on the wiki ? > > http://code.whytheluckystiff.net/camping/wiki/LikeRails > > > > On 11/14/06, Mark Fredrickson <mark.m.fredrickson at gmail.com> wrote: > > Hi, > > > > I just put together a little mixin to provide pseudo-RESTful services > > in camping apps. Basically, it looks for a hidden _verb field in form > > posts, and sets the @method to the supplied value (e.g. put or delete > > - which browsers don''t support). This lets you define put and delete > > methods in your controllers. Groovy. > > > > Code: > > > > http://pastie.caboo.se/22613 > > > > Is there any permanent repo of little code snippets/mini-libraries for > > Camping? Is the wiki the best place? I think a lot of camping code > > could be re-used via mixins and it would be nice to have a > > Camping-forge type place to go find existing work. > > > > Cheers, > > -Mark > > _______________________________________________ > > Camping-list mailing list > > Camping-list at rubyforge.org > > http://rubyforge.org/mailman/listinfo/camping-list > > > > > -- > Rodney > http://www.pinupgeek.com > http://www.dutchrailers.org > _______________________________________________ > Camping-list mailing list > Camping-list at rubyforge.org > http://rubyforge.org/mailman/listinfo/camping-list >
On Nov 13, 2006, at 10:37 PM, Mark Fredrickson wrote:> I just put together a little mixin to provide pseudo-RESTful services > in camping apps. Basically, it looks for a hidden _verb field in form > posts, and sets the @method to the supplied value (e.g. put or delete > - which browsers don''t support). This lets you define put and delete > methods in your controllers. Groovy.That''s rad. While we''re on the topic, I rolled a Railsish respond_to method for my Camping app: http://pastie.caboo.se/22733 -- Chris Wanstrath http://errtheblog.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/camping-list/attachments/20061114/fc8aaaf3/attachment.html
On 14/11/06, Mark Fredrickson <mark.m.fredrickson at gmail.com> wrote:> I''d be happy to include this on the wiki. Can some explain how to add > a helper function into the including module''s namespace? > > eg. How do I get > > module Camping > module REST > module Helpers > def form ... > end > end > end > end > > properly mixed in (so as to provide a form helper to override markaby) > using ''include Camping::REST''You''ll have to use the included callback. like : module REST def self.included(app) app::Helpers.send :include, Helpers end end -- Cheers, zimbatm http://zimbatm.oree.ch
Hi Jonas, Thanks for this reply, and the other cluing me into the .included callback. I''ll take a look at that later today and see if I can get it to work.> Great ! I wanted to implement that for long time and never had it (the > time). I''ve packages a set of Camping extensions in a package called > "Equipment". Apparently I don''t have many followers but maybe you''re > interested to contribute ? > > I think that my lib is a bit too complex and gets intimidating > compared to the LOC of Camping. Let me know if you want to be > introduced a little bit :)Regarding equipment, you''re right: it is a little intimidating. I opened it up and thought "hey, what are all these "depends" calls? why can''t I just use ''include Foo''?". I am willing to believe these are necessary, but I am worried that it raises the bar for new programmers (e.g. me) who aren''t willing to take the time to make their little code snippets (like the two posted in this thread) into full equipment compatible modules. I''d like a solution where I can define something like: module MyModule module Models ... end module Controllers ... end module Views ... end module Helpers ... end end and have anyone else come along and just drop it into their apps with one line of code (or perhaps two, if something needs to be run in the create method). eg MagicModuleIncluder.make_magic :MyModule, :SomeOtherModule, ... def MyApp.create MyModule.create SomeOtherModule.create ... MyApp creation code ... end My inspiration for this is the Camping::Sessions code. It''s not very complicated itself, and it drops right into any other camping app. I''ve been thinking about starting a little website where people can upload "songs." Little camping components that don''t require a lot of work to create or include in other apps. (The reason behind the word song is that when one goes camping, you''re likely to have a sing-a-long. Apps can join in or not if they want. Cheesy? Yes.) A place where developers can share their code without having to meet a lot of dependency requirements or create a gem, or otherwise put themselves out. Think pastie + tepee. WIth RSS. Lots of RSS. I''ll make a formal announcement when I have something more than vapor, but if anyone is interested in helping, I think there are two things that need to happen: 1. CampSongs (the module/class) that has the necessary vodoo to make the code I posted above possible. 2. CampSon.gs (the website) the camping app that makes the sharing of songs easy and effective. It should probably eat a healthy amount of dog food and use as many songs as possible. Email me off-list if you''re interested, and I''ll keep you posted. And with that, I shall go make code of this vapor, -Mark
> MagicModuleIncluder.make_magic :MyModule, :SomeOtherModule, ... > > def MyApp.create > MyModule.create > SomeOtherModule.create > ... MyApp creation code ... > endI''m not sure I quite understand this... what does MagicModuleIncluder do that simply including modules doesn''t? (As in: http:// code.whytheluckystiff.net/camping/wiki/BeforeAndAfterOverrides) What sort of stuff do you have in mind for these components? But to add some more mixin stuff to the stew, here''s a one you can use to send JSON in the body of a request and have it parsed for you into the @input: http://mdaines.com/svn/messages/trunk/lib/json_input.rb Also an authentication mixin (without proper credit to its original author but this repository is an unreleased project and I''ll put it back in soon) which you can use inside controllers: http://mdaines.com/svn/messages/trunk/lib/authentication.rb You might also have a look at the fake_method one which does the same thing as the code posted earlier in this thread. -- Michael Daines
This is what I though. Equipment seems pretty complicated but it is not really. What''s complicated is the extension mechanism that was created to support many use cases. If you overlook that, the rest is pretty simple. Basically, to create a Camping equipment, you do the following : module YourExtension extend Equipment # installs the hooks depends_on OtherExtension # make sure the other extension is included first # Here you mimic your app''s structure. class methods are defined with a module # called like your constant + ClassMethods. Like ControllersClassMethods. module Controllers # controllers will get copied over to your app class Woot # R is not available end end module Helpers # new helper def hello end end module CClassMethods # class methods for your app def create # the create method is chained super # do something end end end in your app : require ''equipment'' Camping.goes :YourApp module YourApp equip YourExtension end Maybe I should put that more in form an make a tutorial. -- Cheers, zimbatm http://zimbatm.oree.ch
> I''m not sure I quite understand this... what does MagicModuleIncluder > do that simply including modules doesn''t? (As in: http:// > code.whytheluckystiff.net/camping/wiki/BeforeAndAfterOverrides) What > sort of stuff do you have in mind for these components?So, I haven''t entirely got to the bottom of this yet, but let''s at some examples of include not working as I want. (As to what I want: entire MVC stacks that I can drop into different apps - eg. a user login engine that works in any app a /user and provides some useful predicates - is_logged_in?, etc...) So, I''ve created a little app that holds "Things." Nothing more than a title. Super simple. Now that I have my thing engine working, I want to incorporate it into another app. I comment out some stuff that would seem to conflict (eg. the layout view, the Index controller, Camping.goes :SimpleApp). You can see it here: http://pastie.caboo.se/23577 Seems straight forward, yes? Now let''s include it in another app. We take a direct approach and include each part of the MVC stack in the appropriate part of our app. See the "Simpler" app here: http://pastie.caboo.se/23578 Try to run it. No luck: [mark 18:14:11 app]$ camping simple_app.rb !! trouble loading simpleapp: [NameError] uninitialized constant Base /Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/activesupport-1.3.1/lib/active_support/dependencies.rb:123:in `const_missing'' /Users/mark/Documents/Programming/Ruby/campingtest/app/simple_app.rb:13 Hmm. Strange. While I don''t think it''s a good idea, let''s try to uncomment the Camping.goes :SimpleApp line in our included MVC. Try to launch. Success (or so we think). The index page works. It''s all good, right? Let''s try to look at our "things"http://localhost:3301/thing Camping Problem! SimpleApp::Controllers::Thing.GET NoMethodError no such method `list_thing'': ... Uh oh. Something''s borked. I haven''t figured out how to solve this problem, but I''m sure it''s solvable. But you can see the problem. Looking at the camping code itself, it clearly does some unusual stuff to add apps to the mix. Like eval''ing a gsub version of the camping file itself. That kind of stuff is wild, but it makes it hard to anticipate exactly how to hook into the system. As Jonas''s emails on the subject indicate, Equipment has been wrestling with this problem. I''m going to keep hacking on this. Perhaps I''ll have a better solution soon. Also - feel free to point out why I''m an idiot. :-) -Mark
@Mark Fredrickson : This is exactly the problems that Equipment solves. Add "extend Equipment" in the SimpleApp module and "equip SimpleApp" in Simpler. You''ll also have to remove the models and the routes in SimpleApp since I didn''t implement the class methods and Base. If you want to do it on your own you''ll have to solve the following problem : include ModuleA in ModuleB. Then add some methods to ModuleA or include another module into it. Then look in ModuleB.instance_methods. Your new ModuleA methods should not be there. -- Cheers, zimbatm http://zimbatm.oree.ch
Mark Fredrickson wrote: > [...] I want: entire MVC stacks that I can drop into different apps - > eg. a user login engine that works in any app a /user and provides > some useful predicates - is_logged_in?, etc...) I''ve had a look at this and think I''ve found something like a solution. The Controllers and Models don''t seem to be much of an issue, the Views are a little more problematic. Read on for the details. # Views Camping.goes :NewApp module NewApp module Views; include OtherApp::Views; end end Doesn''t work because NewApp::Views is included into NewApp::Mab *before* the inclusion of OtherApp::Views. As a result the OtherApp::Views methods are *not* included in the NewApp::Mab class and so are not available for controllers/other view methods to call. At least I *think* that''s what''s happening. Camping.goes :NewApp module NewApp class Mab; include OtherApp::Views; end end Works, but you can''t override OtherApp''s views in NewApp. If OtherApp includes a layout then you''re stuck with it (unless you change it under the Mab class in NewApp rather than Views). # Create the NewApp module and include the OtherApp''s Views into it module NewApp module Views; include OtherApp::Views; end end # Stir in Camping goodness Camping.goes :NewApp # Write the NewApp, freely using the views from OtherApp module NewApp # ... models, views, controllers, etc. end Works, and is somewhat less coupled to Camping''s implementation. A benefit of this is that you can override any of OtherApp''s views in NewApp (e.g. overriding the layout) without leaving the cosy confines of the Views module. # Controllers Camping.goes :NewApp module NewApp module Controllers; include OtherApp::Controllers; end end Works. Doing the include before Camping.goes, as in Views above, also works. # Models Camping.goes :NewApp module NewApp module Models; include OtherApp::Models; end include OtherApp # for the create method end Doesn''t work -- the OtherApp.create singleton method isn''t included into NewApp (due to the way include works). Camping.goes :NewApp module NewApp module Models; include OtherApp::Models; end def self.create Models.create_schema end end Doesn''t work, the OtherApp tables don''t get created. create_schema doesn''t see the schema from OtherApp for some reason. Camping.goes :NewApp module NewApp module Models; include OtherApp::Models; end def self.create OtherApp::Models.create_schema end end Works. Tables are created and models from OtherApp can be used in NewApp. Doing the include, and defining self.create, before Camping.goes, as in Views above, also works. # Putting it all together See the attached: campers.rb and campfire.rb. campers.rb is a simple app that exposes a list of campers, campfire.rb extends this with another controller and view, please excuse the campness of it all. The main ingredient is the means by which Campfire includes Campers: module Campfire module Models; include Campers::Models; end module Controllers; include Campers::Controllers; end module Views; include Campers::Views; end module Helpers; include Campers::Helpers; end def self.create; Campers.create; end end This comes *before* the `Camping.goes :Campfire` line. So, if you want to incorporate one Camping app within another the above method seems to be the way to go. Seems a bit verbose though and I don''t like that whole "you have to extend the new application before creating it with Camping.goes" thing. How about coercing include to help us out a bit? module Campers def self.included(other_app) %w{Helpers Models Controllers Views}.each do |mod| next unless self.const_defined? mod unless other_app.const_defined? mod other_app.const_set(mod, Module.new) end our_mod = self.const_get(mod) other_app.const_get(mod).class_eval(){include our_mod} end if !other_app.method_defined?(''create'') \ && self.method_defined?(''create'') other_app.class_eval( "def self.create; #{self.name}.create; end" ) end end end Hmmm. That''s decidedly *more* verbose. But we can now do this: module Campfire; include Campers; end Camping.goes :Campfire # ... Campfire models, views, controllers, etc. So, if we can hide that great big chunk of `included` somewhere out of sight, but where Camping apps can pick it up, we''d be somewhere near to where we want to be. -- Adam -------------- next part -------------- A non-text attachment was scrubbed... Name: campers.rb Type: application/x-ruby Size: 1340 bytes Desc: not available Url : http://rubyforge.org/pipermail/camping-list/attachments/20061120/995d29c5/attachment-0002.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: campfire.rb Type: application/x-ruby Size: 834 bytes Desc: not available Url : http://rubyforge.org/pipermail/camping-list/attachments/20061120/995d29c5/attachment-0003.bin