tsechingho/ckeditor-rails

Incorrect asset links in css when deploying to a sub-directory

Opened this issue · 0 comments

I have an app for which two separate instances are deployed, a stable public-facing production version accessed at my server's root url, like https://example.com/, and a pre-release version deployed to a separate directory and accessed at https://example.com/pre/, which is used for testing out new features against my production database. In the latter case, Rails.application.config.relative_url_root is set to '/pre' in production.rb.

I discovered that for my pre-release code, asset precompilation during deployment was resulting in image assets referenced within ckeditor css files being rewritten with incorrect paths. For example, in the css file /vendor/assets/stylesheets/ckeditor/skins/moono-lisa/editor.css, the image 'icons.png' is referenced as a background image with url 'icons.png'. During compilation, this asset gets written to the server at public/assets/ckeditor/skins/moono-lisa/icons.png and so we would expect it to be referenced by path /pre/assets/ckeditor/skins/moono-lisa/icons.png. However in editor.css after precompilation it is referenced by the path /pre/assets/ckeditor/skins/moono-lisa/pre/icons.png, i.e. with a spurious relative_url_root segment preceding the file name.

From what I can tell, the problem occurs because of the way the css file is processed first by Sprockets::Rails::AssetUrlProcessor and then by Ckeditor::Rails::AssetUrlProcessor. In Sprockets::Rails::AssetUrlProcessor.call, the asset path is rewritten from icons.png to /pre/icons.png, with the prefix being added by the ActionView helper asset_path which is included into Sprockets::Rails::Context. The resulting file is passed on to the next processor in the pipeline, Ckeditor::Rails::AssetUrlProcessor. As I understand it, this is needed because the css files originate from a non-Rails codebase and so don't encode embedded asset references relative to Sprockets' load_paths e.g. using Rails helpers like asset_path.

Ckeditor::Rails::AssetUrlProcessor.call prepends each asset url in the css file with a prefix consisting of: ::Rails.application.config.action_controller.relative_url_root, followed by
"#{::Sprockets::Railtie.config.assets.prefix}/ckeditor" and finally the matched folders
"/skins/moona-lisa".

However the relative_url_root prefix added by the default sprocket-rails processor is not removed first and so ends up embedded in the path string in addition to the correct prefix attached by Ckeditor::Rails::AssetUrlProcessor.

The solution I have adopted is to simply modify the line in the call method that computes raw_asset_path:

raw_asset_path = context.asset_path($1)

with the following:

raw_asset_path = context.asset_path($1).gsub(/^#{Regexp.quote(::Rails.application.config.relative_url_root)}/, '')

i.e. removing the relative_url_root from the default processor before adding the prefix required by ckeditor.

Is my analysis of the problem correct?