Passing variable to layout template in Mojolicious - perl

I am trying to set the refresh rate of a status page using a stash variable
So I have the following code in the controller to render the page:
my $refreshrate = 10;
$self->stash( refreshrate => $refreshrate);
$self->render();
in the html template I have:
% layout 'refreshLayout', title => 'A title';
% content_for refresh => begin
% end
<div>....body content .../<div>
and in the layout template I have:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta charset="UTF-8"/>
<meta http-equiv="refresh" content="<%= refreshrate %>"/>
.....
<title><%= title %></title>
</head>
<body><%= content %></body>
</html>
I always end up with a page rendered with no value in the content attribute of the refresh meta tag.
It looks like the refreshrate replacement does not work.
However both the content and title replacements do work.
So what am I doing wrong here?
And while we are here, why in the layout template do we do use <%= content %> (and not $content)
While in the template of the regular page we use the more logical <%= $variable %>
How does the replacement work in the layout template versus the replacement in the template of the main page?

The stash values appear as perl variables in your templates. (title is special as it's also a default helper function).
If you want to pass the stash value for refreshrate to the layout, you have to add it to your layout() args:
use Mojolicious::Lite;
get '/' => sub {
my $c = shift;
$c->stash (refreshrate => 10),
$c->render(template => 'foo/bar')};
app->start;
__DATA__
## foo/bar.html.ep
% layout 'mylayout', title => 'Hi there',refreshrate => $refreshrate;
Hello World!
## layouts/mylayout.html.ep
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
<meta charset="UTF-8"/>
<meta http-equiv="refresh" content="<%= $refreshrate %>"/>
<title><%= $title %></title></head>
<body><%= content %></body>
</html>
See Layouts in Rendering doc

Related

Sweetalert 2 i cant make this library work

Here is the problem. Sorry for stupid question.
I read how to connect this library to my project.
I use vs-code. First, i need to install npm in my project with command npm install sweetalert2 in vs-code terminal. I did that.
Next i need to add reference to sweetalert2.min.js and sweetalert2.min.css in <head>.
And call the function.
Swal.fire({
title: 'Error!',
text: 'Do you want to continue',
icon: 'error',
confirmButtonText: 'Cool'
})
I also make button with onclick function but this not work. I click button and nothing. No modal window.
Here is my code. Help to see my problem. Thank you!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="styles/style.css" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Oleo+Script+Swash+Caps&display=swap" rel="stylesheet">
<script src="/node_modules/sweetalert2/dist/sweetalert2.min.js"></script>
<link rel="stylesheet" href="/node_modules/sweetalert2/dist/sweetalert2.min.css">
<script>
function CBR_XML_Daily_Ru(rates) {
function trend(current, previous) {
if (current > previous) return ' ▲';
if (current < previous) return ' ▼';
return '';
}
var USDrate = rates.Valute.USD.Value.toFixed(4).replace('.', ',');
var USD = document.getElementById('USD');
USD.innerHTML = USD.innerHTML.replace('00,0000', USDrate);
USD.innerHTML += trend(rates.Valute.USD.Value, rates.Valute.USD.Previous);
var EURrate = rates.Valute.EUR.Value.toFixed(4).replace('.', ',');
var EUR = document.getElementById('EUR');
EUR.innerHTML = EUR.innerHTML.replace('00,0000', EURrate);
EUR.innerHTML += trend(rates.Valute.EUR.Value, rates.Valute.EUR.Previous);
}
</script>
<link rel="dns-prefetch" href="https://www.cbr-xml-daily.ru/">
<script src="https://www.cbr-xml-daily.ru/daily_jsonp.js" async></script>
</head>
<body>
<button onclick="functi()">Тест Sweetalert</button>
<div class="container-message">
<div class="mainInfo">
<h1>Что день грядующий нам готовит ? Богатство или бедность? <span class="usd-color">&#36</span></h1>
<div id="USD">Доллар США $ — 00,0000 руб.</div>
<div id="EUR">Евро € — 00,0000 руб.</div>
</div>
</div>
<script>
function functi() {
Swal.fire({
title: 'Error!',
text: 'Do you want to continue',
icon: 'error',
confirmButtonText: 'Cool'
})
}
</script>
</body>
</html>
And also attach chrome-console log console
So, i find solution.
I use cdn url from documentation <script src="//cdn.jsdelivr.net/npm/sweetalert2#11"></script>.
But this not work.
I change this url in head to <script src="https://cdn.jsdelivr.net/npm/sweetalert2#11"></script>
And it works!

how to integrate sailsjs with vuetify?

I am trying to use vuetify component like tables in my sails project. I can get the UI working fine, but all actions (button clicks) are not working unless I disable parasails for that page. Anyone has experience integrating sails with vuetify?
I followed this example:
https://github.com/ndabAP/vue-sails-example
But instead of using vue-bootstrap I did with Vuetify with the vue-cli:
vue create frontend
cd frontend
vue add vuetify
And in the vue.config.js I used:
// frontend/vue.config.js
outputDir: "../backend/assets/dependencies",
In the backend generate a controller route to index.js:
// config/routes.js
'/*': { action:'index', skipAssets: true, skipRegex: /^\/api\/v1\/.*$/ },
with the content:
// controllers/index.js
module.exports = {
friendlyName: 'View homepage',
description: 'Display homepage view',
exits: {
success: {
statusCode: 200,
description: 'Display the view index page.',
viewTemplatePath: 'pages/index'
},
},
fn: async function () {
return {};
}
};
The view layouts/layout.ejs should content:
<% /* views/layouts/layout.ejs */ %>
<!DOCTYPE html>
<html>
<head>
<title><%=typeof title == 'undefined' ? 'New Sails App' : title%></title>
<!-- Viewport mobile tag for sensible mobile support -->
<meta charset=utf-8>
<meta http-equiv=X-UA-Compatible content="IE=edge">
<meta name=viewport content="width=device-width,initial-scale=1">
<link rel=icon href=/favicon.ico>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!--STYLES-->
<!--STYLES END-->
</head>
<body>
<noscript>
<strong>We're sorry but frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id=app></div>
<!--TEMPLATES-->
<!--TEMPLATES END-->
<%- exposeLocalsToBrowser() %>
<!--SCRIPTS-->
<!--SCRIPTS END-->
</body>
</html>
And that is the better way that I figured it out. If there is another simplest way I want to know, because I think that is necessary modifying parasails.js to upload components directly or change the form of registering pages by registering components instead, using a unique page in a similar way.

Showing loader inside a dialog popup

I have made a page in UI5 in which there is a button to open the dialog popup. On this popup page, I have some text boxes and chart, but the chart is taking so much time in loading so the entire page is displayed as white screen until the chart is loaded.
I want to show some loader for this white screen. What can be the possible solution?
(I was trying for loading a text box first and then chart but the problem is entire page is loaded together)
try below code for loader.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8">
<title>Example Application</title>
<script id="util-coreloader"
src="util/CoreLoader.js"
data-loader-src="resources/sap-ui-core.js"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-resourceroots='{
"com.inwerken": "../com_inwerken"
}'
data-sap-ui-xx-bindingSyntax="complex">
</script>
<script>
// execute when Core is loaded ...
CoreLoader.onReadyState(function() {
sap.ui.getCore().attachInitEvent(function () {
// .. load Component
var oComponentContainer = new sap.ui.core.ComponentContainer({
height: "100%",
name: "Example"
});
oComponentContainer.placeAt("content");
CoreLoader.ready();
});
});
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>

