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