Part of Thymeleaf fragment included only once - thymeleaf

I have a Thymeleaf fragment like this
<div th:fragment="f1">
<script src="x.js"></script>
<div> ... </div>
</div>
The script part I want to include it only once, even though I will include f1 more than once in the page.
What's the easiest/cleanest way to achieve this?
I can even split this fragment into two fragments and then the problem will be reduced on how to include a fragment only once in a page.
It can be somehow done if we'll be able to manipulate the request attributes from Thymeleaf. I understand that Thymeleaf if for rendering only, but a feature like this could be useful. Even to have something like include-once or if the included fragment has an id(or th:id) attribute, to include it only once.

use #ids.
<div th:fragment="f1">
<script src="x.js" th:if="${#ids.seq('f1.script.') == 'f1.script.1'}"></script>
hello
</div>
or
<div th:fragment="f1">
<script src="x.js" th:if="${#ids.next('f1.script.') == 'f1.script.1'}" th:id="${#ids.seq('f1.script.')}"></script>
hello
</div>

Related

THYMELEAF - FRAGMENT TAG REMOVED

I'm trying to replace a tag with a fragment of a template. After the inclusion, some part of the HTML code is removed
In my root page, I have
<p th:replace="mycomponent::firstFragment" th:with="myVar=#{'Hello'}"></p>
in my template I have
<p th:fragment="firstFragment" th:utext="#{someText}"><span th:utext="${myVar}"></span></p>
<p th:fragment="secondFragment" th:utext="#{someOtherText}"><span ></span>${otherVar}</p>
The outcome is only the p element of the fragment without the inside span. I've tried with th:inline="text" but maybe I used it in a wrong way
you can try th:include code. example .....
<span th:include="fragments/navbar::navbarPortion" th:remove="tag"/>

Umbraco 7 - How to allow users to add new content fields on-the-fly?

I'm setting up Umbraco 7.7 for the first time and creating the document types and templates for a page that displays the people that work at our organization (includes their names, photos, and bios).
How do I configure it such that the content manager can add another "person"—effectively a cluster of divs with user-editable images and text—without having to manually add another "person" to the template? Using Partial Views seems like part of the solution, but I'm unclear on how to fit it all together.
My template (simplified) currently looks something to the effect of:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
Layout = null;
}
<!doctype html>
<html>
<body>
<div class="person-bio">
<img src="/media/person-01-photo.jpg">
<p>#Umbraco.Field("person-01-name")</p>
<p>#Umbraco.Field("person-01-title")</p>
<p>#Umbraco.Field("person-01-bio")</p>
</div>
<div class="person-bio">
<img src="/media/person-02-photo.jpg">
<p>#Umbraco.Field("person-02-name")</p>
<p>#Umbraco.Field("person-02-title")</p>
<p>#Umbraco.Field("person-02-bio")</p>
</div>
<div class="person-bio">
<img src="/media/person-03-photo.jpg">
<p>#Umbraco.Field("person-03-name")</p>
<p>#Umbraco.Field("person-03-title")</p>
<p>#Umbraco.Field("person-03-bio")</p>
</div>
<!-- etc., etc. -->
</body>
</html>
Thank you! Any help would be much appreciated.
You'll probably will want to use the Nested Content control for this. It allows you to add a list of entities (in your case persons) on a document
More documentation about the nested content control can be found here: https://our.umbraco.com/documentation/getting-started/backoffice/Property-Editors/Built-in-Property-Editors/Nested-Content
So from my understanding you don't need a partial view. If it's that simple and you want to output only the div I see you're repeating, then loop it:
#foreach (var person in whateverYourCollectionIs) {
<div class="person-bio">
<img src="/media/person-01-photo.jpg">
<p>#person.GetPropertyValue<string>("pseudoNameFieldAlias")</p>
<p>#person.GetPropertyValue<string>("pseudoTitleFieldAlias")</p>
<p>#person.GetPropertyValue<string>("pseudoBioFieldAlias")</p>
</div>
}
That loop will create the exact same html for each person, but with the appropriate names, Titles, Bio etc. This is not the actual code you get to use but it hopefully leads you to the correct direction.
This is the documentation that will help