How to add meta tags from widget in Orchard?

I'm trying to add some meta tags from widget (/views/parts/ folder) that gets data from database outside of orchard. I need to put them to head section, and frankly I got no idea how to achieve that.
I tried:
using (Script.Head())
{
<meta property="description" content="ABC">
}
SetMeta("ABC", "description");
But none of these work :-(
Edit: our document.cshtml code:
#using Orchard.Mvc.Html;
#using Orchard.UI.Resources;
#{
RegisterLink(new LinkEntry { Type = "image/x-icon", Rel = "shortcut icon", Href = Url.Content("~/modules/orchard.themes/Content/orchard.ico") });
string title = Convert.ToString(Model.Title);
string siteName = Convert.ToString(WorkContext.CurrentSite.SiteName);
string classForPage = "static " + Html.ClassForPage();
}
<!DOCTYPE html>
<!--[if lt IE 7]>
<html lang="#WorkContext.CurrentCulture" class="#classForPage no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>
<html lang="#WorkContext.CurrentCulture" class="#classForPage no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>
<html lang="#WorkContext.CurrentCulture" class="#classForPage no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html lang="#WorkContext.CurrentCulture" class="#classForPage no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8" />
<title>#Html.Title(title, siteName)</title>
<meta name="viewport" content="width=device-width">
#{
Display(Model.Head);
}
<meta property="og:title" content="#Layout.Title - #Convert.ToString(WorkContext.CurrentSite.SiteName)">
<meta property="og:site_name" content="#Convert.ToString(WorkContext.CurrentSite.SiteName)">
<meta property="og:url" content="#Request.Url">
<meta property="og:type" content="article">
<script>(function(d){d.className="dyn"+d.className.substring(6,d.className.length);})(document.documentElement);</script>
</head>
<body>
#Display(Model.Body)
#Display(Model.Tail)
</body>
</html>
Does anybody know how to achieve that?
IResourceManager provides the necessary methods.
For use it in view:
var resourceManager = WorkContext.Resolve<Orchard.UI.Resources.IResourceManager>();
resourceManager.SetMeta(new Orchard.UI.Resources.MetaEntry
{
Name = "description",
Content = "ABC"
});
But it can be also used in other places (e.g. part driver).
Edit
using SetMeta("description", "ABC") in view give the same results.
I used the following code in my layout.cshtml file before header tag and it worked.
#using (Script.Head())
{
<meta name="description" content="<your description>"/>
<meta name="keywords" content="<your keywords here>"/>
}
Enjoy!!!

PHP > Unable to embed youtube video by function

I don't know what's wrong with my embed script, to my logic it should properly embed the video in the frame, but it loads a framed view of www.youtube.com instead of my video video.
There are 2 files in a single directory:
ClassMedia.php:
<?php
class Media {
public function embedYT($code){
echo "<iframe width='560' height='349' src='http://www.youtube.com/embed/".$code." frameborder='0' allowfullscreen></iframe>";
}}
Demo.php:
<?php include "classMedia.php"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Demo</title>
</head>
<body>
<?php
$media = new Media();
$code = "XSGBVzeBUbk";
$media-> embedYT($code);
?>
</body>
</html>
You're missing a single quote right after src='http://www.youtube.com/embed/".$code.", you want this:
echo "<iframe width='560' height='349' src='http://www.youtube.com/embed/".$code."' frameborder='0' allowfullscreen></iframe>";
Note the added single quote.
YouTube ends up seeing a bad URL (http://www.youtube.com/embed/$code frameborder= where $code is the real code) and hands you the homepage instead of what you think you were asking for.