We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

extending themes in Vokuro app.

Hi guys.

I am extending Vokuro app ( https://github.com/phalcon/vokuro ) to my own backend, i think it's a nice ACL solution.

My question goes to extending templates with volt. My theme i have, uses multiple js/css files in head and footer, but it's different for every site.

How can i easily replace <head> information and scripts in bottom. I have tried to do {% blocks head %} {% endblocks %} in my <head> and then using that in my template i want to have a different head but the lines was just parsed into where i have it in my template.

Vokuro is using View(); with template inheritance so there is a main file /views/index.volt and then sub pages /views/index/index.volt etc.

My /views/index.volt is this.

<!DOCTYPE html>
<html>
<head>
    <title>Minimal 1.3 - Login Page</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta charset="UTF-8" />

    <link rel="icon" type="image/ico" href="/images/favicon.ico" />
    <!-- Bootstrap -->
    {% block head %}
        <link href="/css/vendor/bootstrap/bootstrap.min.css" rel="stylesheet">
        <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
        <link rel="stylesheet" href="/css/vendor/animate/animate.min.css">
        <link type="text/css" rel="stylesheet" media="all" href="/js/vendor/mmenu/css/jquery.mmenu.all.css" />
        <link rel="stylesheet" href="/js/vendor/videobackground/css/jquery.videobackground.css">
        <link rel="stylesheet" href="/css/vendor/bootstrap-checkbox.css">
        <link rel="stylesheet" href="/css/vendor/bootstrap/bootstrap-dropdown-multilevel.css">

        <link rel="stylesheet" href="/js/vendor/rickshaw/css/rickshaw.min.css">
        <link rel="stylesheet" href="/js/vendor/morris/css/morris.css">
        <link rel="stylesheet" href="/js/vendor/tabdrop/css/tabdrop.css">
        <link rel="stylesheet" href="/js/vendor/summernote/css/summernote.css">
        <link rel="stylesheet" href="/js/vendor/summernote/css/summernote-bs3.css">
        <link rel="stylesheet" href="/js/vendor/chosen/css/chosen.min.css">
        <link rel="stylesheet" href="/js/vendor/chosen/css/chosen-bootstrap.css">

        <link href="/css/minimal.css" rel="stylesheet">

        <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
        <!--[if lt IE 9]>
        <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="//oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
        <![endif]-->
    {% endblock %}
</head>
<body class="bg-1">
{{ content() }}

</div>
<!-- Wrap all page content end -->

<section class="videocontent" id="video"></section>

<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="//code.jquery.com/jquery.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="/js/vendor/bootstrap/bootstrap.min.js"></script>
<script src="/js/vendor/bootstrap/bootstrap-dropdown-multilevel.js"></script>
<script type="text/javascript" src="/js/vendor/mmenu/js/jquery.mmenu.min.js"></script>
<script type="text/javascript" src="/js/vendor/sparkline/jquery.sparkline.min.js"></script>
<script type="text/javascript" src="/js/vendor/nicescroll/jquery.nicescroll.min.js"></script>
<script type="text/javascript" src="/js/vendor/animate-numbers/jquery.animateNumbers.js"></script>
<script type="text/javascript" src="/js/vendor/videobackground/jquery.videobackground.js"></script>
<script type="text/javascript" src="/js/vendor/blockui/jquery.blockUI.js"></script>

<script src="/js/vendor/flot/jquery.flot.min.js"></script>
<script src="/js/vendor/flot/jquery.flot.time.min.js"></script>
<script src="/js/vendor/flot/jquery.flot.selection.min.js"></script>
<script src="/js/vendor/flot/jquery.flot.animator.min.js"></script>
<script src="/js/vendor/flot/jquery.flot.orderBars.js"></script>
<script src="/js/vendor/easypiechart/jquery.easypiechart.min.js"></script>

<script src="/js/vendor/rickshaw/raphael-min.js"></script>
<script src="/js/vendor/rickshaw/d3.v2.js"></script>
<script src="/js/vendor/rickshaw/rickshaw.min.js"></script>

<script src="/js/vendor/morris/morris.min.js"></script>

<script src="/js/vendor/tabdrop/bootstrap-tabdrop.min.js"></script>

<script src="/js/vendor/summernote/summernote.min.js"></script>

<script src="/js/vendor/chosen/chosen.jquery.min.js"></script>

<script src="/js/minimal.min.js"></script>

<script>
$(function(){

    // Initialize card flip
    $('.card.hover').hover(function(){
        $(this).addClass('flip');
    },function(){
        $(this).removeClass('flip');
    });

    // Initialize flot chart
    var d1 =[ [1, 715],
        [2, 985],
        [3, 1525],
        [4, 1254],
        [5, 1861],
        [6, 2621],
        [7, 1987],
        [8, 2136],
        [9, 2364],
        [10, 2851],
        [11, 1546],
        [12, 2541]
    ];
    var d2 =[ [1, 463],
        [2, 578],
        [3, 327],
        [4, 984],
        [5, 1268],
        [6, 1684],
        [7, 1425],
        [8, 1233],
        [9, 1354],
        [10, 1200],
        [11, 1260],
        [12, 1320]
    ];
    var months = ["January", "February", "March", "April", "May", "Juny", "July", "August", "September", "October", "November", "December"];

    // flot chart generate
    var plot = $.plotAnimator($("#statistics-chart"),
            [
                {
                    label: 'Sales',
                    data: d1,
                    lines: {lineWidth:3},
                    shadowSize:0,
                    color: '#ffffff'
                },
                { label: "Visits",
                    data: d2,
                    animator: {steps: 99, duration: 500, start:200, direction: "right"},
                    lines: {
                        fill: .15,
                        lineWidth: 0
                    },
                    color:['#ffffff']
                },{
                label: 'Sales',
                data: d1,
                points: { show: true, fill: true, radius:6,fillColor:"rgba(0,0,0,.5)",lineWidth:2 },
                color: '#fff',
                shadowSize:0
            },
                { label: "Visits",
                    data: d2,
                    points: { show: true, fill: true, radius:6,fillColor:"rgba(255,255,255,.2)",lineWidth:2 },
                    color: '#fff',
                    shadowSize:0
                }
            ],{

                xaxis: {

                    tickLength: 0,
                    tickDecimals: 0,
                    min:1,
                    ticks: [[1,"JAN"], [2, "FEB"], [3, "MAR"], [4, "APR"], [5, "MAY"], [6, "JUN"], [7, "JUL"], [8, "AUG"], [9, "SEP"], [10, "OCT"], [11, "NOV"], [12, "DEC"]],

                    font :{
                        lineHeight: 24,
                        weight: "300",
                        color: "#ffffff",
                        size: 14
                    }
                },

                yaxis: {
                    ticks: 4,
                    tickDecimals: 0,
                    tickColor: "rgba(255,255,255,.3)",

                    font :{
                        lineHeight: 13,
                        weight: "300",
                        color: "#ffffff"
                    }
                },

                grid: {
                    borderWidth: {
                        top: 0,
                        right: 0,
                        bottom: 1,
                        left: 1
                    },
                    borderColor: 'rgba(255,255,255,.3)',
                    margin:0,
                    minBorderMargin:0,
                    labelMargin:20,
                    hoverable: true,
                    clickable: true,
                    mouseActiveRadius:6
                },

                legend: { show: false}
            });

    $(window).resize(function() {
        // redraw the graph in the correctly sized div
        plot.resize();
        plot.setupGrid();
        plot.draw();
    });

    $('#mmenu').on(
            "opened.mm",
            function()
            {
                // redraw the graph in the correctly sized div
                plot.resize();
                plot.setupGrid();
                plot.draw();
            }
    );

    $('#mmenu').on(
            "closed.mm",
            function()
            {
                // redraw the graph in the correctly sized div
                plot.resize();
                plot.setupGrid();
                plot.draw();
            }
    );

    // tooltips showing
    $("#statistics-chart").bind("plothover", function (event, pos, item) {
        if (item) {
            var x = item.datapoint[0],
                    y = item.datapoint[1];

            $("#tooltip").html('<h1 style="color: #418bca">' + months[x - 1] + '</h1>' + '<strong>' + y + '</strong>' + ' ' + item.series.label)
                    .css({top: item.pageY-30, left: item.pageX+5})
                    .fadeIn(200);
        } else {
            $("#tooltip").hide();
        }
    });

    //tooltips options
    $("<div id='tooltip'></div>").css({
        position: "absolute",
        //display: "none",
        padding: "10px 20px",
        "background-color": "#ffffff",
        "z-index":"99999"
    }).appendTo("body");

    //generate actual pie charts
    $('.pie-chart').easyPieChart();

    //server load rickshaw chart
    var graph;

    var seriesData = [ [], []];
    var random = new Rickshaw.Fixtures.RandomData(50);

    for (var i = 0; i < 50; i++) {
        random.addData(seriesData);
    }

    graph = new Rickshaw.Graph( {
        element: document.querySelector("#serverload-chart"),
        height: 150,
        renderer: 'area',
        series: [
            {
                data: seriesData[0],
                color: '#6e6e6e',
                name:'File Server'
            },{
                data: seriesData[1],
                color: '#fff',
                name:'Mail Server'
            }
        ]
    } );

    var hoverDetail = new Rickshaw.Graph.HoverDetail( {
        graph: graph,
    });

    setInterval( function() {
        random.removeData(seriesData);
        random.addData(seriesData);
        graph.update();

    },1000);

    // Morris donut chart
    Morris.Donut({
        element: 'browser-usage',
        data: [
            {label: "Chrome", value: 25},
            {label: "Safari", value: 20},
            {label: "Firefox", value: 15},
            {label: "Opera", value: 5},
            {label: "Internet Explorer", value: 10},
            {label: "Other", value: 25}
        ],
        colors: ['#00a3d8', '#2fbbe8', '#72cae7', '#d9544f', '#ffc100', '#1693A5']
    });

    $('#browser-usage').find("path[stroke='#ffffff']").attr('stroke', 'rgba(0,0,0,0)');

    //sparkline charts
    $('#projectbar1').sparkline('html', {type: 'bar', barColor: '#22beef', barWidth: 4, height: 20});
    $('#projectbar2').sparkline('html', {type: 'bar', barColor: '#cd97eb', barWidth: 4, height: 20});
    $('#projectbar3').sparkline('html', {type: 'bar', barColor: '#a2d200', barWidth: 4, height: 20});
    $('#projectbar4').sparkline('html', {type: 'bar', barColor: '#ffc100', barWidth: 4, height: 20});
    $('#projectbar5').sparkline('html', {type: 'bar', barColor: '#ff4a43', barWidth: 4, height: 20});
    $('#projectbar6').sparkline('html', {type: 'bar', barColor: '#a2d200', barWidth: 4, height: 20});

    // sortable table
    $('.table.table-sortable th.sortable').click(function() {
        var o = $(this).hasClass('sort-asc') ? 'sort-desc' : 'sort-asc';
        $('th.sortable').removeClass('sort-asc').removeClass('sort-desc');
        $(this).addClass(o);
    });

    //todo's
    $('#todolist li label').click(function() {
        $(this).toggleClass('done');
    });

    // Initialize tabDrop
    $('.tabdrop').tabdrop({text: '<i class="fa fa-th-list"></i>'});

    //load wysiwyg editor
    $('#quick-message-content').summernote({
        toolbar: [
            //['style', ['style']], // no style button
            ['style', ['bold', 'italic', 'underline', 'clear']],
            ['fontsize', ['fontsize']],
            ['color', ['color']],
            ['para', ['ul', 'ol', 'paragraph']],
            ['height', ['height']],
            //['insert', ['picture', 'link']], // no insert buttons
            //['table', ['table']], // no table button
            //['help', ['help']] //no help button
        ],
        height: 143   //set editable area's height
    });

    //multiselect input
    $(".chosen-select").chosen({disable_search_threshold: 10});

})

</script>
</body>
</html>

And this is the main file i want to extend in my other templates.

Like my 404/505 and login screen is different than that main file.

i apologize for the code view, it didn't work properly when i used the markup.



58.4k

hey

you want to add login page, in controller login you can use code

this->view->pick('login/index');

with login is folder



21.1k

Vokuro generate forum with $this->view->form = $form;

But i will try to use pick() with the 404/500 error.

hey

you want to add login page, in controller login you can use code

this->view->pick('login/index');

with login is folder



58.4k

You can used example https://github.com/duythien/blog, i used vokuro app



43.9k
Accepted
answer

Hi,

you have defined all your assets ressources in the main layout file : view/index.volt

Are you sure you need this bunch of css and js on ALL your pages ?

How can i easily replace <head> information and scripts in bottom

phalcon's asset manager can help you for solving your question and for loading ressources when needed (on controller action level per example)



21.1k

Hi, i just tried pick() in my controllerBase with the error message.

if (!is_array($identity)) {

                $this->flash->notice('You don\'t have access to this module: private');

                /*$dispatcher->forward(array(
                    'controller' => 'index',
                    'action' => 'index'
                ));*/
                $this->view->pick('index/500');
                return false;
            }

But didn't help.

hey

you want to add login page, in controller login you can use code

this->view->pick('login/index');

with login is folder



21.1k

Thanks Le51.

It is actually a good solution :)

But i have this problem now, https://forum.phalcon.io/discussion/459/assets-management do you know a solution for that?

Hi,

you have defined all your assets ressources in the main layout file : view/index.volt

Are you sure you need this bunch of css and js on ALL your pages ?

How can i easily replace <head> information and scripts in bottom

phalcon's asset manager can help you for solving your question and for loading ressources when needed (on controller action level per example)