Put some elements from component into head tag - astrojs

I want that some tags from component to go to head tag.
I want to put in the slot named head.
How could achieve this ?
layout.astro
<html>
<head>
<slot name="head" />
</head>
<body>
<slot />
<mycomponent />
</body>
</html>
mycomponent.astro
<link .... slot="head">
<div>
...
</div>

Solution
It is possible to place a tag, but only from where you call a Layout where the single <head> is placed, using slots like this
in the Layout.astro you create a
default slot and
a named slot e.g. name="head" but you could use any name
<head>
<title>{title}</title>
<slot name="head"/>
</head>
<body>
<slot />
</body>
then in your page or in the Component that is calling the Layout
<Layout title="Welcome to Astro.">
<link slot="head" rel="icon" type="image/svg+xml" href="/favicon.svg" />
<main>
<h1>Astro</h1>
</main>
</Layout>
Clarifications
The slot concept is independent from the Layout and head
The Layout component can have any name and can be used from any component
In Astro there can be only one single <head> element per page, all other used <head> tags will stay where they are and will not be moved by the compiler to the main top <head>
A page and all of its children components can use the slot concept to fill it tags inside the single parent <head> tag via slots
This only works if the component directly includes the component e.g. Layout that is providing the slots
References
Note : The reference below from the Astro Documentation website recommends to "place the single <head> and its contents in a layout component."
https://docs.astro.build/en/guides/troubleshooting/#using-head-in-a-component
named slots :https://docs.astro.build/en/core-concepts/astro-components/#named-slots

Related

Spring and Thymeleaf Fragments

I am developing a Spring Boot application and using Thymeleaf Templating. I am new to this and need a little guidance. I have a index.html file which is the main view which should be displayed. Inside the index.html file i have two fragments, a header and a footer which display as well. What i am having trouble with is inserting more fragments into the index.html file. I want to insert another fragment which displays a navigation top bar as well as a second fragment that displays a side navigation menu. I am looking to include the topnavbar right below the header fragment and the side nav menu on the left side of screen. How do i go about doing this? Thank you.
Index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head lang="en">
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous"/>
<link rel="stylesheet" href="../static/css/main.css"
th:href="#{css/main.css}" media="screen"/>
<title>Spring Boot | Web Application</title>
</head>
<body>
<div class="container">
<div class="row" th:include="header :: banner"></div>
<div class="row">
<div class="col-sm-3"><hr /></div>
<div class="col-sm-9 text-center">col-sm-8</div>
</div>
<div class="row">
<div class="col-sm-12"><hr /></div>
</div>
<div class="row" th:include="footer :: copy"></div>
</div>
<!-- jQuery, Popper.js, Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/js/bootstrap.min.js" integrity="sha384-a5N7Y/aK3qNeh15eJKGWxsqtnX/wWdSZSKp+81YjTmS15nvnvxKHuzaWwXHDli+4" crossorigin="anonymous"></script>
</body>
</html>

Use different css or java script per page with freemarker

Using FreeMarker, I would like to be able to load different stylesheets or javascript files in different templates. My problem may be in my implementation.
I have a single layout macro which looks like this:
<#macro layout>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- common javascript and css references here -->
</head>
<body>
<div class="container">
<!-- header stuff -->
<#nested>
<!-- footer stuff -->
</div>
</body>
</html>
</#macro>
I use this in all templates like this:
<!-- "declare" specific css or js here -->
<#layout.layout>
<div id="mapid">
<!-- use specific css or js -->
</div>
</#layout.layout>
In some of my templates I would like to use specific stylesheets or javascript libraries that apply to the common case. What is the best approach for this?
I've tried passing variable in to the layout macro to insert the css and js references but I've found no easy way to assign a block of text using #assign.
You can declare nested tags and send as a parameter the name like this:
layout.ftl
<#macro layout>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- common javascript and css references here -->
<#nested "styles">
<#nested "scripts">
</head>
<body>
<div class="container">
<!-- header stuff -->
<#nested "content">
<!-- footer stuff -->
</div>
</body>
</html>
</#macro>
And then you can receive as a parameter the section and use an if like this:
page.ftl
<#layout.layout; section>
<#if section = "scripts">
<script src="/js/myscripts/myfile.js"></script>
</#if>
<#if section = "styles">
<link rel="stylesheet" href="/css/style.css" />
</#if>
<#if section="content">
<div id="mapid">
</div>
</#if>
</#layout.layout>
I separated the layout into page start end page end, and define the nested in page start.
page_start.ftl
<#macro external>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>${title}</title>
<meta name="keywords" content="${keyword}">
<meta name="description" content="${description}">
<link href="https://cdn.insdep.com/themes/1.0.0/easyui.css" rel="stylesheet" type="text/css">
<link href="https://cdn.insdep.com/themes/1.0.0/easyui_animation.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="https://cdn.insdep.com/jquery/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="https://cdn.insdep.com/easyui/jquery.easyui-1.5.1.min.js"></script>
<#nested >
</head>
<body>
<#include "global/header.ftl">
<#include "global/sidebar.ftl">
</#macro>
page_end.ftl
<#include "global/footer.ftl">
</body>
</html>
<#import "page_start.ftl" as page>
<#page.external>
<link href="https://cdn.insdep.com/themes/1.0.0/easyui_plus.css" rel="stylesheet" type="text/css">
</#page.external>
hello world
<#include "page_end.ftl">
But I do think, this is not a very decent solution.

