I'm trying to edit the page when my blog displays the Parts.Blogs.BlogPost.List.cshtml. I went to ContentItems under content and added a MediaPicker Field called BlogPostImage to my BlogPosts, and I also made an alternate to Parts.Blogs.BlogPost.List.cshtml in my theme (which is the file I'm editing. The code that I have in there is:
#using Orchard.ContentManagement;
#{
IEnumerable<object> blogPosts =
Model.ContentItems;
}
#if (blogPosts == null || blogPosts.Count() < 1)
{
<p>#T("No posts.")</p>
}
else
{
int count = 0;
<div id="Blog">
<div id="slides">
<div class="slides_container">
#foreach (dynamic post in blogPosts)
{
count++;
string title = post.ContentItem.TitlePart.Title;
ContentItem item = post.ContentItem;
string text = post.ContentItem.BodyPart.Text;
string postImageUrl = post.BlogPostImage.Url;
<div class="slide">
<img src="#postImageUrl" width="625" height="400" alt="Slide #count.ToString()">
<div class="caption" style="bottom: 0">
<h4>#title</h4>
</div>
</div>
}
</div>
</div>
</div>
}
I cannot however figure out how in the world to call that mediapicker field into my list. Any way I try it comes back blank with some kind of querystring in the href. Something like "?23423455657". I took off the variable and that querystring still shows up. What I'm basically trying to accomplish is to put these into a slideshow, with the jquery to start the slideshow in the layout.cshtml. TIA
//SOLUTION:
After days and days of reading and researching I finally found a working solution.
Replacing:
string postImageUrl = post.BlogPostImage.Url;
With:
string postImageUrl = ((ContentItem)post.ContentItem).Parts.SelectMany(p => p.Fields).Where(f => f.Name == "BlogPostImage").First().Storage.Get<string>(null);
Got it from here: http://blog.cloudconstruct.com/post/Creating-a-rotating-image-gallery-in-Orchard-CMS.aspx
I hope it helps anyone stuck in the same boat. I am still curious why I couldn't simply call it the way I had it, but it's working now! :)
You can get the image url using dynamic:
dynamic postItem = post.ContentItem;
var postImageUrl = (string)postItem.BlogPost.BlogPostImage.Url;
Content item, when used as a dynamic object, exposes all its parts (here we're using the part that has the same name as the type, and where the fields are added when adding them from the admin). The part itself has dynamic members for each field (here, BlogPostImage), and from there you can get to the field's properties (Url here).
I tried the above answer with version 1.7 with no joy. I ended up having to download a copy of the source so I could delve into the objects. The below code got me the information I needed and also will help in future when I add extra fields to other content. I used part of the above answer to get to my solution...
IEnumerable<object> blogPosts = Model.ContentItems.ContentItems;
foreach (dynamic post in blogPosts) {
dynamic q = ((ContentItem)post.ContentItem).Parts.SelectMany(p => p.Fields).Where(f => f.Name == "BlogPostImage").First();
string postImageUrl = q.MediaParts[0].MediaUrl;
<img src="#postImageUrl" />
}
Hope this helps somebody.
Related
I tried to get the routeName from the URL because i need to set another class in the Layout of the body if i'm on the /Category page.
#{string classContent = Request.QueryString["routeName"] != "/Category" ? "container" : "";};
<div id="Content" class="body-wrapper #classContent">
My problem is, Request.QueryString["routeName"] is always empty and couldn't find why.
Does someone know why it's always empty or has a better approach for setting a different class if you're on a certain page?
In the end i solved it with that code:
var segments = Request.Url.AbsolutePath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string classContent = "container";
if (segments.Count() > 1) { classContent = segments[1] != "category" ? "" : "container";}
Request.Url.AbsolutePath gets the whole URL.
After that i split the whole URL and save it into a list.
Then i test if the list is long enough to be on another site except home.
In the end i look if the second part of the url is /Category and save the Css class appropriate to the output of the url.
I'm rendering a map of items retrieved from a database and filtered via the value state of an input field and attempting to then set the state of the input field as the value stored in some list item on click. I figured that using document.getElementById().innerHTML would allow me to retrieve the content stored within the appropriate tag and then set it to state which does work, the issue I'm facing is that it will only retrieve the innerHTML of the first item rendered in the map.
I've tried solutions ranging from applying UUID to making the mapped content available to the window and transfering the state of the individual objects but each disparate solution only moves the value of the first item to state - any ideas?
Rendered Content:
window.filteredItems = this.state.items.filter(
(item) => {
return item.companyNameObj.toLowerCase().indexOf(this.state.search.toLowerCase()) !== -1;
}
);
<div className="fixed-width">
<div className="search-container">
<form>
<input type="text" name="search" className="search-bar" placeholder="Search: " onChange={this.handleChange} value={this.state.search} />
</form>
<ul className="search-results">
{window.filteredItems.map((item) => {
return (
<div className="distinct-result-container">
<li key={item.id}>
<div className="image-container">
<img src={item.imageObj} alt={item.companyNameObj + " logo."}/>
</div>
<div className="company-container">
<span onClick={this.stateTransfer}><h3 id={"ID"}>{item.companyNameObj}</h3></span>
<p>Owned by: {item.ownerNameObj}</p>
</div>
</li>
</div>
)
})}
</ul>
</div>
<Footer />
</div>
);
stateTransfer()
stateTransfer(id) {
var search = this.state.search;
var uniqueID = document.getElementById("ID").innerHTML;
this.setState({
search: uniqueID
});
}
The current content of stateTransfer() doesn't represent any significant attempts at approaching a solution to this issue, it's just the minimum required implementation to move the innerHTML content to the input fields value.
EDIT: I've further clarified on the task at hand and a potential solution in the comments below (which follow this), I'm just hoping someone is able to help me with the actual implementation.
#DILEEPTHOMAS The list is comprised of data pulled from a Firebase Realtime Database and is rendered via mapping the filteredList and a search query; that functoionality works fine - what I need is to be able to click the element of any distinct li and have the innerHTML (the text stored in that li's item.companyNameObj) be moved to the value of the input field (so users can navigate the search content with re-typing).
#JoshuaLink I can't necessarily configure the items of the list any
further as it's just data pulled from an external database - I believe
the appropriate solution is to somehow provide a unique HTML ID value
to each newly rendered li and have that selected ID moved to
stateTransfer() where it can be set as the input fields value, I'm
just struggling with the actual implementation of this.
EDIT 2: I've managed to figure out a solution to both parts of the problem as described above - I'll post it as an answer below.
I managed to solve both parts of my problem:
The key issue, which was moving the text stored in each distinct li to the input value, which was apparently easily solved by making my stateTransfer() function accept an event and passing the .innerText value of the h3 through the event (I assumed I would have to use .innerHTML, which would require me to provide each distinct li with a unique generated ID) as follows:
stateTransfer(e) {
var search = this.state.search;
var innerText = e.target.innerText
this.setState({
search: innerText
})
}
The secondary issue, (which I incorrectly assumed was integral to implementing a solution to my question), assigning unique HTML id values to my procedurally generated li's was solved by implementing a for-loop in a componentDidUpdate() function which iterates through the current total length of the list and and assigns an id with the loop iterator concatenated to the end of the string as follows:
componentDidUpdate() {
var i;
var searchCompanyNames = document.querySelectorAll('.comapnyNames');
for(i = 0; i < searchCompanyNames.length; i++) {
searchCompanyNames[i].id = 'companyName-' + i;
}
}
Whilst I didn't need to assign unique ID's to the li's in the correct implementation, it's a useful trick worth noting nonetheless.
I'm still fiddling with typo3 (Version: 6.2.15) and I have gotten none of the code I found on the net to work. What I want to do, is define that a header is always converted into:
<h2 class="title-divider">
<span> {HEADERTEXT} <span class="de-em"></span></span>
<small>{SUBHEADER}</small>
</h2>
What I tried:
Based on this website: https://axelerant.com/change-typo3-header-layout-options/
I was able to add new Header types, but when I use the code for the styling from this website, my header just disappears...
I also tried to use the code that was published at http://www.typo3-addict.com/2010/03/a-custom-header-layout/ but first, it doesn't work for me, and second I don't really get how I could change it to display the subheader.
Can anyone point me in the right direction, or even better give me a code example that explains the concept that is followed, since it seems to be a misunderstanding of the concept.
Thanks in advance!
Alright, a couple of ours into the documentation and I have found a solution that works:
I added
stdheader.10.2 = COA
stdheader.10.2 {
setCurrent {
field = header
htmlSpecialChars = 1
}
key {
field = header_layout
ifEmpty = {$content.defaultHeaderType}
ifEmpty.override.data = register: defaultHeaderType
}
10 = TEXT
10.current = 1
20 = TEXT
20 {
field = subheader
stdWrap.noTrimWrap = | <span class="de-em"></span></span><small>|</small>|
stdWrap.required = 1
field.value =
}
stdWrap.dataWrap = <h2 class="title-divider">|</h2>
typolink.parameter.field = header_link
stdWrap.required = 1
}
stdheader.20.2 = COA
stdheader.20.2 {
wrap = <span style="display: none" class="hiddensubheader">|</span>
}
to the lib element in setup.ts.
I am using ng-repeat in my html to display the title of each 'workbook' object in an array that is on the scope. For some reason, the third title is being displayed three times. There are three objects in this test list, so it is iterating through the correct number of times. Here is the template html code:
<div id="list-of-workbooks" ng-controller="TableauListCtrl" class="ng-scope" >
<ul>
<li ng-repeat="workbook in workbooks" ng-click="clickWorkbook(workbook)" ng-mouseover="mouseoverWorkbook(workbook)" class="ng-binding"> {{ workbook.getTitle() }} </li>
</ul>
</div>
The output looks like this:
Workbook 3 Title
Workbook 3 Title
Workbook 3 Title
Is my error in the syntax? Thanks!
EDIT: It is also possible that the error occurs when the list is made. Each title is read from an XML Document (that long chain of calls returns the correct title) and is used to set the title of a Workbook (a custom service), which is then added to the list. Are there any error in this code? It is from the application module.
var title;
var workbooks = [];
for (var i = 0; i < workbooksData.length; i++) {
var workbook = Workbook;
title = workbooksData[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
workbook.setTitle(title);
workbooks[i] = workbook; // add a workbook with each title to the array of Workbooks
}
return workbooks;
Could it have something to do with the way angular listens to changes in the model, as is suggested in this question's accepted answer, in the second bullet point? That is pretty beyond my scope of understanding, so if someone could point me in the right direction to learn more I would appreciate it!
Try removing spaces from your div's id attribute "List of Workbooks".
You could have:
<div id="list-of-workbooks" ...>
Also, take a look at:
What are valid values for the id attribute in HTML?
Trying to display a set of images from uComponents' MNTP, and can't get a value for the umbracoFile property - in the example below, both umbracoFile and url return empty strings:
foreach (var id in #Model.sliders) {
var media = Model.MediaById(id.InnerText);
if (media != null){
var url = media.umbracoFile;
<p>name = #media.Name</p>
<p>alt = #media.altText</p>
<p>url = #media.umbracoFile</p>
<p>url = #url</p>
}
}
It's getting really really really annoying... I've worked around it in other areas like so, using Model.Media:
<img src="#Model.Media("topRightImage", "umbracoFile")" alt="#Model.Media("topightImage", "altText")" />
But that will only help if with the media picker data type, not mntp. It shouldnt' be that difficult, should it?
I can get the images to load if I rebuild the internal search index, but they're gone again on subsequent refreshes.
I've seen others having similar problems, and would really appreciate a solution...
ta
Nathan
This looks like a bug that was fixed in 4.7.2. See the following codeplex item:
http://umbraco.codeplex.com/workitem/30778