Ticket #32849 Discussion: Line breaks handling in ManifestStaticFilesStorage regex

Hello everyone,

I’d like to contribute to ticket #32849 (“ManifestStaticFilesStorage line breaks regex”) and would appreciate feedback before submitting a patch. Here’s my analysis:

Current Behavior

  1. Files are loaded with original line breaks (storage.py#L315)
  2. Default regex patterns (like url()) work because minifiers preserve them
  3. Custom regex patterns (like CKEditor’s appendStyleSheet) fail when line breaks exist

Proposed Solutions

Option 1: Pre-process content (remove line breaks)

def read_manifest(self):
    content = super().read_manifest()
    return content.replace('\n', '')  # Simple but might break sourcemaps?

Option 2 : Document the requirement for line break-aware regex

# In docs:
"Custom patterns must account for potential line breaks, e.g. r'\s?' between tokens"

Option 3 : Auto-convert patterns

def prepare_pattern(self, pattern):
    return pattern.replace(' ', '\s*')  # Automatic whitespace handling

Questions

  1. Which approach aligns best with Django’s philosophy?
  2. Should this be considered a bug fix (Option 1) or a docs clarification (Option 2)?
  3. Are there edge cases I’m missing? (e.g., sourcemaps, CSS comments)

Geordan

I would say the Django philosophy is to “not break things”.
I am not sure what would be the drawbacks of Option 3.

With my limited knowledge of this particular topic and assuming option 3 does not break anything, I would say 3 could be the best approach.

If option 3 risks breaking some other code, then probably option 2.

From what you stated, I think option 1 is the most likely to break things, not just sourcemap (it’s just a hunch, if someone knows better, listen to them).

Thank you @emma for the guidance! Based on your feedback, I’ll pursue Option 3 (auto-convert patterns) with these precautions:

Implementation Plan

  1. Safe Pattern Conversion
def prepare_pattern(self, pattern):
    # Only handle spaces between tokens, not inside strings
    return re.sub(r'([^\\])(\s+)(?=[^\"\']*[\"\'\)])', r'\1\s*', pattern)
  1. Backward Compatibility
  • Keep original behavior for default patterns (url())
  • Add MANIFEST_STRICT_MODE=False setting for legacy systems
  1. Testing Strategy
    Will test against:
  • CKEditor 4/5
  • Webpack-generated files
  • Sourcemaps
  • CSS @import with line breaks
1 Like