I have two divs with the same class and ID.how do I use within, so that I can simulate clicks?

I work on a Rails project that uses Capybara for front end testing. I ended up in a situation where I have duplicate div tags with the same ID. How can I use capybara scoping so that I select only one of them and perform my tests within that div?
Given the html
<div id="wrapper1">
<div id="conflict">...</div>
</div>
<div id="wrapper2">
<div id="conflict">...</div>
</div>
then you should be able to do
within("#wrapper1") do
find("#conflict") # will find the matching element inside the wrapper1 div
end
However you really should just fix the HTML and any JS that uses those divs, since it is technically illegal HTML which can cause any number of unpredictable behaviors

Why does my Recipe need a url?

I am testing my Schema with Google's Rich Text tool1, and it keeps telling me that my Recipe item needs a url property.
The documentation states:
Errors indicate either missing required fields or syntax errors.
The error that I get is that the field url is empty and shouldn't be. However, I have no idea what I should fill in. I mean, obviously the tool expects a URL, but - semantically - whereto should that URL go? What if I don't have a URL to point to?
If I decide to leave the supposedly required field empty, does that mean that the complete Recipe will not be a valid Schema? Or simply that it's missing a field?
<body itemscope itemtype="http://schema.org/WebPage">
<main>
<header itemscope itemtype="http://schema.org/Country" itemprop="about">
<h1 itemprop="name">France</h1>
<p>
<span class="capital" title="Capital" itemprop="containsPlace">Paris</span>
<span title="Member of the EU since 1958" itemprop="additionalProperty" itemscope itemtype="http://schema.org/PropertyValue">
<meta itemprop="name" content="Member of the EU since">
<span itemprop="value" class="member-since">1958</span>
</span>
</p>
</header>
<div itemprop="mainEntity" itemscope itemtype="http://schema.org/ItemList">
<meta itemprop="description" content="Recipes that are particular for France">
<article class="recipe loading" id="recipe-1" data-recipe="" itemref="img-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/Recipe">
<meta itemprop="position" content="1">
<aside class="media">
<img itemprop="image" id="img-0" src="https://s-media-cache-ak0.pinimg.com/originals/ef/4c/5c/ef4c5c0b008d11710caa7a10f502d288.jpg">
<div itemscope itemtype="http://schema.org/VideoObject" class="youtube">
<a itemprop="contentUrl" href="https://www.youtube.com/watch?v=fHgULHwyZJo" title="Watch a video on how to make Eclair">
<meta itemprop="name" content="Making éclairs">
<meta itemprop="uploadDate" content="2016-07-12">
<meta itemprop="description" content="In this video you'll learn how to make éclairs">
<img itemprop="thumbnailUrl" src="https://i.ytimg.com/vi/fHgULHwyZJo/maxresdefault.jpg" alt="Eclairs tutorial">
</a>
<iframe href="https://www.youtube.com/watch?v=fHgULHwyZJo" title="YouTube video player" frameborder="0" allowfullscreen="1" width="640" height="360" src="https://www.youtube.com/embed/fHgULHwyZJo?enablejsapi=1&autoplay=1&modestbranding=1&rel=0&showInfo=0&origin=http%3A%2F%2Flocalhost&widgetid=1"></iframe>
</div>
</aside>
<div class="text">
<div class="wiki-text">
<h1 itemprop="name">Eclairs</h1>
<p itemprop="description">An éclair is an oblong pastry made with choux dough filled with a cream and topped with icing. The dough, which is the same as that used for profiterole, is typically piped into an oblong shape with a pastry bag and baked until it is crisp and hollow
inside. </p>
<p class="read-more">For more information about <span class="recipe-name">Éclair</span>, read the Wiki.</p>
</div>
<div class="rating" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
Rated <span itemprop="ratingValue">3.5</span>/5 based on <span itemprop="reviewCount">11</span> customer reviews
</div>
<div class="cooking">
<h2>Bake it yourself!</h2>
<div>
<meta itemprop="cookTime" content="PT50M">
<span>Bake time: 50 minutes</span>
</div>
</div>
</div>
</article>
</div>
</main>
</body>
1 Related question: Defining a relationship between a country and a recipe with Schema
The error shown in Google’s SDTT doesn’t mean that you have an actual error in your Schema.org markup (as not providing the url property is perfectly fine). It’s checking if your markup conforms to Google’s guidelines for their Recipes rich card. If you don’t care about it, you don’t have to do anything.
If you care about the Recipes rich card:
Google requires the url property for each ListItem (i.e., each Recipe) in a list of recipes:
ListItem.url
URL, required
The canonical URL of the item page. Every item should have a unique URL.
While you could achieve "unique URL[s]" with fragments (like #recipe-2, #recipe-3 etc.), the guideline says "item page", so Google seems to want to see a dedicated page per recipe.
However, their more general Mark Up Your Lists documentation describes the "Combined" way to mark up host-specific lists, which allows this (bold emphasis mine):
When multiple recipes are on a single page, use list page markup that both itemizes the data types and exposes their properties in the item field.
In this case, be sure to include a unique URL for each item, which in this case might include an anchor tag.
So if this also applies to their Recipes rich card, it might work in your case to provide the fragment as URL:
<article id="recipe-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/Recipe http://schema.org/ListItem">
<link itemprop="url" href="#recipe-1" />
<!-- … -->
</article>
<article id="recipe-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/Recipe http://schema.org/ListItem">
<link itemprop="url" href="#recipe-2" />
<!-- … -->
</article>
The URL parameter should contain the base web address at which your item can be viewed using a browser.
This parameter is of great importance in indexing your content by smart content tools and search bots, like Google. Once you provide it, Google will be able to link any reference to your item to the declared URL.
This param is important when your web-app serves the same content at different addresses for different devices. By providing the same URL parameter, you can avoid any eventual penalty for duplicated content.
The URL parameter is usually the base (un-prettified) version of your permalinks, especially when using popular website engines like WordPress, where you can change your permalinks structure, but the base url scheme (usually in the form of /?p=id - where id is the id of the article) will always work. This way you can make sure that, even if you decide to change the permalinks structure after a while, your ranking and indexing for that content will not be hurt, because the declared URL will remain unchanged and older links to it will work, regardless of your pretty-permalinks current scheme.
Declared URL parameter also avoids another common problem for indexing services:
For example, if you provide a link for your monthly featured recipe, if the search engine indexes the current recipe with the "this months hot recipe link", when people will be looking for it (based on the indexed text or ingredients) next month, they'll find another recipe, which would not be what they are looking for, so they will hit the back button snappish, thus:
not finding what they were looking for, although it is on your website and
hurting your ranking, because Google monitors user behavior and whenever they go back, it clearly means the currently indexed content is wrong for that search.
Providing a URL for the recipe will allow the search engine to index and link it correctly so people who want to see it can see it and so that your ranking goes up while they spend time on your website reading the recipe or when bookmarking it.

Can I simplify this code with an HTML Helper?

I have the following code on my web pages:
<div class="rep_tb0" id="Activity" style="display:none;">
<div class="rep_tr0">
<div class="rep_td0" id="ActivityLog">Activity Log<br /><br /></div>
</div>
</div>
It's repeated for many pages and I would like to just code it once in one place. Can anyone tell me what are my options for doing this. Can I code an HTML Helper or is there a better / another way of doing this?
I think you need to use a partial in this case. Just create a .cshtml file and put that code in. Then call
#Html.Partial("PartialName");
Yes, build an HTML helper by creating an extension method. It's a lot easier than you think.
Check out this article:
http://weblogs.asp.net/jgalloway/archive/2011/03/23/comparing-mvc-3-helpers-using-extension-methods-and-declarative-razor-helper.aspx
Or this article:
http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs

Resources