I'm new to Umbraco 7 and MVC. I have added a property called 'teaser' to the media file type. When I upload a media file, the back office interface recognizes the new property and allows me to set its value.
I am, however, unable to figure out how to access that value for use in the interface. Here's the code:
#if (CurrentPage.HasValue("audioFiles")) {
var audioIdList = CurrentPage.audioFiles.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
var audioList = Umbraco.TypedMedia(audioIdList);
<ul class="audioFileList"> #{
foreach (var af in audioList) {
<li>
#af.Name<br />
#af.teaser;
</li>
}
}
</ul>
}
When I run this code, it throws an error saying that "'Umbraco.Web.Models.PublishedContentBase' does not contain a definition for 'teaser'". The Url and the Name are retrieved just fine. It's only the added 'teaser' that's a problem.
Thanks - Jon
try this:
#af.GetPropertyValue("teaser")
You can only use af.teaser if you are using the dynamic "CurrentPage" object. In this case you inherit from a TypedList which gives you strongly typed .Net objects. These do not contain your custom properties.
If you like the dynamics more, you should replace var audioList = Umbraco.TypedMedia(audioIdList); by var audioList = Umbraco.Media(audioIdList);. This will give you a dynamic object.
Related
I am trying to get all the innertext from a list of "li"-elements. It seems I am hitting something, there are 19 elements in the variable has, but I don't know how to pick out the actual innertext values:
string xpath = "//h1[#title='UL']//li";
IElementHandle[] has = await ((IPage)pageTabel).XPathAsync(xp);
IJSHandle ha = has[0].GetPropertiesAsync("value");
I think e.g.
foreach (var listItem in has)
{
Console.WriteLine((await listItem.GetPropertyAsync("textContent")).RemoteObject.Value.ToString());
}
would work. I don't know whether browser's also implement the (originally IE only) innerText property, if they do then of course above doing GetPropertyAsync("innerText") instead should also work.
If you'd prefer a strongly typed experience then PuppeteerSharp.Dom provides a set of extensions to PuppeteerSharp.
Install PuppeteerSharp.Dom from Nuget.org then you can use the strongly typed extensions.
// Add using PuppeteerSharp.Dom; to access XPathAsync<T>
string xpath = "//h1[#title='UL']//li";
var has = await ((IPage)pageTabel).XPathAsync<HtmlListItemElement>(xpath);
foreach (var listItem in has)
{
var textContent = await listItem.GetTextContentAsync();
}
I am retrieving a string from a MS Sql table, it could be just one name or delimited names: For example Tom or Speaker 1, Speaker 2.
I convert the string to list in the controller using:
Event cevent = db.Events.Find(id);
string speakers = cevent.Speakers;
ViewBag.speakers = "";
if (!String.IsNullOrWhiteSpace(speakers) &&
speakers.Contains(","))
{
ViewBag.speakers = speakers.Split(',').ToList();
}
else
{
ViewBag.speakers = speakers;
}
return View(cevent);
In the view I use the following to display the list:
<ul>
#foreach (var item in ViewBag.speakers)
{
<li> #item </li>
}
</ul>
Works great with the list, I get:
• Speaker 1
• Speaker 2
However, if the ViewBag has just one item, I get:
• T
• o
• m
You might consider always passing an enumerable speaker object to the view regardless of whether or not there are one or more than one speaker.
In your view, you are enumerating over the speakers object, which, in the case of the "Tom", is a list of chars. You might try something like this, instead:
In the controller:
ViewBag.speakers = new List<string>();
string speakers = cevent.Speakers;
var listOfSpeakers = speakers.Split(',').ToList();
foreach (var speaker in listOfSpeakers)
{
ViewBag.speakers.Add(speaker)
}
If you need to format the HTML output differently depending on whether more than one speaker is passed to the view, you can use if(ViewBag.speakers.Count > 1) on the speaker list in a conditional block and handle the output differently in that case.
I am trying to understand how to use anglesharp.
I made this code based on the example (https://github.com/AngleSharp/AngleSharp):
// Setup the configuration to support document loading
var config = Configuration.Default.WithDefaultLoader();
// Load the names of all The Big Bang Theory episodes from Wikipedia
var address = "http://store.scramblestuff.com/";
// Asynchronously get the document in a new context using the configuration
var document = await BrowsingContext.New(config).OpenAsync(address);
// This CSS selector gets the desired content
var menuSelector = "#storeleft a";
// Perform the query to get all cells with the content
var menuItems = document.QuerySelectorAll(menuSelector);
// We are only interested in the text - select it with LINQ
var titles = menuItems.Select(m => m.TextContent).ToList();
var output = string.Join("\n", titles);
Console.WriteLine(output);
This works as expected but now I want to access the Href property but I am unable to do this:
var links = menuItems.Select(m => m.Href).ToList();
When I look in the debugger I can see in results view that the HtmlAnchorElement enumerable object has a Href property but I am obviously not trying to access it right.
None of the examples in the documentation show a property being accessed so I guess it's something so simple that doesn't need to be shown but I am not seeing how to do it.
Can anyone show me how I should be accessing a html property with angle sharp?
edit:
This works when I cast it to the correct type
foreach (IHtmlAnchorElement menuLink in menuItems)
{
Console.WriteLine(menuLink.Href.ToString());
}
How would I write that as a Linq statement like the titles variable?
Alternative to har07's answer:
var menuItems = document.QuerySelectorAll(menuSelector).OfType<IHtmlAnchorElement>();
You can cast to IHtmlAnchorElement as follow :
var links = menuItems.Select(m => ((IHtmlAnchorElement)m).Href).ToList();
or using Cast<IHtmlAnchorElement>() :
var links = menuItems.Cast<IHtmlAnchorElement>()
.Select(m => m.Href)
.ToList();
im a bit late to this topic, but you can use
string link = menuItem.GetAttribute("href");
or this if its a list of items
List<string> menuItems = LinkList.Select(item => item.GetAttribute("href")) .ToList();
For the following examples, I'm using a content tree which looks like this:
Content tree
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var home = Model.Content.Descendants().Where(x => x.DocumentTypeAlias == "BlogContainer");
<div class="container">
<ul>
#foreach (var item in home)
{
foreach (var items in item.Children)
{
foreach (var baby in items.Children.OrderBy("date desc"))
{
var date = baby.GetPropertyValue<DateTime>("date");
<li>#items.Name - #baby.Name - #date</li>
}
}
}
</ul>
</div>
}
And the result is Result three I need to collect all items and set order by date
Try and do something like
var allItems = homePage.Descendants("YourItemNodeType")
.Where(item => item.HasValue("date")
&& item.GetPropertyValue<DateTime>
("date") != DateTime.MinValue)
.ToList()
.OrderByDescending(item => item.GetPropertyValue<DateTime>("date"));
This should get you all your items in both category 1 and category 2, i always tend to check if my date is actually set ( you wouldnt need to do that for create date mentioned by #bowserm as that is always there with a value).
Once u got them to List then you can sort them by their set date, i do this on when i list news articles in different parent pages, then you can just have one loop to go through all of them.
First of all, what Umbraco version are you using? It looks like you are using 6+? Is that right? My answer below should work for 6 and 7.
The property you are looking for is called createDate, so you would use something like baby.GetPropertyValue<DateTime>("createDate"). Even better, you should be able to just type baby.CreateDate. Umbraco has exposed all of the default properties that you might want on the IPublishedContent as properties, so you can get at those without having to use GetPropretyValue(...).
Take a look at this Umbraco v6 MVC Razor Cheatsheet. It lists the default properties you can get off of the nodes in Umbraco. The razor syntax for v6 will also be applicable to v7, so this cheat sheet works for both.
Hello I've had an issue with gathering an object from my Umbraco Blog page specificly cropping it down
#foreach (var item in Model.Content.Children.Where("visible==true"))
{
var BodyTextToCrop = item.GetProperty("bodytext").Value.ToString();
#item.Name<br />
#Umbraco.Truncate(BodyTextToCrop, 2, true)
}
Change your statement to the following:
#foreach (var item in Model.Content.Children.Where(x => x.IsVisible()))
{
var BodyTextToCrop = item.GetProperty("bodytext").Value.ToString();
#item.Name<br />
#Umbraco.Truncate(BodyTextToCrop, 2, true)
}
It looks like your where clause is using the dynamic access of the type and Model.Content could be strongly typed in your case.
Take a look at querying - MVC
Snippet on the page:
//dynamic access
#CurrentPage.Children.Where("Visible")
//strongly typed access
#Model.Content.Children.Where(x => x.IsVisible())