theme.twig (15717B)
1 {{ header }}{{ column_left }} 2 <div id="content"> 3 <div class="page-header"> 4 <div class="container-fluid"> 5 <h1>{{ heading_title }}</h1> 6 <ul class="breadcrumb"> 7 {% for breadcrumb in breadcrumbs %} 8 <li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li> 9 {% endfor %} 10 </ul> 11 </div> 12 </div> 13 <div class="container-fluid"> 14 <div class="panel panel-default"> 15 <div class="panel-heading"> 16 <h3 class="panel-title"><i class="fa fa-list"></i> {{ text_edit }}</h3> 17 </div> 18 <div class="panel-body"> 19 <div class="row"> 20 <div class="col-lg-3 col-md-3 col-sm-12"> 21 <div class="list-group"> 22 <div class="list-group-item"> 23 <h4 class="list-group-item-heading">{{ text_store }}</h4> 24 </div> 25 <div class="list-group-item"> 26 <select name="store_id" class="form-control"> 27 <option value="0">{{ text_default }}</option> 28 {% for store in stores %} 29 <option value="{{ store.store_id }}">{{ store.name }}</option> 30 {% endfor %} 31 </select> 32 </div> 33 </div> 34 <div class="list-group"> 35 <div class="list-group-item"> 36 <h4 class="list-group-item-heading">{{ text_template }}</h4> 37 </div> 38 <div id="path"></div> 39 </div> 40 </div> 41 <div class="col-lg-9 col-md-9 col-sm-12"> 42 <div class="alert alert-info"><i class="fa fa-info-circle"></i> {{ text_twig }}</div> 43 <div id="recent"> 44 <fieldset> 45 <legend>{{ text_history }}</legend> 46 <div id="history"></div> 47 </fieldset> 48 </div> 49 <div id="code" style="display: none;"> 50 <ul class="nav nav-tabs"> 51 </ul> 52 <div class="tab-content"></div> 53 </div> 54 </div> 55 </div> 56 </div> 57 </div> 58 </div> 59 <link href="view/javascript/codemirror/lib/codemirror.css" rel="stylesheet" /> 60 <link href="view/javascript/codemirror/theme/monokai.css" rel="stylesheet" /> 61 <script type="text/javascript" src="view/javascript/codemirror/lib/codemirror.js"></script> 62 <script type="text/javascript" src="view/javascript/codemirror/lib/xml.js"></script> 63 <script type="text/javascript" src="view/javascript/codemirror/lib/formatting.js"></script> 64 <script type="text/javascript"><!-- 65 $('select[name="store_id"]').on('change', function(e) { 66 $.ajax({ 67 url: 'index.php?route=design/theme/path&user_token={{ user_token }}&store_id=' + $('select[name="store_id"]').val(), 68 dataType: 'json', 69 beforeSend: function() { 70 $('select[name="store_id"]').prop('disabled', true); 71 }, 72 complete: function() { 73 $('select[name="store_id"]').prop('disabled', false); 74 }, 75 success: function(json) { 76 html = ''; 77 78 if (json['directory']) { 79 for (i = 0; i < json['directory'].length; i++) { 80 html += '<a href="' + json['directory'][i]['path'] + '" class="list-group-item directory">' + json['directory'][i]['name'] + ' <i class="fa fa-arrow-right fa-fw pull-right"></i></a>'; 81 } 82 } 83 84 if (json['file']) { 85 for (i = 0; i < json['file'].length; i++) { 86 html += '<a href="' + json['file'][i]['path'] + '" class="list-group-item file">' + json['file'][i]['name'] + ' <i class="fa fa-arrow-right fa-fw pull-right"></i></a>'; 87 } 88 } 89 90 $('#path').html(html); 91 }, 92 error: function(xhr, ajaxOptions, thrownError) { 93 alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 94 } 95 }); 96 }); 97 98 $('select[name="store_id"]').trigger('change'); 99 100 $('#path').on('click', 'a.directory', function(e) { 101 console.log($(node).attr('href')); 102 103 e.preventDefault(); 104 105 var node = this; 106 107 $.ajax({ 108 url: 'index.php?route=design/theme/path&user_token={{ user_token }}&store_id=' + $('select[name="store_id"]').val() + '&path=' + $(node).attr('href'), 109 dataType: 'json', 110 beforeSend: function() { 111 $(node).find('i').removeClass('fa-arrow-right'); 112 $(node).find('i').addClass('fa-circle-o-notch fa-spin'); 113 }, 114 complete: function() { 115 $(node).find('i').removeClass('fa-circle-o-notch fa-spin'); 116 $(node).find('i').addClass('fa-arrow-right'); 117 }, 118 success: function(json) { 119 html = ''; 120 121 if (json['directory']) { 122 for (i = 0; i < json['directory'].length; i++) { 123 html += '<a href="' + json['directory'][i]['path'] + '" class="list-group-item directory">' + json['directory'][i]['name'] + ' <i class="fa fa-arrow-right fa-fw pull-right"></i></a>'; 124 } 125 } 126 127 if (json['file']) { 128 for (i = 0; i < json['file'].length; i++) { 129 html += '<a href="' + json['file'][i]['path'] + '" class="list-group-item file">' + json['file'][i]['name'] + ' <i class="fa fa-arrow-right fa-fw pull-right"></i></a>'; 130 } 131 } 132 133 if (json['back']) { 134 html += '<a href="' + json['back']['path'] + '" class="list-group-item directory">' + json['back']['name'] + ' <i class="fa fa-arrow-left fa-fw pull-right"></i></a>'; 135 } 136 137 $('#path').html(html); 138 }, 139 error: function(xhr, ajaxOptions, thrownError) { 140 alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 141 } 142 }); 143 }); 144 145 $('#path').on('click', 'a.file', function(e) { 146 e.preventDefault(); 147 148 var node = this; 149 150 // Check if the file has an extension 151 var pos = $(node).attr('href').lastIndexOf('.'); 152 153 if (pos != -1) { 154 var tab_id = $('select[name="store_id"]').val() + '-' + $(node).attr('href').slice(0, pos).replace(/\//g, '-').replace(/_/g, '-'); 155 } else { 156 var tab_id = $('select[name="store_id"]').val() + '-' + $(node).attr('href').replace(/\//g, '-').replace(/_/g, '-'); 157 } 158 159 if (!$('#tab-' + tab_id).length) { 160 $.ajax({ 161 url: 'index.php?route=design/theme/template&user_token={{ user_token }}&store_id=' + $('select[name="store_id"]').val() + '&path=' + $(node).attr('href'), 162 dataType: 'json', 163 beforeSend: function() { 164 $(node).find('i').removeClass('fa-arrow-right'); 165 $(node).find('i').addClass('fa-circle-o-notch fa-spin'); 166 }, 167 complete: function() { 168 $(node).find('i').removeClass('fa-circle-o-notch fa-spin'); 169 $(node).find('i').addClass('fa-arrow-right'); 170 }, 171 success: function(json) { 172 if (json['code']) { 173 $('#code').show(); 174 $('#recent').hide(); 175 176 $('.nav-tabs').append('<li><a href="#tab-' + tab_id + '" data-toggle="tab">' + $(node).attr('href').split('/').join(' / ') + ' <i class="fa fa-minus-circle"></i></a></li>'); 177 178 html = '<div class="tab-pane" id="tab-' + tab_id + '">'; 179 html += ' <textarea name="code" rows="10"></textarea>'; 180 html += ' <input type="hidden" name="store_id" value="' + $('select[name="store_id"]').val() + '" />'; 181 html += ' <input type="hidden" name="path" value="' + $(node).attr('href') + '" />'; 182 html += ' <br />'; 183 html += ' <div class="pull-right">'; 184 html += ' <button type="button" data-loading-text="{{ text_loading }}" class="btn btn-primary"><i class="fa fa-floppy-o"></i> {{ button_save }}</button>'; 185 html += ' <button data-loading-text="{{ text_loading }}" class="btn btn-danger"><i class="fa fa-recycle"></i> {{ button_reset }}</button>'; 186 html += ' </div>'; 187 html += '</div>'; 188 189 $('.tab-content').append(html); 190 191 $('.nav-tabs a[href=\'#tab-' + tab_id + '\']').tab('show'); 192 193 // Initialize codemirrror 194 var codemirror = CodeMirror.fromTextArea(document.querySelector('.tab-content .active textarea'), { 195 mode: 'text/html', 196 height: '500px', 197 lineNumbers: true, 198 autofocus: true, 199 theme: 'monokai' 200 }); 201 202 codemirror.setValue(json['code']); 203 } 204 }, 205 error: function(xhr, ajaxOptions, thrownError) { 206 alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 207 } 208 }); 209 } else { 210 $('.nav-tabs a[href=\'#tab-' + tab_id + '\']').tab('show'); 211 } 212 }); 213 214 $('.nav-tabs').on('click', 'i.fa-minus-circle', function(e) { 215 e.preventDefault(); 216 217 if ($(this).parent().parent().is('li.active')) { 218 index = $(this).parent().parent().index(); 219 220 if (index == 0) { 221 $(this).parent().parent().parent().find('li').eq(index + 1).find('a').tab('show'); 222 } else { 223 $(this).parent().parent().parent().find('li').eq(index - 1).find('a').tab('show'); 224 } 225 } 226 227 $(this).parent().parent().remove(); 228 229 $($(this).parent().attr('href')).remove(); 230 231 if (!$('#code > ul > li').length) { 232 $('#code').hide(); 233 $('#recent').show(); 234 } 235 }); 236 237 $('.tab-content').on('click', '.btn-primary', function(e) { 238 var node = this; 239 240 var editor = $('.tab-content .active .CodeMirror')[0].CodeMirror; 241 242 $.ajax({ 243 url: 'index.php?route=design/theme/save&user_token={{ user_token }}&store_id=' + $('.tab-content .active input[name="store_id"]').val() + '&path=' + $('.tab-content .active input[name="path"]').val(), 244 type: 'post', 245 data: 'code=' + encodeURIComponent(editor.getValue()), 246 dataType: 'json', 247 beforeSend: function() { 248 $(node).button('loading'); 249 }, 250 complete: function() { 251 $(node).button('reset'); 252 }, 253 success: function(json) { 254 $('.alert-dismissible').remove(); 255 256 if (json['error']) { 257 $('#content > .container-fluid').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> ' + json['error'] + ' <button type="button" class="close" data-dismiss="alert">×</button></div>'); 258 } 259 260 if (json['success']) { 261 $('#content > .container-fluid').prepend('<div class="alert alert-success alert-dismissible"><i class="fa fa-exclamation-circle"></i> ' + json['success'] + ' <button type="button" class="close" data-dismiss="alert">×</button></div>'); 262 263 $('#history').load('index.php?route=design/theme/history&user_token={{ user_token }}'); 264 } 265 }, 266 error: function(xhr, ajaxOptions, thrownError) { 267 alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 268 } 269 }); 270 }); 271 272 $('.tab-content').on('click', '.btn-danger', function(e) { 273 if (confirm('{{ text_confirm }}')) { 274 var node = this; 275 276 $.ajax({ 277 url: 'index.php?route=design/theme/reset&user_token={{ user_token }}&store_id=' + $('.tab-content .active input[name="store_id"]').val() + '&path=' + $('.tab-content .active input[name="path"]').val(), 278 dataType: 'json', 279 beforeSend: function() { 280 $(node).button('loading'); 281 }, 282 complete: function() { 283 $(node).button('reset'); 284 }, 285 success: function(json) { 286 $('.alert-dismissible').remove(); 287 288 if (json['error']) { 289 $('#content > .container-fluid').prepend('<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> ' + json['error'] + ' <button type="button" class="close" data-dismiss="alert">×</button></div>'); 290 } 291 292 if (json['success']) { 293 $('#content > .container-fluid').prepend('<div class="alert alert-success alert-dismissible"><i class="fa fa-exclamation-circle"></i> ' + json['success'] + ' <button type="button" class="close" data-dismiss="alert">×</button></div>'); 294 } 295 296 var codemirror = $('.tab-content .active .CodeMirror')[0].CodeMirror; 297 298 codemirror.setValue(json['code']); 299 }, 300 error: function(xhr, ajaxOptions, thrownError) { 301 alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 302 } 303 }); 304 } 305 }); 306 307 $('#history').delegate('.pagination a', 'click', function(e) { 308 e.preventDefault(); 309 310 $('#history').load(this.href); 311 }); 312 313 $('#history').load('index.php?route=design/theme/history&user_token={{ user_token }}'); 314 315 $('#history').on('click', '.btn-primary', function(e) { 316 e.preventDefault(); 317 318 var node = this; 319 320 // Check if the file has an extension 321 var tab_id = $(node).parent().parent().find('input[name="store_id"]').val() + '-' + $(node).parent().parent().find('input[name="path"]').val().replace(/\//g, '-').replace(/_/g, '-'); 322 323 if (!$('#tab-' + tab_id).length) { 324 $.ajax({ 325 url: 'index.php?route=design/theme/template&user_token={{ user_token }}&store_id=' + $(node).parent().parent().find('input[name="store_id"]').val() + '&path=' + $(node).parent().parent().find('input[name="path"]').val(), 326 dataType: 'json', 327 beforeSend: function() { 328 $(node).button('loading'); 329 }, 330 complete: function() { 331 $(node).button('reset'); 332 }, 333 success: function(json) { 334 if (json['code']) { 335 $('#code').show(); 336 $('#recent').hide(); 337 338 $('.nav-tabs').append('<li><a href="#tab-' + tab_id + '" data-toggle="tab">' + $(node).parent().parent().find('input[name="path"]').val().split('/').join(' / ') + ' <i class="fa fa-minus-circle"></i></a></li>'); 339 340 html = '<div class="tab-pane" id="tab-' + tab_id + '">'; 341 html += ' <textarea name="code" rows="10"></textarea>'; 342 html += ' <input type="hidden" name="store_id" value="' + $(node).parent().parent().find('input[name="store_id"]').val() + '" />'; 343 html += ' <input type="hidden" name="path" value="' + $(node).parent().parent().find('input[name="path"]').val() + '.twig" />'; 344 html += ' <br />'; 345 html += ' <div class="pull-right">'; 346 html += ' <button type="button" data-loading-text="{{ text_loading }}" class="btn btn-primary"><i class="fa fa-floppy-o"></i> {{ button_save }}</button>'; 347 html += ' <button data-loading-text="{{ text_loading }}" class="btn btn-danger"><i class="fa fa-recycle"></i> {{ button_reset }}</button>'; 348 html += ' </div>'; 349 html += '</div>'; 350 351 $('.tab-content').append(html); 352 353 $('.nav-tabs a[href=\'#tab-' + tab_id + '\']').tab('show'); 354 355 // Initialize codemirrror 356 var codemirror = CodeMirror.fromTextArea(document.querySelector('.tab-content .active textarea'), { 357 mode: 'text/html', 358 height: '500px', 359 lineNumbers: true, 360 autofocus: true, 361 theme: 'monokai' 362 }); 363 364 codemirror.setValue(json['code']); 365 } 366 }, 367 error: function(xhr, ajaxOptions, thrownError) { 368 alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 369 } 370 }); 371 } else { 372 $('.nav-tabs a[href=\'#tab-' + tab_id + '\']').tab('show'); 373 } 374 }); 375 376 $('#history').on('click', '.btn-danger', function(e) { 377 e.preventDefault(); 378 379 if (confirm('{{ text_confirm }}')) { 380 var node = this; 381 382 $.ajax({ 383 url: $(node).attr('href'), 384 dataType: 'json', 385 beforeSend: function() { 386 $(node).button('loading'); 387 }, 388 complete: function() { 389 $(node).button('reset'); 390 }, 391 success: function(json) { 392 $('.alert-dismissible').remove(); 393 394 if (json['error']) { 395 $('#history').before('<div class="alert alert-danger alert-dismissible"><i class="fa fa-exclamation-circle"></i> ' + json['error'] + ' <button type="button" class="close" data-dismiss="alert">×</button></div>'); 396 } 397 398 if (json['success']) { 399 $('#history').before('<div class="alert alert-success alert-dismissible"><i class="fa fa-exclamation-circle"></i> ' + json['success'] + ' <button type="button" class="close" data-dismiss="alert">×</button></div>'); 400 401 $('#history').load('index.php?route=design/theme/history&user_token={{ user_token }}'); 402 } 403 }, 404 error: function(xhr, ajaxOptions, thrownError) { 405 alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText); 406 } 407 }); 408 } 409 }); 410 //--></script> 411 </div> 412 {{ footer }}