In Laravel 6, run a file that contains PHP Blade syntax and get its output
1. There is a php Blade code block, which is placed in mysql, and its code is stored in the field schema, as shown in Figure 1
2. Some variables, already declared in the php script, the code block is shown below
{
"sections": {
@foreach ($homepage as $id => $section)
{{-- 轮播图 --}}
@if($section['type'] === 'carousel')
"{{ $id }}": {
"type": "carousel",
"settings": {
"loop": true,
"autoplay": true,
"height": "{{ isset($section['slide_height']) && $section['slide_height'] === 'full' ? 'full' : 'auto' }}",
"interval": {{ $section['interval'] }}
},
"blocks": {
@if (isset($section['items']))
@foreach ($section['items'] as $key => $item)
"slide-{{ $key }}": {
"type": "slide",
"settings": {
"image": "{{ @$item['image']['url'] ?: '' }}",
"url": "{{ $item['button']['url'] }}",
"align": "{{ $item['align'] }}",
"title": {-- $item['title'] --},
"description": {-- $item['description'] --},
"button": {-- $item['button']['text'] --},
"opacity": {{ $item['show_overlay'] ? (100 - $item['opacity']) : 100 }},
"button_background_color": "{{ $item['button_background_color'] }}",
"button_color": "{{ $item['button_text_color']}}",
"color": "{{ $item['text_color'] }}"
}
}@if (!$loop->last),@endif
@endforeach
@endif
}
},
@endif
{{-- 商品分类 --}}
@if($section['type'] === 'collection')
"{{ $id }}": {
"type": "main-collections",
"settings": {
"heading": {-- $section['title'] --}
},
"blocks": {
@foreach ($section['ids'] as $key => $item)
"collection-{{ $key }}": {
"type": "collection",
"settings": {
"id": {{ $item }}
}
}@if (!$loop->last),@endif
@endforeach
}
},
@endif
{{-- 精选商品 --}}
@if($section['type'] === 'product')
"{{ $id }}": {
"type": "main-products",
"settings": {
"show_product_palette": {{ @Module::find('ProductPalette')->isEnabled() && @config('product-palette.show_position') === 'all' ? 'true' : 'false' }},
"heading": {-- $section['title'] --},
"layout": "{{ $section['layout'] }}",
"page_size": {{ $section['amount'] }}
},
"blocks": {
@foreach ($section['category'] as $key => $item)
"collection-{{ $key }}": {
"type": "collection",
"settings": {
"id": {{ $item }}
}
}@if (!$loop->last),@endif
@endforeach
}
},
@endif
{{-- 邮件订阅 --}}
@if($section['type'] === 'subscribe')
"{{ $id }}": {
"type": "apps",
"blocks": {
"newsletter": {
"type": "object/Newsletter/blocks/newsletter",
"settings": {
"heading": {-- $section['title'] --},
"description": {-- $section['description'] --}
}
}
}
},
@endif
{{-- 图片 --}}
@if($section['type'] === 'image')
"{{ $id }}": {
"type": "image",
"settings": {
"heading": {-- $section['title'] --},
"heading_align": "{{ $section['align'] }}"
},
"blocks": {
@if (isset($section['items']))
@foreach ($section['items'] as $key => $item)
"column-{{ $key }}": {
"type": "column",
"settings": {
"image": "{{ @$item['image']['url'] ?: '' }}",
"mobile_image": "{{ @$item['mb_image']['url'] ?: '' }}",
"url": "{{ $item['url'] }}",
"title": "{{ @$item['url_object']['title'] ?: '' }}"
}
}@if (!$loop->last),@endif
@endforeach
@endif
}
},
@endif
{{-- 图文 --}}
@if($section['type'] === 'imagetext')
{{-- 网格 --}}
@if($section['layout_type'] === 'grid')
"{{ $id }}": {
"type": "multi-column",
"settings": {
"heading": {-- $section['title_text'] ?: '' --},
"heading_align": "{{ $section['title_aligns'] }}",
"text_color": "{{ $section['text_color_v2'] }}",
"image_size": "{{ $section['image_style'] === 'auto' ? 'auto' : 'fixed' }}",
"mask_opacity": {{ $section['opacity'] }},
"button_text_color": "{{ $section['button_text_color_v2'] }}",
"button_background_color": "{{ @$section['button_bg_color_v2'] ?: '' }}",
"text_align": "{{ $section['align'] }}"
},
"blocks": {
@if (isset($section['items']))
@foreach ($section['items'] as $key => $item)
"column-{{ $key }}": {
"type": "column",
"settings": {
"heading": {-- $item['title'] ?: '' --},
"text": {-- @$item['description'] ?:'' --},
"image": "{{ @$item['image']['url'] ?: '' }}",
"mobile_image": "{{ @$item['mobile_image']['url'] ?: '' }}",
"url": "{{ @$item['button']['url_object']['url'] }}",
"label": {-- $item['button']['text'] --}
}
}@if (!$loop->last),@endif
@endforeach
@endif
}
},
@else
{{-- 左文右图(left) --}}
{{-- 左图右文(right) --}}
"{{ $id }}": {
"type": "image-text",
"settings": {
"heading": {-- $section['title_text'] --},
"heading_align": "{{ $section['title_aligns'] }}",
"image": "{{ @$section['horizontal']['image']['url'] }}",
"image_placement": "{{ $section['layout_type'] === 'left' ? 'second' : 'first' }}",
"horizontal_align": "{{ $section['horizontal']['level_align'] }}",
"vertical_align": "{{ $section['horizontal']['vertical_align'] === 'flex-start' ? 'top' : ($section['horizontal']['vertical_align'] === 'flex-end' ? 'bottom' : 'middle') }}",
"text_color": "{{ $section['text_color_v2'] }}",
"background_color": "{{ @$section['text_bg_color_v2'] ?: '' }}"
},
"blocks": {
"heading": {
"type": "heading",
"settings": {
"heading": {-- $section['horizontal']['title'] --}
}
},
"text": {
"type": "text",
"settings": {
"text": {-- $section['horizontal']['description'] --}
}
},
"button": {
"type": "button",
"settings": {
"url": "{{ @$section['horizontal']['button']['url_object']['url'] }}",
"label": {-- $section['horizontal']['button']['text'] --},
"text_color": "{{ $section['button_text_color_v2'] }}",
"background_color": "{{ $section['button_bg_color_v2'] }}"
}
}
}
},
@endif
@endif
@endforeach
"0": {
"type": "empty"
}
}
}
3. The code of the compiled template file is as follows.
{
"sections": {
<?php $__currentLoopData = $homepage; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $id => $section): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<?php if($section['type'] === 'carousel'): ?>
"<?php echo e($id); ?>": {
"type": "carousel",
"settings": {
"loop": true,
"autoplay": true,
"height": "<?php echo e(isset($section['slide_height']) && $section['slide_height'] === 'full' ? 'full' : 'auto'); ?>",
"interval": <?php echo e($section['interval']); ?>
},
"blocks": {
<?php if(isset($section['items'])): ?>
<?php $__currentLoopData = $section['items']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
"slide-<?php echo e($key); ?>": {
"type": "slide",
"settings": {
"image": "<?php echo e(@$item['image']['url'] ?: ''); ?>",
"url": "<?php echo e($item['button']['url']); ?>",
"align": "<?php echo e($item['align']); ?>",
"title": <?php echo json_encode($item['title'], JSON_UNESCAPED_UNICODE); ?>,
"description": <?php echo json_encode($item['description'], JSON_UNESCAPED_UNICODE); ?>,
"button": <?php echo json_encode($item['button']['text'], JSON_UNESCAPED_UNICODE); ?>,
"opacity": <?php echo e($item['show_overlay'] ? (100 - $item['opacity']) : 100); ?>,
"button_background_color": "<?php echo e($item['button_background_color']); ?>",
"button_color": "<?php echo e($item['button_text_color']); ?>",
"color": "<?php echo e($item['text_color']); ?>"
}
}<?php if(!$loop->last): ?>,<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php endif; ?>
}
},
<?php endif; ?>
<?php if($section['type'] === 'collection'): ?>
"<?php echo e($id); ?>": {
"type": "main-collections",
"settings": {
"heading": <?php echo json_encode($section['title'], JSON_UNESCAPED_UNICODE); ?>
},
"blocks": {
<?php $__currentLoopData = $section['ids']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
"collection-<?php echo e($key); ?>": {
"type": "collection",
"settings": {
"id": <?php echo e($item); ?>
}
}<?php if(!$loop->last): ?>,<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
}
},
<?php endif; ?>
<?php if($section['type'] === 'product'): ?>
"<?php echo e($id); ?>": {
"type": "main-products",
"settings": {
"show_product_palette": <?php echo e(@Module::find('ProductPalette')->isEnabled() && @config('product-palette.show_position') === 'all' ? 'true' : 'false'); ?>,
"heading": <?php echo json_encode($section['title'], JSON_UNESCAPED_UNICODE); ?>,
"layout": "<?php echo e($section['layout']); ?>",
"page_size": <?php echo e($section['amount']); ?>
},
"blocks": {
<?php $__currentLoopData = $section['category']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
"collection-<?php echo e($key); ?>": {
"type": "collection",
"settings": {
"id": <?php echo e($item); ?>
}
}<?php if(!$loop->last): ?>,<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
}
},
<?php endif; ?>
<?php if($section['type'] === 'subscribe'): ?>
"<?php echo e($id); ?>": {
"type": "apps",
"blocks": {
"newsletter": {
"type": "object/Newsletter/blocks/newsletter",
"settings": {
"heading": <?php echo json_encode($section['title'], JSON_UNESCAPED_UNICODE); ?>,
"description": <?php echo json_encode($section['description'], JSON_UNESCAPED_UNICODE); ?>
}
}
}
},
<?php endif; ?>
<?php if($section['type'] === 'image'): ?>
"<?php echo e($id); ?>": {
"type": "image",
"settings": {
"heading": <?php echo json_encode($section['title'], JSON_UNESCAPED_UNICODE); ?>,
"heading_align": "<?php echo e($section['align']); ?>"
},
"blocks": {
<?php if(isset($section['items'])): ?>
<?php $__currentLoopData = $section['items']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
"column-<?php echo e($key); ?>": {
"type": "column",
"settings": {
"image": "<?php echo e(@$item['image']['url'] ?: ''); ?>",
"mobile_image": "<?php echo e(@$item['mb_image']['url'] ?: ''); ?>",
"url": "<?php echo e($item['url']); ?>",
"title": "<?php echo e(@$item['url_object']['title'] ?: ''); ?>"
}
}<?php if(!$loop->last): ?>,<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php endif; ?>
}
},
<?php endif; ?>
<?php if($section['type'] === 'imagetext'): ?>
<?php if($section['layout_type'] === 'grid'): ?>
"<?php echo e($id); ?>": {
"type": "multi-column",
"settings": {
"heading": <?php echo json_encode($section['title_text'] ?: '', JSON_UNESCAPED_UNICODE); ?>,
"heading_align": "<?php echo e($section['title_aligns']); ?>",
"text_color": "<?php echo e($section['text_color_v2']); ?>",
"image_size": "<?php echo e($section['image_style'] === 'auto' ? 'auto' : 'fixed'); ?>",
"mask_opacity": <?php echo e($section['opacity']); ?>,
"button_text_color": "<?php echo e($section['button_text_color_v2']); ?>",
"button_background_color": "<?php echo e(@$section['button_bg_color_v2'] ?: ''); ?>",
"text_align": "<?php echo e($section['align']); ?>"
},
"blocks": {
<?php if(isset($section['items'])): ?>
<?php $__currentLoopData = $section['items']; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $key => $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
"column-<?php echo e($key); ?>": {
"type": "column",
"settings": {
"heading": <?php echo json_encode($item['title'] ?: '', JSON_UNESCAPED_UNICODE); ?>,
"text": <?php echo json_encode(@$item['description'] ?:'', JSON_UNESCAPED_UNICODE); ?>,
"image": "<?php echo e(@$item['image']['url'] ?: ''); ?>",
"mobile_image": "<?php echo e(@$item['mobile_image']['url'] ?: ''); ?>",
"url": "<?php echo e(@$item['button']['url_object']['url']); ?>",
"label": <?php echo json_encode($item['button']['text'], JSON_UNESCAPED_UNICODE); ?>
}
}<?php if(!$loop->last): ?>,<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
<?php endif; ?>
}
},
<?php else: ?>
"<?php echo e($id); ?>": {
"type": "image-text",
"settings": {
"heading": <?php echo json_encode($section['title_text'], JSON_UNESCAPED_UNICODE); ?>,
"heading_align": "<?php echo e($section['title_aligns']); ?>",
"image": "<?php echo e(@$section['horizontal']['image']['url']); ?>",
"image_placement": "<?php echo e($section['layout_type'] === 'left' ? 'second' : 'first'); ?>",
"horizontal_align": "<?php echo e($section['horizontal']['level_align']); ?>",
"vertical_align": "<?php echo e($section['horizontal']['vertical_align'] === 'flex-start' ? 'top' : ($section['horizontal']['vertical_align'] === 'flex-end' ? 'bottom' : 'middle')); ?>",
"text_color": "<?php echo e($section['text_color_v2']); ?>",
"background_color": "<?php echo e(@$section['text_bg_color_v2'] ?: ''); ?>"
},
"blocks": {
"heading": {
"type": "heading",
"settings": {
"heading": <?php echo json_encode($section['horizontal']['title'], JSON_UNESCAPED_UNICODE); ?>
}
},
"text": {
"type": "text",
"settings": {
"text": <?php echo json_encode($section['horizontal']['description'], JSON_UNESCAPED_UNICODE); ?>
}
},
"button": {
"type": "button",
"settings": {
"url": "<?php echo e(@$section['horizontal']['button']['url_object']['url']); ?>",
"label": <?php echo json_encode($section['horizontal']['button']['text'], JSON_UNESCAPED_UNICODE); ?>,
"text_color": "<?php echo e($section['button_text_color_v2']); ?>",
"background_color": "<?php echo e($section['button_bg_color_v2']); ?>"
}
}
}
},
<?php endif; ?>
<?php endif; ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
"0": {
"type": "empty"
}
}
}
4. Decided to skip the step of compiling the PHP Blade file to the PHP template file, but manually adjust it to the compiled format, and then remove the Blade syntax in it. The following is a compiled example of Blade format. as shown in Figure 2
5. The following is an example after removing the Blade syntax. All variables involved like $__env have been deleted. as shown in Figure 3
6. Decide to write a simple code block first to verify the feasibility of the technical solution. If feasible, try to execute the block of code generated by step 5.
{
<?php $items = [1, 2, 3]; ?>
<?php if(isset($items)): ?>
<?php $count = count($items); foreach($items as $key => $item): $count--; ?>
"slide-<?php echo $key; ?>": {
"type": "slide",
"settings": {
"image": "<?php echo $item ?: ''; ?>"
}
}<?php if($count != 0): ?>,<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
}
7. Run the file (phpcode.php) where this code is located directly, and the result is converted into a json structure, which is in line with expectations. as shown in Figure 4
{
"slide-0": {
"type": "slide",
"settings": {
"image": "1"
}
}, "slide-1": {
"type": "slide",
"settings": {
"image": "2"
}
}, "slide-2": {
"type": "slide",
"settings": {
"image": "3"
}
} }
8. Now you need to create a new PHP script, and then use the output buffer to include a PHP file into a string. Reference:https://www.php.net/manual/zh/function.include.php, create a new php file ob.php, after running, the output json structure is in line with expectations. as shown in Figure 5
<?php
$string = get_include_contents('phpcode.php');
echo $string;
function get_include_contents($filename) {
if (is_file($filename)) {
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
return false;
}
9. However, because the front-end colleagues think that the scheme of adjusting the template to PHP’s native syntax is poor readability, the workload is too large. The backend is still required to automate all the processes, and also include the process of Blade compiled into a PHP template. The final implementation is as follows
/*
$filename = $directory . '/' . substr($themeAsset->asset_key, 6);
if (Storage::disk('local')->exists($filename)) {
ob_start();
include storage_path('app') . '/' . $filename;
$contents = ob_get_contents();
ob_end_clean();
$themeAsset->schema = $contents;
$themeAsset->save();
}
*/
View::addLocation(storage_path('app') . '/' . $directory);
$filename = substr(substr($originalThemeAsset->asset_key, 0, strpos($originalThemeAsset->asset_key, '.')), 6);
$variables = $this->getBladeSchemaCompilerVariables($filename, $originalThemeInstallation->theme);
$schema = View::make($filename)->with($variables)->render();
$themeAsset->schema = $schema;
$themeAsset->save();




