2013-08-17 47 views
8

我正在構建一個Django應用程序,該應用程序爲單個頁面Angular應用程序提供服務。我該如何告訴grunt-usemin忽略Django的靜態模板標籤?

Django的服務的角度的index.html的它具有以下usemin腳本塊:

<!-- build:js scripts/scripts.js --> 
<script src="{% static "scripts/app.js" %}"></script> 
<script src="{% static "scripts/controllers/main.js" %}"></script> 
<script src="{% static "scripts/controllers/stats.js" %}"></script> 
<script src="{% static "scripts/directives/highchart.js" %}"></script> 
<!-- endbuild --> 

Usemin試圖找到「{%靜態‘腳本/ app.js’%}」上的文件系統,當然失敗因爲它真的應該試圖找到的是「scripts/app.js」。

有沒有人看到這個解決方法?

+0

你是否用'grunt build'構建了這個站點,不應該爲客戶端提供一個usemin塊,這隻適用於咕嚕聲,並且與後端(afaik)無關。 – Patrick

+0

我試圖利用Django的反向URL查找靜態url,所以我從Django路徑提供Angular的index.html,這允許我在index.html中使用Django模板標籤。我已經放棄了這一點,現在將從靜態url訪問index.html,而不是正確的Django路線。我會咬緊牙關,如果我的靜態文件網址發生變化,我會手動更新index.html。 – davemckenna01

+0

@ davemckenna01自8月份起,當您最初提問時,您是否發現過任何新內容?我目前正在使用grunt/yeoman和Angular,並且將工作流程與django集成在一起會讓我放慢腳步。 – kevins

回答

9

好吧,我想我有一個解決方法。假設您希望構建的文件也指向構建資產的靜態url。

這將要求您在視圖上下文中定義STATIC_URL(而不是使用src="{% static 'foo/bar.js' %}",您將使用src="{{STATIC_URL}}foo/bar.js")。我無法讓{% static %}工作,而無需攻擊grunt-usemin源代碼。

所以使用您的例子,這樣的:

<!-- build:js {{STATIC_URL}}scripts/scripts.js --> 
<script src="{{STATIC_URL}}scripts/app.js"></script> 
<script src="{{STATIC_URL}}scripts/controllers/main.js"></script> 
<script src="{{STATIC_URL}}scripts/controllers/stats.js"></script> 
<script src="{{STATIC_URL}}scripts/directives/highchart.js"></script> 
<!-- endbuild --> 

編譯爲:

<script src="{{STATIC_URL}}scripts/scripts.js"></script> 

爲了實現這一點,我不得不添加以下咕嚕配置(在Gruntfile.js):

// custom createConfig script for replacing Django {{STATIC_URL}} references 
// when building config for concat and cssmin 
var path = require('path'); 
function createDjangoStaticConcatConfig(context, block) { 
    var cfg = {files: []}; 
    var staticPattern = /\{\{\s*STATIC_URL\s*\}\}/; 

    block.dest = block.dest.replace(staticPattern, ''); 
    var outfile = path.join(context.outDir, block.dest); 

    // Depending whether or not we're the last of the step we're not going to output the same thing 
    var files = { 
    dest: outfile, 
    src: [] 
    }; 
    context.inFiles.forEach(function(f) { 
    files.src.push(path.join(context.inDir, f.replace(staticPattern, ''))); 
    }); 
    cfg.files.push(files); 
    context.outFiles = [block.dest]; 
    return cfg; 
} 


grunt.initConfig({ 
    /*...*/ 

    // add a preprocessor to modify the concat config to parse out {{STATIC_URL}} using the above method 
    useminPrepare: { 
     html: 'app/index.html', 
     options: { 
     dest: 'dist', 
     flow: { 
      steps: { 
      js: [ 
       { 
       name: 'concat', 
       createConfig: createDjangoStaticConcatConfig 
       }, 
       'uglifyjs' 
      ], 
      // also apply it to css files 
      css: [ 
       { 
       name: 'cssmin', 
       createConfig: createDjangoStaticConcatConfig 
       } 
      ] 
      }, 
      // this property is necessary 
      post: {} 
     } 
     } 
    }, 

    // add a pattern to parse out the actual filename and remove the {{STATIC_URL}} bit 
    usemin: { 
     html: ['dist/{,*/}*.html'], 
     css: ['dist/styles/{,*/}*.css'], 
     options: { 
     assetsDirs: ['dist'], 
     patterns: { 
      html: [[/\{\{\s*STATIC_URL\s*\}\}([^'"]*)["']/mg, 'django static']] 
     } 
     } 
    }, 


    // if you are using bower, also include the jsPattern to automatically 
    // insert {{STATIC_URL}} when inserting js files 
    'bower-install': { 
     app: { 
     html: 'app/index.html', 
     jsPattern: '<script type="text/javascript" src="{{STATIC_URL}}{{filePath}}"></script>' 
     } 
    } 
}); 
+0

偉大的工作,但輸出不產生{{STATIC_URL}}前綴 – debuggerpk

+1

嘿感謝,此修復程序我的問題與PHP。對於有此問題的人來說,'post:{}'屬性是必需的 – stalin

+0

@stalin是的。我會在那裏記下來,所以更明顯。謝謝! – lakenen

3

(我一直在尋找解決方案時發現這個問題,所以我只是分享我找到她的解決方案e,以便像我這樣的其他人可以找到它。)

我剛剛發現了一個名爲grunt-bridge的咕嚕插件,它可以將靜態文件用static標記包裝在html模板中。文檔不是很好,但我想如何讓它爲我的項目工作。

如果你有這樣的腳本:

<!-- build:js({.tmp,app}) /scripts/scripts.js --> 
    <script src="scripts/app.js"></script> 
    <script src="scripts/util/util.js"></script> 
    ... 

它最終輸出到輸出是這樣的:

<script src="{% static 'adjangoappname/scripts/94223d51.scripts.js' %}"></script> 

安裝gruntbridge與npm install grunt-bridge --save-dev和 在咕嚕增加一個配置是這樣Gruntfile.js的.init配置:

bridge: { 
    distBaseHtml: { 
     options: { 
      pattern: '{% static \'adjangoappname{path}\' %}', 
      html: '<%= yeoman.minifiedDir %>/index.html', dest: '<%= yeoman.templateDir %>/index.html' 
     } 
    }, 
    distIndexHtml: { 
     options: { 
      pattern: '{% static \'adjangoappname{path}\' %}', 
      html: '<%= yeoman.minifiedDir %>/index.html', dest: '<%= yeoman.templateDir %>/index.html' 
     } 
    }, 
    // ... etc for each html file you want to modify 
}, 

其中<%= yeoman.minifiedDir %>是最終縮小的html文件的輸出目錄,而<%= yeoman.minifiedDir %>是目標模板目錄。 將adjangoappname替換爲您的django應用程序的名稱或您想要的任何目錄前綴。

然後加入咕嚕橋最後在registerTask名單如下:

grunt.registerTask('build', [ 
    //... 
    'htmlmin', 
    'bridge' 
]); 

(我認爲這是可能的,以使配置更加緊湊,但是這是第一種方法,我發現工作)

+0

grunt-bridge插件很棒。我用yeoman-webapp測試了它。我需要從'build'任務中刪除'htmlmin',因爲grunt-bridge不喜歡缺少'htmlmin'生成的引號。 – tsand