From: Alexandru Popescu Date: 2005-08-30T02:46:05+09:00 Subject: Re: Soks Wiki - Support for page tagging added --------------090203050906060800060500 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit #: Tom Counsell changed the world a bit at a time by saying on 8/29/2005 5:15 PM :# > Hello Alexandru > > On 27 Aug 2005, at 10:29, Alexandru Popescu wrote: >> I am not sure this is the right place to post this message, so >> sorry if it is not. > > There is also a soks mailing list, you can join at http:// > rubyforge.org/mail/?group_id=481 and a wiki about soks at http:// > www.soks.org. > For the moment I will not join Soks ML but soon I will be there :-). >> My first Ruby coding was directed to add support for tagging to >> Soks. It works in the following form: >> >> - include anywhere in the page a line containing >> tags: category1 category2 ... etc >> >> and than these are automatically link to category pages, category >> pages create a backlink to the page. The category pages are managed >> automatically. > > This is definitely possible, and shouldn't need much code. > I have already done this. What is more interesting to me is the way I did it :-). >> Being the first time working with Ruby I have faced 2 problems: >> >> 1/ understanding/navagating the existing code > > Always a problem. http://www.soks.org/view/HowToHackSoks may give > some clues. > It was a good start. But I am talking about real working and not about the available documentation. >> 2/ understanding the correct way to extend the existing code >> I would very pleased if somebody (maybe the authors?) would take a >> look at what have I done and help me understand my mistakes and >> correct them in the future. > > Happy to help, although it may be best for you to either send me the > code direct, or to the soks mailing list above. > > I look forward to hearing from you, > > Tom > > Attached is the main addition to soks code. There are some other tweaks I have done and I am listing them here: - removed automatic page linking (socks-view.rb#inline_soks) - imported the attached extensions from start.rb, just before instantiating the wiki. Being the first thing done by me in Ruby I don't expect to have the Ruby flavor, so I will be very glad to hear your comments. thanks for your time, :alex |.::the_mindstorm::.| ps: if you want to send the answer offline pls use the_mindstorm[at]evolva[dot]ro. many thanks --------------090203050906060800060500 Content-Type: text/plain; name="soks-model-ext.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="soks-model-ext.rb" class Page alias :default_initialize :initialize attr_accessor :wiki def initialize(name, wiki) $LOG.debug("initialize: #{name} #{wiki}") default_initialize name @wiki = wiki end # Returns an empty version of itself. # rewrite of the original method to allow passing the wiki reference def self.empty( name , wiki) $LOG.debug("new self.empty"); empty = self.new( name , wiki) empty.revise( $MESSAGES[:Type_what_you_want_here_and_click_save], "NoOne" ) class << empty def empty?; true; end end empty end end # a Page with support for tags class TaggedPage < Page attr_accessor :tags def initialize( name, wiki) super name, wiki @tags = [] end # Revises the content of this page, creating a new revision class that stores the changes def revise( new_content, author ) return nil if new_content == @content updated_content = prepare_content(new_content) # $' is $POSTMATCH old_tags, @tags = @tags, [] updated_content.each_line { |line| extract_tags $' if line =~ /^tags:\s+/i } @wiki.refresh_taglinks(self, @tags - old_tags, old_tags - @tags) if @wiki super(updated_content, author) end def content=(new_content) @content = prepare_content(new_content) @content.each_line { |line| extract_tags $' if line =~ /^tags:\s+/i } end def extract_tags(tagsline) @tags = [] regex = /([^=\[]+)/ tagsline.split(/\s+/).each do |t| tagname = regex.match(t)[1] @tags << tagname end @tags.uniq! display_page_tags if $LOG.debug? @tags end def prepare_content(new_content) updated_content = "" new_content.each do |line| if line =~ /^tags:\s+/i updated_content << "tags:" $'.split(/\s+/).each do |t| #puts "matched : #{t} with start #{t[0, 2]}" updated_content << " [[#{t}=>tag:#{t}]]" unless (t[0, 2] == "[[") updated_content << " #{t}" if (t[0, 2] == "[[") end updated_content << "\n" else updated_content << line end end updated_content end private def display_page_tags message = "page [#{@name}] tags {" @tags.each { |tagname| message << "#{tagname} " } message << "}" $LOG.debug(message) end end class Wiki alias :noself_new_page :new_page ENHANCED_PAGE_CLASSES = [ [ /^picture of/i, ImagePage ], [ /^attached/i, AttachmentPage ], [ /.*/, TaggedPage ] ] # redefinition of new_page method that provides the pages with # a reference to Wiki def new_page( name, initializer = :new ) $LOG.debug("using new new_page method") ENHANCED_PAGE_CLASSES.each do |regex,klass| return klass.send( initializer, name, self) if name =~ regex end end # added to support relinking of tag pages def refresh_taglinks(page, add_to, remove_from) add_to.each { |pagename| add_link(pagename, page) } if add_to remove_from.each { |pagename| remove_link(pagename, page) } if remove_from end private def add_link(pagename, to_page) work_page = page("tag:#{pagename}") new_content = "" add_link = true link = "#{to_page.name} => #{to_page.name}" regexp = Regexp.new(link) work_page.content.each_line do |line| add_link = false if line =~ regexp new_content << line unless line =~ /^#{$MESSAGES[:page_deleted]}/i end if add_link new_content << '* [[' << link << ']]' new_content << "\n" revise work_page.name, new_content, "automatictagging" puts "added link in page [#{work_page.name}] to page: [#{to_page.name}]" puts "new content of page [#{work_page.name}] is:\n #{work_page.content}" end return work_page end def remove_link(pagename, to_page) work_page = page("tag:#{pagename}") return if work_page.empty? remove_link = false link = "#{to_page.name} => #{to_page.name}" regexp = Regexp.new(link) new_content = "" work_page.content.each_line do |line| if line =~ regexp remove_link = true else new_content << line end end if remove_link revise work_page.name, new_content, "automatictagging" puts "removed link in page [#{work_page.name}] to page: [#{to_page.name}]" puts "new content of page [#{work_page.name}] is:\n #{work_page.content}" end return work_page end end --------------090203050906060800060500--