Overwrite a file after rebuild


(Khoa Nguyen) #1

I want to add some custom Slug (lib/slug.rb) to my instance.It work fine.
But after a rebuild, It won’t survive. How can I do it?
I find a interested Reposity on github
GitHub - lidel/discourse-locale-override: Simple hack to override official translations files in Discourse and persist them between Docker rebuilds.

But I don’t know how it work with ruby files?


(Robin Ward) #2

You should create a plugin to change the ruby code you want. If you tell us exactly what you’re changing maybe someone can suggest how to put it in a plugin.


(Khoa Nguyen) #3

@eviltrout
I want to rewrite lib/slug.rb like this
https://github.com/thangngoc89/discourse/blob/master/lib/slug.rb

I added some simple string replace. (It look a little bit ugly and there are some characters handled by Discourse)

#For Vietnamese slug 
    vietnamese   = "àáạảãâầấậẩẫăằắặẳẵèéẹẻẽêềếệểễìíịỉĩòóọỏõôồốộổỗơờớợởỡùúụủũưừứựửữỳýỵỷỹđÀÁẠẢÃÂẦẤẬẨẪĂẰẮẶẲẴÈÉẸẺẼÊỀẾỆỂỄÌÍỊỈĨÒÓỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÙÚỤỦŨƯỪỨỰỬỮỲÝỴỶỸĐêùà"
    replacements = "aaaaaaaaaaaaaaaaaeeeeeeeeeeeiiiiiooooooooooooooooouuuuuuuuuuuyyyyydAAAAAAAAAAAAAAAAAEEEEEEEEEEEIIIIIOOOOOOOOOOOOOOOOOUUUUUUUUUUUYYYYYDeua"
	string = string.tr(vietnamese, replacements)
	#End Vietnamese slug

(Robin Ward) #4

In that case, the Slug#for method is quite simple. I’d recommend creating a basic discourse plugin that just includes that code in plugin.rb. Then install it like other plugins. It should work!


(Khoa Nguyen) #6

Let’s learn ruby.
Do I need to register anything or just write that method in plugin.rb?


(Kane York) #7

Here’s your plugin.rb file. It should look familiar.

# author: bar
# name: foo
# version: blah

module Slug

  def self.for(string)
  
	#For Vietnamese slug 
    vietnamese   = "àáạảãâầấậẩẫăằắặẳẵèéẹẻẽêềếệểễìíịỉĩòóọỏõôồốộổỗơờớợởỡùúụủũưừứựửữỳýỵỷỹđÀÁẠẢÃÂẦẤẬẨẪĂẰẮẶẲẴÈÉẸẺẼÊỀẾỆỂỄÌÍỊỈĨÒÓỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÙÚỤỦŨƯỪỨỰỬỮỲÝỴỶỸĐêùà"
    replacements = "aaaaaaaaaaaaaaaaaeeeeeeeeeeeiiiiiooooooooooooooooouuuuuuuuuuuyyyyydAAAAAAAAAAAAAAAAAEEEEEEEEEEEIIIIIOOOOOOOOOOOOOOOOOUUUUUUUUUUUYYYYYDeua"
	string = string.tr(vietnamese, replacements)
	#End Vietnamese slug
	
    slug = string.gsub("'", "").parameterize
    slug.gsub!("_", "-")
    # TODO review if ja should use this
    # ko asked for it to be removed
    if ['zh_CN', 'ja'].include?(SiteSetting.default_locale)
      unless defined? Stringex
        require 'stringex_lite'
      end
      slug = string.to_url
    end
    slug =~ /[^\d]/ ? slug : '' # Reject slugs that only contain numbers, because they would be indistinguishable from id's.
  end

end

(Khoa Nguyen) #8

Could you please check this repo ? @riking


I tried to install that repo, rebuild the app but it doesn’t work.


(Robin Ward) #9

You don’t have the proper comments at the top for the plugin metadata.


(Khoa Nguyen) #10

Thank you I will add comments there.


(Khoa Nguyen) #11

I added comment and update plugin (via Docker Manager)
But it doesn’t work

# name: discourse-vietnamese-slug
# about: A Discourse plugin to generate Vietnamese slug
# version: 0.1
# authors: Khoa Nguyen

(Khoa Nguyen) #12

@eviltrout could you help me on this please?


(Robin Ward) #13

It looks like it’s a load order issue. You can do it like this:

# name: discourse-vietnamese-slug
# about: A Discourse plugin to generate Vietnamese slug
# version: 0.1
# authors: Khoa Nguyen

after_initialize do
  module ::Slug

    def self.for(string)

      # For Vietnamese slug
      vietnamese   = "àáạảãâầấậẩẫăằắặẳẵèéẹẻẽêềếệểễìíịỉĩòóọỏõôồốộổỗơờớợởỡùúụủũưừứựửữỳýỵỷỹđÀÁẠẢÃÂẦẤẬẨẪĂẰẮẶẲẴÈÉẸẺẼÊỀẾỆỂỄÌÍỊỈĨÒÓỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÙÚỤỦŨƯỪỨỰỬỮỲÝỴỶỸĐêùà"
      replacements = "aaaaaaaaaaaaaaaaaeeeeeeeeeeeiiiiiooooooooooooooooouuuuuuuuuuuyyyyydAAAAAAAAAAAAAAAAAEEEEEEEEEEEIIIIIOOOOOOOOOOOOOOOOOUUUUUUUUUUUYYYYYDeua"
      string = string.tr(vietnamese, replacements)
      # End Vietnamese slug

      slug = string.gsub("'", "").parameterize
      slug.gsub!("_", "-")
      # TODO review if ja should use this
      # ko asked for it to be removed
      if ['zh_CN', 'ja'].include?(SiteSetting.default_locale)
        unless defined? Stringex
          require 'stringex_lite'
        end
        slug = string.to_url
      end
      slug =~ /[^\d]/ ? slug : '' # Reject slugs that only contain numbers, because they would be indistinguishable from id's.
    end

  end
end

(Basically I wrapped it in an after_initialize block and made sure I was patching ::Slug instead of just Slug.


(Khoa Nguyen) #14

Woa. It works perfectly. We should write this as a how to create your own language slug :smile:
Thank you so much @eviltrout @riking.


#15

@riking @eviltrout if we only want to insert one new line in an existing function, do we need to copy the entire method to our plugin.rb with the new line?


(Robin Ward) #16

Usually yes, but it depends. Sometimes there are hooks to do what you need. What are you tryin gto change?


#17

A couple changes. One change is to lib/sender.rb to add a header to allow analytics tracking by the ESP and another change is to permalinks_controller.rb and lib/permalink_constraint.rb to allow more permissive/flexible matching of permalinks @eviltrout


(Robin Ward) #18

In those cases you could probably add an extensibility point to the methods as a PR to discourse. We’d likely accept it if a good example was given.

Otherwise extending and overwriting the method is your only approach.


#19

thanks, I’ll do the plugin approach first since I’d like the changes available immediately but will submit a PR as well.

can you clarify what a “extensibility point” is?


(Robin Ward) #20

In general when I refer to extensiblity points I mean:

  • Look at the code and identify where your change would go
  • Identify the best way to modify discourse to allow plugins to make that change.
    • For example, you could call a method that does very little to get a result, and then someone could override just that new method instead of the larger method that called it.
    • There is DiscourseEvent for when you want to insert a callback but don’t need a return value.
    • Not applicable to your examples but in templates you can add plugin outlets.