Rails Describes the Source of HTML Content

I'm looking for a gem or an elegant way to set up a system where I can see where certain HTML content came from. I am working on a large project, and many of my times determine where a particular piece of HTML content came from. I know that you can see which partial layouts are used to display the page in the magazines, but I'm looking for something more practical.

An example of this might be.

<!-- ... app/views/layouts/main.html.slim --> <body> <!-- ... app/views/people/index.html.slim --> <div class="foo"> <table clas="items"> <!-- ... app/views/people/shared/_person.html.slim --> <td> <span>John Doe</span> </td> </table> </div> </body> 

If, before rendering, any partial / page / layout rails engine engine adds a comment describing the origin.

+5
source share
2 answers

Perhaps this rails_view_annotator gem would be a good starting point:

Rails View Annotator wraps partial Rails rendering with html comments indicating the location of the partial rendering drive.

According to the README project, the stone will display the displayed content as follows:

 <!-- begin: app/views/user/_bio.html.haml (from app/views/user/show.html.haml:4) --> <div class='bio'>Ed Bio</div> <!-- end: app/views/user/_bio.html.haml (from app/views/user/show.html.haml:4) --> 

However, it does not look like it in active development, so it cannot be compatible with the latest versions of Rails YMMV.

+3
source

I don’t know if there is a stone for this, but you can rewrite the class intended for rendering the output of all views and partitions located in:

.bundle/ruby/ruby-2.3.1/gems/action-view-4.2.5.1/lib/action_view/template.rb (replace the version number)

There is a method called def compile(mod) owerwrite to add your own lines that you want to represent in the view. For your case, you can do something like this:

 def compile(mod) #:nodoc: encode! method_name = self.method_name code = @handler.call(self) # This is the code I have added code.insert(63, "@output_buffer.safe_append='\n<!--#{self.inspect} start -->\n'.freeze\;") code.insert(code.size-19, "@output_buffer.safe_append='\n<!--#{self.inspect} end -->\n'.freeze\;") # Make sure that the resulting String to be eval'd is in the # encoding of the code source = <<-end_src def #{method_name}(local_assigns, output_buffer) _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code} ensure @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer end end_src # Make sure the source is in the encoding of the returned code source.force_encoding(code.encoding) # In case we get back a String from a handler that is not in # BINARY or the default_internal, encode it to the default_internal source.encode! # Now, validate that the source we got back from the template # handler is valid in the default_internal. This is for handlers # that handle encoding but screw up unless source.valid_encoding? raise WrongEncodingError.new(@source, Encoding.default_internal) end mod.module_eval(source, identifier, 0) ObjectSpace.define_finalizer(self, Finalizer[method_name, mod]) end 

Added code:

 code.insert(63, "@output_buffer.safe_append='\n<!--#{self.inspect} start -->\n'.freeze\;") code.insert(code.size-19, "@output_buffer.safe_append='\n<!--#{self.inspect} end -->\n'.freeze\;") 

And it will display all partial and all representations in the views as they are rendered.

The result will look like this:

 <!--app/views/profiles/_header.html.erb start --> Your text on the page <!--app/views/profiles/_header.html.erb end --> 

If you want to extract this into a separate class, create a new initialization file in the config/initializers/ directory of the Rails project, which is called, for example, render_override.rb , and paste the code something like this:

 ActionView::Template.class_eval do # @override def compile(mod) encode! method_name = self.method_name code = @handler.call(self) # This is the code I have added code.insert(63, "@output_buffer.safe_append='\n<!--#{self.inspect} start -->\n'.freeze\;") code.insert(code.size-19, "@output_buffer.safe_append='\n<!--#{self.inspect} end -->\n'.freeze\;") # Make sure that the resulting String to be eval'd is in the # encoding of the code source = <<-end_src def #{method_name}(local_assigns, output_buffer) _old_virtual_path, @virtual_path = @virtual_path, #{@virtual_path.inspect};_old_output_buffer = @output_buffer;#{locals_code};#{code} ensure @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer end end_src # Make sure the source is in the encoding of the returned code source.force_encoding(code.encoding) # In case we get back a String from a handler that is not in # BINARY or the default_internal, encode it to the default_internal source.encode! # Now, validate that the source we got back from the template # handler is valid in the default_internal. This is for handlers # that handle encoding but screw up unless source.valid_encoding? raise WrongEncodingError.new(@source, Encoding.default_internal) end mod.module_eval(source, identifier, 0) ObjectSpace.define_finalizer(self, Finalizer[method_name, mod]) end end 

Reboot the server so that the changes can be picked up, and now your views will be displayed with these new settings.

You might want to surround your eval class with the RAILS_ENV='dev' check or something similar so that it can only be started during development and you are ready to go.

0
source

Source: https://habr.com/ru/post/1259405/


All Articles