In the Nautilus System Browser (Pharo 6) there's a right-click command to Add package... as well as Add class... and even Add protocol..., but I can't find anywhere a way to Add method....
Where is that command?
In Pharo, adding a method is not as explicit as the other elements. To add a new method:
Select the protocol for the method, and you should see a template in the editor pane:
messageSelectorAndArgumentNames
"comment stating purpose of message"
| temporary variable names |
statements
Edit this template to make a new method,
Save (Right-click Accept) it using Ctrl-S.
In fact, any time you change a method's definition (e.g., messageSelectorAndArgumentNames) and save it in the editor (Right-click Accept or Ctrl-S), it will create a new method.
For more details, see the section 1.3 of Developing a simple counter document (emphasis is mine):
Create a method
Now let us create the accessor methods for the instance variable count. Start
by selecting the class Counter in a browser, and make sure the you are editing the instance side of the class (i.e., we define methods that will be sent to
instances) by deselecting the Class side radio button.
Create a new protocol by bringing the menu of methods protocol list. Select
the newly created protocol. Then in the bottom pane, the edit field displays
a method template laying out the default structure of a method. As a general
hint, double click at the end of or beginning of the text and start typing your
method. Replace the template with the following method definition:
count
"return the current value of the value instance variable"
^ count
This defines a method called count, taking no arguments, having a method
comment and returning the instance variable count. Then choose accept in
the menu to compile the method.
Related
I have a template switch where, based on the node's concept, I want to create runtime objects using that node's properties and/or children. The right-hand side of each case is an inline template. How do I access node's properties/children from that inline template? More specifically, in the screenshot below, the arguments to the line() and rectangle() methods need to be extracted from the corresponding LineCommand and Rectangle nodes.
Note that the Alt+Enter menu doesn't offer to "Add a Property Macro".
I am using MPS 2018.1.5.
In order to extract an argument from the node's children you need to add the template argument (e.g. "null") and then put the macro on it. Then in the process of generation, the template argument (null) will be replaced with the generation target of the node's children.
If you want to use the node's property, then you should add a more specific argument (e.g. empty string) and put the caret to the property cell (between the quotes) and then you will see the "Add Property Macro" intention
template argument
template argument with the property
add property macro
Add a dummy argument first and then use Alt+Enter on the argument to add a macro to replace it with something from the node.
I need to dynamically handle the object properties through code in my project as many of the object values are changing dynamically. So is there any way to parameterize object's properties in UFT?
To parameterize Object's Properties you need to Open your Object Repository in Object Repository Manager and go to Tools > Manage Repository Parameters and here you will get a window named as Manage Repository Parameters.
In this window click on "+" button and add Name, Default Value and Description of the parameter.
Till here you have successfully added the Dynamic Parameter.
Now to assign this parameter to an object what you need to do is just click on your object in which you want to use this property and then configure the value of required description property by pressing Ctrl + F11. Now from Repository Parameter window you can select "Parameter" radio box and select the property you added before and click OK.
After doing all these steps use this object in your code by just writing the below code and you are good to go with Parameterization of your Object.
Repository.Value("AddedObject") = "ValueYouWantToPassInRequiredProperty"
I have created a custom module (actually I have created a handful in recent years, and this same obstacle frustrates me every time) following the Kentico documentation:
https://docs.kentico.com/display/K9/Creating+custom+modules
The problem I end up with every time, is in developing the User Interface for Parent/Child classes. I create a Vertical Tab node, and beneath it I add an edit tab and a Binding tab for the child class. This all works, and I can add and remove bindings at will, but what I can't do is ADD a new child class and bind it.
Using the Standard Edit Binding template, I am able to bind EXISTING Job Titles to the selected Category, but I cannot CREATE a new one from that page:
To solve this, I created a custom Edit Binding template, and added a New Child Class Header Action that points to a New / Edit Object child:
Which gives me a button that I can use to add a new child class (Job Title):
This approach works per se, in that I can click the New Job Title button and create a new item on the subsequent page:
But no binding is created to link the child object (Job Title) to the selected parent object (Category), An even bigger problem is that once I click Save, I am presented with the following:
The new object DOES SAVE, but the post-save navigation is somehow failing. The event log offers little in the way of diagnostics:
So I thought to create a completely custom interface to accomplish my needs here, according to the Kentico documentation:
https://docs.kentico.com/display/K9/Manually+creating+the+interface+for+custom+modules
So I change the Element Content of the New Job Title page to a custom page that I created to post a DataForm for the new object:
Taking care to assign the proper Object Types on the Properties Tab:
The intent was to programmatically create the binding upon save and also handle the correct navigation to avoid the ambiguous parameter error above, but when this page loads, the UIContext.ObjectID and UIContext.ParentObjectID are both 0:
So I cannot create the binding programmatically. I was able however to solve the error that I received by manually assigning the redirect. The experience is still lacking even with this hack, since it returns to the listing page, but the user still has to click "Add Items" to assign the binding after successfully creating it with the custom page I built.
This cannot be the proper way to do this, so any help with getting me on the right track would be greatly appreciated.
In order for the EditedObject to have a value you have to either decorate the page with the EditedObjectAtribute e.g. like this:
[EditedObject("<custom.objecttype>", "<objectid>", ...)]
or set the object yourself:
int objectId = QueryHelper.GetInteger("objectid", 0);
EditedObject = SomeInfoProvider.GetSomeInfo(objectId);
In your case, I'd recommend exploring what query parameters are available on the page and using them to fetch appropriate object(s). Also, make sure "JobCategoryId" is passed to the "New Job Title" dialog so that you can create the binding.
Btw - kudos for well asked question!
In orchard, I've added a boolean field called "IsDone" to the built in Content Menu Item content part via that Admin interface. I've then picked an item in Navigation and set the option to "yes" for the corresponding field i added.
In my custom theme, I've copied over MenuItem.cshtml.
How would I get the value of my custom "IsDone" field here?
I've tried something like
dynamic item = Model.ContentItem;
var myValue = item.MenuItem.IsDone.Value;
but I'm pretty sure my syntax is incorrect (because i get null binding errors at runtime).
thanks in advance!
First i suggest you use the shape alternate MenuItemLink-ContentMenuItem.cshtml instead of MenuItem.cshtml to target the content menu item directly.
Secondly, the field is attached to the ContentPart of the menu item. The following code retrieves the boolean field from this content part:
#using Orchard.ContentManagement;
#using System.Linq;
#{
Orchard.ContentManagement.ContentItem lContentItem = Model.Content.ContentItem;
var lBooleanField = lContentItem
.Parts
.Where(p => p.PartDefinition.Name == "ContentMenuItem") // *1
.SelectMany(p => p.Fields.Where(f => f.Name == "IsDone"))
.FirstOrDefault() as Orchard.Fields.Fields.BooleanField;
if (lBooleanField != null)
{
bool? v = lBooleanField.Value;
if (v.HasValue)
{
if (v.Value)
{
#("done")
}
else
{
#("not done")
}
}
else
{
#("not done")
}
}
}
*1
Sadly you cannot simply write lContentItem.As<Orchard.ContentManagement.ContentPart>() here as the first part in the part list is derived from this type, thus you would receive the wrong part.
While #ViRuSTriNiTy's answer is probably correct, it doesn't take advantage of the power of the dynamic objects that Orchard provides.
This is working for me but is a much shorter version:
#Model.Text
#{
bool? IsDone = Model.Content.ContentMenuItem.IsDone.Value;
var IsItDoneThough = (IsDone.HasValue ? IsDone.Value : false);
}
<p>Is it done? #IsItDoneThough</p>
You can see that in the first line I pull in the IsDone field using the dynamic nature of the Model.
For some reason (I'm sure there is a good one somewhere) the BooleanField uses a bool? as its backing value. This means that if you create the new menu item and just leave the checkbox blank it will be null when you query it. After you have saved it as checked it will be true and then if you go back and uncheck it then it will have the value false.
The second line that I've provided IsItDoneThough checks if it has a value yet. If it does then it uses that, otherwise it assumes it to be false.
Shape Alternate
#ViRuSTriNiTy's other advice, to change it to use the MenuItemLink-ContentMenuItem.cshtml instead of MenuItem.cshtml is also important.
The field doesn't exist on other menu items so it will crash if you try to access it. Just rename the .cshtml file to fix this.
Dynamic Model
Just to wrap this up with a little bit of insight as to how I got there (I'm still learning this as well) the way I figured it out is as follows:
.Content is a way of casting the current content item to dynamic, so you can use the dynamic advantages with the rest of line;
When you add the field in the admin panel it looks like it should be right there on the ContentItem, however it actually creates an invisible ContentPart to contain them and calls it whatever the ContentItem's type is.
So if you had added this field to a Page content type you would have used Model.Content.Page.IsDone.Value. If you had made a new content type called banana it would be Model.Content.Banana.IsDone.Value, etc.
Once you are inside the "invisible" part which holds the fields you can finally get at IsDone. This won't give you the actual value yet though. Each Field has its own properties which you can look up in the source code. the IsDone is actually a BooleanField and it exposes its data via the Value property.
Try doing a solution-wide search for : ContentField to see the classes for each of the fields you have available.
Hopefully this will have explained things clearly but I have actually written about using fields in a blog post and as part of my getting started with modules course over on the official docs (its way down in part 3 if you're curious).
Using built-in features instead of IsDone
This seems like a strange approach to do it this way. If you have a Content Item like a Page then you can just use the "Show on a menu" setting on the page.
Go to admin > content > open the page > down near the bottom you will find "Show on a menu":
This will automatically put it into your navigation and then you can move it around to where you want:
After it "IsDone" you can just go back and untick the "Show on a menu" option.
Setting up the alternative .cshtml
To clarify your comments about how to use the alternative, you need to
Copy the file you have at Orchard.Core/Shapes/Views/MenuItem.cshtml over to your theme's view folder so its /Views/MenuItem.cshtml
Rename the copy in your theme to MenuItem-ContentMenuItem.cshtml
Delete probably everything in it and paste in my sample at the start of this post. You don't want most of the original MenuItem.cshtml code in there as it is doing some special tricks to change itself into a different shape which isn't what you want.
Reset your original Orchard.Core/Shapes/Views/MenuItem.cshtml back to the factory default, grab it from the official Orchard repository
Understanding the view names
From your comments you asked about creating more specific views (known as alternates). You can use something call the Shape Tracer to view these. The name of them follows a certain pattern which makes them more and more specific.
You can learn about the alternates on the official docs site:
Accessing and Rendering Shapes
Alternates
To figure out what shape is being used and what alternates are available you can use the shape tracing module which is documented here:
Getting Started with Shape Tracing
I want to add a simple panel to a dialog created using Visual Studio resource editor, but the resource editor doesn't allow this - I need to add my own CWnd as a dialog child. However that way I think I have to use CWnd::Create manually, and pass in names for the class and the window.
I want to create an ID like IDC_MYPANEL, and as much as possible add the window so it works like something defined in the template. What's the right way to do this, and what's the best MFC class to use as a simple panel... just use CWnd itself?
What do you mean by 'a simple panel'? If it's a custom control, derive from CWnd, override Create() and call CWnd::Create() with NULL as the class name so that MFC makes its own, and add a line to resource.h with the IDC_XXX value of your control. If it's a sub-dialog, with controls on it, derive from CDialog and call CDialog::Create() with the IDD that you define in your dialog.
The only difference when creating a control at runtime is that in OnInitDialog, you do some Create() and initialisation things, and you don't include a DDX_Control() line for that control. For the rest everything works the same.