I have MultilistField in my Product Template, and datasource for multilist field is Images - i.e Product Images.
i want to retrieve the Image-URL from the Multilist field. can you please guide.
FYI, i dont have Glasmapper or TDS in my solution. can you provide basic sitecore approach
Just use GetItems() method of MultilistField and then call MediaManager.GetMediaUrl method:
MultilistField mfField = Sitecore.Context.Item.Fields["mf_field_name"];
foreach (var item in mfField.GetItems())
{
var mediaUrl = Sitecore.Resources.Media.MediaManager.GetMediaUrl(new MediaItem(item));
}
Related
In my EmberJS app, I have two models, Book and Page. Book has a hasMany relationship to Page. In my controller to edit a single book, I am making a query to get all pages related to that book, and then assigning the response from the query back to the Book's page field.
I am using a third party EmberJS library ember-models-table to make paginated tables. I pass in book.pages to the paginated table component, and all works fine, except when I want to actually move between pages of results. The version of ember-models-table I'm using expects certain fields on book.pages to be present when paginating results: meta, query, store, and type.modelName. I can explicitly set those fields onto book.pages, but I have a feeling there has got to be a better way. Why would EmberJS strip fields like meta and store, from an ember-data query response, when you set that response onto another object?
Controller
this.get('store').query('page', { bookId }).then((res) => {
set(book, 'pages', res);
// Third Party Paginated Table Component Requires These Fields
set(book, 'pages.meta', res.get('meta'));
set(book, 'pages.query', res.get('query'));
set(book, 'pages.store', res.get('store'));
set(book, 'pages.type.modelName', res.get('type.modelName'));
});
HBS - Pages table
{{models-table-paginated
data=book.pages
columns=columns
customClasses=(hash table='table table-condensed')
showGlobalFilter=false
showColumnsDropdown=false
selectRowOnClick=false
pageSize=10
}}
You need to edit your serializer too. For example, i use models-table too but in backend, i use Django adapter. So i had to edit the serializer for each model to calculate the remaining pages (totalPages) and form that number to make the pagination based on your pageSize. Also at query on your route, you need to set pageSize and page as default. Now if you don't use meta like Django you should check your adapter documentation
for example, in Django the serializer for book model will be like this
import DRFSerializer from './drf';
import DS from 'ember-data';
import { isNone } from '#ember/utils';
export default DRFSerializer.extend(DS.EmbeddedRecordsMixin,{
extractMeta: function(store, type, payload) {
let meta = this._super(store, type, payload);
if (!isNone(meta)) {
// Add totalPages to metadata.
let totalPages = 1;
if (!isNone(meta.next)) {
// Any page that is not the last page.
totalPages = Math.ceil(meta.count / payload[type.modelName].length);
} else if (isNone(meta.next) && !isNone(meta.previous)) {
// The last page when there is more than one page.
totalPages = meta.previous + 1;
}
meta['totalPages'] = totalPages;
}
return meta;
}
i am using django and cloudinary direct upload to upload iamges
it is working if the form is valid.
but if my form is not valid, my page reloaded, and then the form will ask the user to upload the image again.
any way to solve this?
my code is attached below.
since i use direct upload, after an image is uploaded. it will be displayed immediately on the front end.
but when the form is invalid and the form is refreshed, the image is gone. ( after your latest update, it is true i do not need to re upload the photo again. but the photo is gone. how to display that again?)
thanks.
<script>
$('.cloudinary-fileupload').bind('cloudinarydone', function(e, data) {
var imag_var = $.cloudinary.image(data.result.public_id, {
format : data.result.format,
version : data.result.version,
transformation : 'form_preview'
});
$('.preview').html(imag_var);
$('.status_value').text('Uploaded:' + data.result.public_id);
$('#id_cover_image').val(data.result.public_id);
return true;
});
$('.cloudinary-fileupload').bind('fileuploadprogress', function(e, data) {
$('.progress').attr({
style : "visibility:show",
});
$('.status_value').text('Uploading...');
});
</script>
The Cloudinary javascript plugin puts the preloaded resource URI in a hidden field.
See here.
From the above one sees that if the field already exists the javascript plugin will populate it. Otherwise, it will create it.
In order to retain that URI across invalid form submissions you should create a hidden field named according to the field name you specified for cloudinary_direct_upload_field and which is populated with the value from the failed submission.
Another way to work around the issue would be to submit the form using an AJAX call. That way the data on page is retained even if validation failed and resubmission is possible. See here for an example of how that may be done.
EDIT:
Version 1.0.12 of the Cloudinary Python client library now adds the hidden field when needed out of the box so resubmissions should work. See the change log.
EDIT 2:
In order to regenerate a preview image in case of form validation error you can add something like this to the javascript code you run on page load (assuming the field name in the form is "image"):
//If form validation failed have the posted preloaded URI from the earlier
//submission so we can show preview
//pull the value from the hidden field
var imageUri = $('#direct_upload input[name="image"]').val();
//preloaded image URI structure
//{resource_type}/{type}/v{version}/{filename}#{signature}
var regex = /^([^\/]+)\/([^\/]+)\/v(\d+)\/([^#]+)#([^\/]+)$/;
//if there is value and it matches the pattern:
if (imageUri && regex.test(imageUri)) {
var uriParts = regex.exec(imageUri);
var version = uriParts[3];
var filename = uriParts[4];
//reconstruct a viable source
var src = "v" + version + "/" + filename;
//generate a cloudinary image tag and add it to the 'preview' div
$(".preview").append(
$.cloudinary.image(src, {
transformation: "form_preview" //your named transformation
})
);
}
I have downloaded Sitecore 7 Autohaus demo for learning purpose.
I notice that in Autohaus code, there is a model - Car.
I would like to know how does sitecore know how to map between Car model (code) and CarModel template (sitecore template).
There are a few more steps between the car template and the car object model.
One of the main features of Sitecore 7 is the embedded search capability. When items, created from the car template, are saved, that information is stored in a search index (Lucene or Solr)
The Car model is not mapped directly from the template or the database item but from the search document created.
When you use the LINQ layer e.g.
var index = ContentSearchManager.GetIndex("sitecore_master_index");
using (var context = index.CreateSearchContext())
{
var query= context.GetQueryable<Car>()
.Where(item => item.Seats == 2);
}
Sitecore will execute a search and then take the 'Car' object and populate/hydrate it with the information from the search results by use of Sitecore's DocumentMapper.
This will populate public properties and also indexers of the Car object. The DocumentMapper takes care of casting to and from object types for you (such as DateTime / int etc).
The DocumentMapper will try and map properties with matching field names but you can place attributes on the object properties to help Sitecore map specifically to your objects.
This example tells Sitecore to map the field 'modelkey' to the property ModelId.
[IndexField("modelkey")]
public string ModelId { get; set; }
You can see the LINQ queries used in Autohaus on most of the pages and should be a great resource for learning how Sitecore 7 works.
More info about various parts of Sitecore 7 can be found here: http://www.sitecore.net/Community/Technical-Blogs/Sitecore-7-Development-Team.aspx
I use the following to get, for instance, the header of the current page;
Header = Sitecore.Context.Item["Header"]
But how would i go about getting the src url of a image field?
PictureSrc = Sitecore.Context.Item["MyImage"]
You will want to look at leveraging the Sitecore.Resources.Media.MediaManager to get the URL to a media library item.
Before you get there, get the field from the item and cast it to a FileField. Once you have a FileField you can get access to the MediaItem.
Item item = Sitecore.Context.Item;
Sitecore.Data.Fields.ImageField imgField = ((Sitecore.Data.Fields.ImageField)item.Fields["MyImage"]);
string url = Sitecore.Resources.Media.MediaManager.GetMediaUrl(imgField.MediaItem);
string altText = imgField.Alt;
Link to Sitecore Media Item
I want to implement search functionality, So my requirement is I want to search some keyword in body tag in all content page. I do not know how I can search keyword in body tag in Sitecore. Please guide me?
As Anton outlined, the concept of searching the Body tag is wrong for Sitecore. You want to think in terms of Content in fields of Items. Sitecore's ContentSearch is how you can achieve this.
Sitecore comes with default indexes out-of-the-box that you should use for the search. You should rebuild these via the Index Manager in the Content Editor and then base your search on the basic example I've outlined for you below.
public IEnumerable<Item> Search(string searchterm)
{
string indexName = "sitecore_web_index";
using (var index = ContentSearchManager.GetIndex(indexName).CreateSearchContext())
{
var predicate = PredicateBuilder.True<SearchResultItem>();
IQueryable<SearchResultItem> query = index.GetQueryable<SearchResultItem>().Where(i => i.Content.Contains(searchterm)).Filter(predicate);
var searchResults = query.GetResults();
foreach (var hit in searchResults.Hits)
{
yield return hit.Document.GetItem();
}
}
}
jRobbins's answer is sensible (he get's my upvote). However, it is technically possible to index the content of the body tag. I would be cautious with this. I've seen it working well, but I've also seen it completely destroy the performance of a site.
The approach involves the creating a computed field in your index. You populate the computed field by making a web request to your newly published page and scraping the response body tag.
Here's are a couple of module that more or less does that:
https://github.com/efocus-nl/sitecorewebsearch
https://github.com/hermanussen/sitecore-html-crawler
If you can accept something a little less accurate, then you could loop through each of the components on your page and extract content from their datasources. That approach is discussed in this video:
http://www.techphoria414.com/Blog/2012/May/Sitecore_Page_Editor_Unleashed