Blade passing values from view to master and then pass it to header.blade

I have a situation where i have a view file users.blade.php which extends master. and the master includes another file called header.blade.php, i want to pass some data from users.blade to header.blade.
Here is the simplified version of the files
/****** Users.blade.php *********/
#extends('shared.master')
#section('title', 'Dashboard')
#section('pagecss')
<link rel="stylesheet" href="links to css file" />
#endsection
Here is the master.blade.php
/******Shared/master.blade.php ********/
<html>
<head>
<title>#yield('title')</title>
#include('shared.header')
</head>
<body >
#yield('content')
</body>
</html>
Here is the header file
/******Shared/header.blade.php ********/
<link rel="stylesheet" href="links to bootstrap" />
#yield('pagecss')
<link rel="stylesheet" href="links to other files" />
#yield('pagecss') doesn't work in the header.blade, but it does work in master.blade. Now i cant paste it in master.blade because there are some files which override other files, so it has to be in a specific order. Any ideas how to make the yield work in header.blade?
EDIT:
I do like Bharat Geleda approach, i have modified the code to include some heredocs to make it more convenient. But i think its kind of a hack and still looking for a better solution.
/********** Users.blade.php ***********/
#extends('shared.master')
#section('title', 'Dashboard')
#section('pagecss')
<link rel="stylesheet" href="links to css file" />
#endsection
<?php $pagecss = <<<CSS_FILES
<link rel="stylesheet" href="links to page css" />
CSS_FILES;
?>
/*********** Shared/header.blade.php **********/
#if(isset($pagecss))
{{-- */ echo $pagecss;/* --}}
#endif
A possible solution would be to do this
<?php $pagecss = '<link rel="stylesheet" href="links to css file" />'?>
/****** Users.blade.php *********/
#extends('shared.master')
#section('title', 'Dashboard')
master.blade.php would remain the same
/******Shared/master.blade.php ********/
<html>
<head>
<title>#yield('title')</title>
#include('shared.header')
</head>
<body >
#yield('content')
</body>
</html>
And then in your header file you could do this
/******Shared/header.blade.php ********/
<link rel="stylesheet" href="links to bootstrap" />
#if(isset($pagecss))
{{ $pagecss }}
#endif
<link rel="stylesheet" href="links to other files" />
EDIT: TESTING OUT QUESTION
main.blade.php (master in your case)
<html>
<head>
#include('test.header')
</head>
<body >
#yield('content')
</body>
</html>
header.blade.php
<link rel="stylesheet" href="links to bootstrap" />
#yield('pagecss')
<link rel="stylesheet" href="links to other files" />
users.blade.php
#extends('test.main')
#section('content')
CONTENT
#endsection
#section('pagecss')
<link rel="stylesheet" href="links to css file" />
#endsection
OUTPUT :
<html>
<head>
<link rel="stylesheet" href="links to bootstrap" />
<link rel="stylesheet" href="links to css file" />
<link rel="stylesheet" href="links to other files" />
</head>
<body >
CONTENT
</body>
</html>
I guess this is as expected.
Simple if it's working on homepage and not in inner views, that means you've used it, and Blade will take only the higher level and resolve it (include its content where it should be placed within #yield).
What I'm trying to say that if you got a #yield within your header file and you've used it as #section('pagecss') later you got another view as in your case Users.blade.php with the same statement #section('pagecss') blade won't take the inner one.
Solution
Nice way but foolish:
create another #yield within your shared header blade file and name it as level two or like so. i.e #yield('pagecss-2')
Good way:
using #parent, this directive is going to append (rather than overwriting) content to the layout
as mentioned here within docs of laravel

schema.org VideoObject → itemprop will not validate with W3C Validator

I am using the schema.org VideoObject for video on my webpages. However when I run the W3C Validator I get the following errors for each property:
The itemprop attribute was specified, but the element is not a property of any item.
This occurs for every item property show below:
<div class="video-wrapper-inner" itemprop="video" itemscope itemtype="http://schema.org/VideoObject">
<meta itemprop="name" content="Name of the Video" />
<meta itemprop="description" content="Description of the Video. " />
<meta itemprop="thumbnailUrl" content="../images/thumbnail.jpg" />
<meta itemprop="embedURL" content="http://player.vimeo.com/external/123456.hd.mp4?s=ddddd44ssdd43d23rf" />
<meta itemprop="duration" content="T1M10S" />
<meta itemprop="uploadDate" content="2013-12-26T08:00:00+08:00" />
<meta itemprop="transcript" content="Transcript from the video here." />
<video poster="../images/thumbnail.jpg" controls><source src="http://video file location" type='video/mp4;codecs="avc1.42E01E, mp4a.40.2"' /></video>
</div>
By the way my web page is set up as follows:
<!DOCTYPE html>
<html lang="en">
My question is, what is the correct markup to pass the W3C Validator.
The W3C Markup Validator complains because you use the video property on the div (VideoObject).
(See this question if this is an error at all: Is 'itemprop' without parent 'itemscope' valid? Does it create an item?)
Do you have a parent item that references this VideoObject via the video property? If so, add it to your page and validate again (the error should be gone). If you don’t have such a parent item, you could probably remove this property.

Ajax.BeginForm redirect instead of replacing div container [duplicate]

My Search.cshtml has a div named "search-results" that is to be updated. SearchResults is the action name. I have done this many times on MVC2/VS2008 projects, but this is my first using MVC3 and VS2010.
The problem is, instead of my search result being rendered in my div, it clicking submit is redirecting me displaying my partial as a standalone page.
I have read that this may be because Ajax is not enabled. My _Layout.cshtml looks like this:
<!DOCTYPE html>
<html>
<head>
<title>#ViewBag.Title</title>
<script src="#Url.Content("~/Scripts/2011.2.712/jquery-1.5.1.min.js")" type="text/javascript"></script>
<link href="#Url.Content("~/Content/themes/base/jquery.ui.core.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/themes/base/jquery.ui.datepicker.css")" rel="stylesheet"  type="text/css" />
<link href="#Url.Content("~/Content/themes/base/jquery.ui.theme.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/main.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/2011.2.712/jquery-1.5.1.min.js")" type="text/javascript"></script>
#(Html.Telerik().StyleSheetRegistrar().DefaultGroup(group => group.Add("telerik.common.css").Add("telerik.transparent.css").Combined(true).Compress(true)))
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>My MVC Application</h1>
</div>
#(Html.Telerik().Menu()
.Name("menu")
.Items(menu => {
menu.Add().Text("Home").Action("Index", "Home");
menu.Add().Text("About").Action("About", "Home");
menu.Add().Text("Employees").Action("List", "Employee");
}))
</div>
<div id="main">
#RenderBody()
<div id="footer">
</div>
</div>
</div>
#(Html.Telerik().ScriptRegistrar().DefaultGroup(group => group.Combined(true).Compress(true)))</body>
</html>
Do I need to add MicrosoftMvcAjax.js or jquery.unobtrusive-ajax.js in? My web.config (root) contians the following:
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
If I add MicrosoftMvcAjax.js in at the end of the element, I get an error sayning namespace 'Type' is undefined error from the first line of MicrosoftMvcAjax.js:
Type.registerNamespace('Sys.Mvc');Sys.Mvc.$create_AjaxOptions=function(){return {};}
What am I missing here. I am sure my code is fine, as it copied alsmost verbatim from my MVC2 projects.
You forgot to include the jquery.unobtrusive-ajax.js script to your page (adjust the path as necessary):
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
As far as Microsoft*.js scripts are concerned, they are obsolete in ASP.NET MVC 3 and should no longer be used unless you are porting some legacy application. They have been replaced by jQuery.
Ok, figured out my problem.
I was calling Ajax.BeginForm with the AjaxOption OnSuccess pointint to a js function that updated my place holder. But this is not needed, with unobtrusive. Once I removed the OnSucces from the Ajax options everything started working.
~S

Resources