Episerver-Get all properties of particular datatype in a content area items - episerver

I have a content area in a page .This content area holds different other blocks as part of content area items.
For instance, News Page has content area. Content area has Carousal block, Hero Block ,XYZ block & so on.
Is there a way to get all the properties of XHTMLstring type from all the blocks(carousal, hero ,xyz).I need to get all the text from these blocks.

If the blocks within the content area all implement a interface that exposes a xhtmlstring, for example IContentWithXhtmlString, then you should be able to access it with something like this.
var repo = ServiceLocator.Current.GetInstance<IContentRepository>();
var contentItems = currentPage.MyContentAreaProperty
.FilteredItems
.Select(x => repo.Get<IContentWithXhtmlString>(x.XhtmlString));
Further reading can be found here

Related

Extracting tableViewCell Widths in an Array?

I woukld like to form an Array which contains the widths of each label inside the customTableCell. As illustrated in the attached image, I managed to extract all the widths I am interested in but they are not all in the same array. Any idea how can I extrac t all the widths in ONE array?
#BrunoPastre is correct, but appending is also not the way to assign the values in the array. This function will be run many times for some cells, as you scroll up and down. You will end up with the same widths listed many times at different places in the array.
You should create the array with the right dimension, then assign them as cellsWidthsArray[indexPath.row] = cell.cellTextLabel.frame.size.width.
You should create your array only once, not every time tableView(_: UITableView, cellForRowAt: IndexPath) -> UITableViewCell is called. This can be achieved by moving the declaration of your array, on line 83, to somewhere outside of the function scope, but inside the class scope, like line 92. When you do that, cellsWitdhsArray will become a class variable, or an attribute, that can be accessed from anywhere inside the class
That method is called once per cell, if you declare a local variable cellsWidthArray its not going to persist across multiple calls of that function.
What you need is to "save" this array somewhere that isn't a local, temporary scope. The best way to do this is to save it as a property on the class.
I can see in your code you already have another array thats a property: tableViewRowsInsideSectionsArray. Scroll up to (hopefully) the very top of the class declaration in the same scope add your own cellsWidthArray.
It should look something like
class MyViewController {
...
private var cellsWidthArray: [CGFloat] = []
...
That way that local array isn't lost every time the function ends - it's owned by the view controller and is available anywhere within that class as long as that class exists.
HOWEVER, it may not work as you expect because another issue with that method (tableView(cellForRowAt:) is that it's only called when a cell is being displayed (visible on the screen). And it will be called multiple times if you scroll a cell off and back on the screen.
You can solve potential duplication by creating a dictionary where the key is something uniquely identifying the cell (it seems like its just going to be the text here) and the value is the width. Something like:
class MyViewController {
...
private var cellsWidthDictionary: [String: CGFloat] = [:]
...
func tableView(cellForRowAt:) { // I didn't feel like typing it all out
...
cellsWidthDictionary[theTextYouAreUsing] = width
But you now have another issue, the way you are getting the width, accessing the frame of the label just after you set the text, might not actually be correct. This function just prepares the cell, auto layout and frame adjustments might happen later.
A simple one line solution one might be tempted to do is to force a layout on the cell, after setting the text on the label, something like:
cell.cellTextLabel.sizeToFit() or cell.layoutIfNeeded()
that will just adjust the frame of the label to perfectly wrap the existing content.. but a much better solution would be to actually calculate it..
You could use https://developer.apple.com/documentation/foundation/nsstring/1531844-size
something like
let labelSize = (label.text?.size(attributes: [NSFontAttributeName: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))
then accessing labelSize.width
You're still left with the problem of only having that function called when a cell is about to be displayed on the screen. You can either manually scroll through every cell to build that table if you're using it for debugging/testing/informative purposes. But otherwise you would need to do something else...
Fortunately, Swift has a function that calculates the size a string would take - you just have to make sure you specify the text/font/size/any other styling elements. I pointed it out above... you can just iterate through all the strings that you're feeding into the cells and generate the dictionary right then and there as soon as you get the data.
Keep in mind this assumes a single line, if you have a max width for the label or other constraints that would cause the text to be cut off you would need to be even more explicit - I encourage you to google how to calculate the size of a label based off your needs if so.

Nested block types in Episerver

I am about to build a block for creating content tables in Episerver.
I would like this block to have a ContentArea which in turn will contain only blocks of type TableRowBlock (so that I can have an arbitrary number of rows).
If I create a block type called TableBlock and another one called TableRowBlock, they will both be visible when an editor adds a new block.
Since TableRowBlock only makes sense within a TableBlock, I would like to hide it so that it is only visible when adding a block to the ContentArea property of a TableBlock.
How can I do this?
What you're asking isn't supported out-of-the-box, I'm afraid.
However, you could:
Add an [AllowedContentTypes] attribute to your ContentArea property for TableBlock, and specify the TableRowBlock type as the allowed type. That way the editor won't have to select block type when clicking "Add new block" in the content area editor.
Customize which content type(s) are suggested when new content is created by creating your own IContentTypeAdvisor which would suggest TableRowBlock when TableBlock is being edited:
[ServiceConfiguration(typeof(IContentTypeAdvisor))]
public class ContentTypeAdvisor : IContentTypeAdvisor
{
public IEnumerable<int> GetSuggestions(IContent parent, bool contentFolder, IEnumerable<string> requestedTypes)
{
// Suggest relevant content types
}
}
Full example available here.

EpiServer - load block list based on property on each block

If I want to load a list of blocks based on a type I know I can do something like the following:
var blockType = contentTypeRepository.Load<MyBlock>();
But if I want to load the list based on both a type and a property on each block called tag being equal to "A", and at the same time have the list sorted by the property date on each block, how would I do that?

How to set a block for dynamic node in DRUPAL 7

I am new to Drupal. I have created a block that I want to show on some specific pages. Like if the url is "/node/2278" then I want to show the block for all the page under this "/node/2278". This may be /node/2278/1 or /node/2278/any-number.
You can use the Followings Path configurations
using (node/2278) -> the block will display only on node/2278.
using (node/2278/*) -> the block will display on node/2278/12 where * can be any text or number
using (node/2278/*/*) -> the block will display only on node/2278/12/45 where * can be any text or number
Use "/node/2278/*" , I think it actually tells you that the star can be a wildcard under the textfield where you enter it.
Don't forget you can set up url aliases so the path does not have to be "node/..." but can be whatever you want (admin/config/search/path/patterns)

Load an Image in Multiple movie clips using as3

I am really curious of asking a particular question to everyone of you. I am creating an Application in flash that is lot similar to this Application Zazzle Case Cover
I am almost ready with what i was supposed to do and How i have to do. But, still i am ain't a very big Tech_geek to handle all these . I list out some of the things which i could`nt achieve. Kindly help me if possible.
I know that inorder to load unlimited number of images in a Movie Clip, we need Array. But to go with it, I am not sure of framing it properly.
I have Merged certain codings from internet and encoded it to act as the Application in that Site for a Single image in a Single view, but when i try to add child or make it display the same image in all other views i can't frame the coding. It is not behaving properly .
Last but not the Least, I am confused of displaying the Bitmap data in as3... I wanted to show the Uploaded Panel Image in the below thmbnail area but i am not so sure of it.
The Questionnaire format of the Above problems are
How to upload unlimited number of images in a Movie Clip using Array ?
Is it is possible to Display the same image in two Movie Clips simultaneously using addChild ?
I had lots of blah and blah but this area plays the 2nd Question and even Answer for it. But i am ain't sure revealing the Answer.
function onMovieClipLoaderComplete(event:Event):void
{
// Hide progress bar
progressBar.visible=false;
var loadedContent:DisplayObject=event.target.content;
var loader:Loader=event.target.loader as Loader;
loadedContent.x=-37.625;
loadedContent.y=-37.625;
loadedContent.width=75.25;
loadedContent.height=75.25;
trace("loadedContent.width="+loadedContent.x);
trace("loadedContent.height="+loadedContent.y);
mcOnStage=true;
con1.container.addChild(loader);
clears.addEventListener(MouseEvent.CLICK, removeMC);
function removeMC(MouseEvent):void {
trace("Its Removed");
if (mcOnStage )
{
con1.container.removeChild(loader);
con1.textcontainer.removeChild(txt);
mcOnStage=false;
}
}
}
"con1.container.addChild(loader);"
Can i add "con1.container2.addChild(loader);" for the same loaded image.
How to Clone a Movieclip's Bitmap data and Display it in another area or Movieclip ???
Guide me if possible...
I have included the SWF file along with this Question...
https://docs.google.com/file/d/0B5jnHM1zpP4MOHRCeWFqX05sSTA/edit?usp=sharing
Can Someone check the first Site and gimme little notes of how can i bring all those modules in this flash as3 based application.
Here's how you would display the same image twice, with reference to the code you included in your post:
//here's your code
var loadedContent:DisplayObject=event.target.content as DisplayObject;
//create bitmap data instance same size and as the loaded content
var transparent:Boolean = true;
var fillColor:uint = 0xFFFFFFFF;
var bitmapData:BitmapData = new BitmapData(loadedContent.width, loadedContent.height, transparent, fillColor);
//draw the loaded content into the bitmap data
bitmapData.draw( loadedContent );
//create new bitmap
var bitmap:Bitmap = new Bitmap( bitmapData);
//add the loaded content
con1.container.addChild(loader);
//add your 'cloned' content
con1.container2.addChild( bitmap );

Resources