Skip to content

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

@MarkMT

Description

@MarkMT

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions