I would like to be able to export content editor's 'my toolbar' to a package so that whenever I restore the db on my dev machine I can also restore my buttons.
Where are those settings stored? I have looked all around in the core database and can't find it. The closest I have come is content\documents and settings{user name}...but my user name is not listed there.
Sitecore 6.6
It is saved in Sitecore "Registry": Sitecore.Web.UI.HtmlControls.Registry. It is wrapper under user profile entity. Toolbar buttons are saved by "/Current_User/Ribbon/My Strip" key separately for each user. If you want to move this data from one machine to another: think about serialization of user(I am not sure if it will serialized properly), moving whole Core database or copying values from aspnet_Profile table(is not convenient as values are serialized).
Sample code, how you can access these values:
var key = "/Current_User/Ribbon/My Strip";
var username = Sitecore.Context.GetUserName();
key = key.Replace("Current_User", username);
Response.Write("Key:" + key);
Response.Write("Registry:" + Registry.GetString(key));
Response.Write("Profile:" + Sitecore.Context.User.Profile[key]);
Under hood Registry.GetString(key) calls Sitecore.Context.User.Profile[key].
Sorry, you will not be able to find it in Core database and put it to package....
Related
Trying get started with custom module development on Drupal 8. Don't have previous Drupal dev background. Been reading and watching some materials in the past 2 or so weeks.
I decided to dare doing a little more "complex" other than "Hello World", but I got stuck on how would I actually go about this.
This is what I have so far:
I created a content type for "people". It's very simple, all it has is the person's name and birthdate (date only), so you can use the form to input a few people.
I created a view that displays the list of people, their names and their birthdate. Of course everything so far is using the core admin thing.
Now, I wanted to create a custom module that calculates the person's age (based on the date stored in the DB). It takes today's date, subtracts the person's birthdate, and calculates their age.
Then, with some magic, it returns the age to the render/page output and now this calculated value (the age) will be displayed on the view as well along with the person's name and birthdate.
I assume I would need to "hook into" a place somewhere, where the list of people is returned from the database. Then I loop through the data, get the birthdate, calculate the age, stick the result (age) back into the data, and then the page/view will display this - somehow.
Of course I am already stuck on how would I go about doing this? Where would I need to hook into? With what API? And then of course, I created a view already, but the view doesn't have the "age" field - since that is calculated on the fly. So where and how would I display it?
So many questions...
If anyone would know some tutorial that is similar to this, I'd appreciate it. It's kinda tough getting started with the "custom" side of Drupal.
Thanks for some tips!
without custom programming
You can actually do this without custom coding. For this you can I would use either of the following modules field_token_value or computed_field.
They both create a field without giving the user a textbox to input any value.
The value of such fields are calculated from predefined rules/custom coding/tokens defined per field.
from your custom theme
The easiest way is to do this on the theming layer and not store this value in the database. You have to use hook_preprocess_node in your THEMENAME.theme
function THEMENAME_preprocess_node(&$variables){
//install debug and kint to be able to use
//kint($variables);
$node = $variables["node"];
if($node->getType() == "CONTENTTYPE" && $node->hasField('field_date')){
//get date value something like "2018-09-07T21:35:30"
$date = $node->field_date->value;
//your logic and age calculations
// ...
$age = 35;
//set variable to use in node.html.twig based templates
$variables["person_age"] = $age;
}
}
In order to get more information on what is available install debug module and enable kint (which is part of debug) to be able to see variables using kint function
Than copy node.html.twig from your custom theme (or parent theme or classy core theme) to your THEMENAME/templates folder and rename it node--CONTENTTYPE.html.twig.
In there you can include the variable you just created in proprocess.
person age: {{ person_age }}
Make sure you clear the cache for all those changes to be seen by Drupal.
FOR MORE INFO
To find out what twig templates to override see here
More on twig and getting available variables
Getting more info on which twig template is used can also be obtained by enabling debug mode on previous link.
I would suggest you pick up a book on drupal development to understand all those concepts in a more concrete way.
Seeing release 1.3.3 of the smartsheet SDK and the ability to import XLS files straight from the SDK (which I haven't tried yet), I started thinking about how I would be able to achieve my goal to upload very large sheets with a minimum number of requests.
(see related questions: Building whole sheet programmatically with Python SDK, How to create a project sheet via the python SDK)
My current test methodology is to import an XLS file (though the UI so far), which comes in not formatted properly (Trying to make a project sheet, with gantt view, and resource management).
Using the python SDK, I use the Sheets.copy_rows() method to copy the rows from the sheet that was imported in the UI, to another blank sheet that is created following my project sheet template.
This seems to work perfectly, with the exception of the contact column, in which I would like to display the contact name rather than the contact email address.
According to https://smartsheet-platform.github.io/api-docs/?python#contact-list-columns:
When creating or updating cells for a contact list column, the
displayValue attribute works as follows:
If displayValue is non-null and non-empty, the Smartsheet cell displays the value provided.
If displayValue is an empty string, the Smartsheet cell displays the email address.
If displayValue is null or absent, Smartsheet makes a best guess effort at filling it in with a contact’s name based on the email
address.
Looking at the sheet I created from the import, I can see my cell data as: {"columnId": 7027801426552708, "value": "eleroy#******.com"}.
According to the doc above, since displayValue is absent, I was hoping the copy into a contact list column would attempt to fill with the contact's name based on the email address.
Is there a way I can force it to convert to the contact's name either on XLS import or during the copy?
Edit:
As seen with some of the answers below, I guess it makes sense that the copy would copy the data as is, so I'm left trying to have it fill in the contact name on XLS import.
I am trying to find a way to inject both the display value and the value in Excel, but haven't succeeded yet. I have tried Hyperlinks, email links, =HYPERLINK() formula, but so far no success.
If you set the Value with the email address and the displayValue as the contact name, you should be able to get what you're looking for. For example, the following body of a generic HTTP request would display "MyUser Gmail" in the cell, but have the myuser#gmail as the contact email.
[
{
"toBottom": true,
"cells": [
{
"columnId": 6xxxxxxxxxxxxxx8,
"value": "myuser#gmail.com",
"displayValue": "MyUser Gmail"
}
]
}
]
If the displayValue is empty, it's an indication that this cell's Contact does not have a name associated with it. If your original sheet does include a name, the point of failure is likely in the copy process.
Without looking into the Python SDK, I might guess that copy_rows() is only copying by value and not displayValue. Try manually setting the value/displayValue of the contact cell and see if that works.
My django app uses update_or_create() to update a bunch of records. In some cases, updates are really few within a ton of records, and it would be nice to know what got updated within those records. Is it possible to know what got updated (i.e fields whose values got changed)? If not, does any one has ideas of workarounds to achieve that?
This will be invoked from the shell, so ideally it would be nice to be prompted for confirmation just before a value is being changed within update_or_create(), but if not that, knowing what got changed will also help.
Update (more context): Thought I'd give more context here. The data in this Django app gets updated through various means (through users coming on the web site, through the admin page, through scripts (run from the shell) that populate data from a csv etc.). The above question is important mostly for the shell scripts that update data from csvs, hence a solution at the database/trigger/signal level may not be helpful here (I guess).
This is what I ended up doing:
for row in reader:
school_obj0, created = Org.objects.get_or_create(school_id = row[0])
if (school_obj0.name != row[1]):
print (school_obj0.name, '==>', row[1])
confirmation = input('proceed? [y/n]: ')
if (confirmation == 'y'):
school_obj1, created = Org.objects.update_or_create(
school_id = row[0], defaults={"name": row[1],})
Happy to know about improvements to this approach (please see the update in the question with more context)
This will be invoked from the shell, so ideally it would be nice to be
prompted for confirmation just before a value is being changed
Unfortunately, databases don't work like that. It's the responsibility of applications to provide this functionality. And django isn't an application. You can however use django to write an application that provides this functionality.
As for finding out whether an object was updated or created, that's what the return value gives you. A tuple where the second value is a flag for update or create
We have a very weird issue in our Siebel 7.8 application.
In the Application_Start event we define a bunch of profile attributes, which determine if the logged user will be allowed to perform certain operations or not. The code is something like this:
if (userHasSuperpowers) {
TheApplication().SetProfileAttr("CanFly", "Y");
} else {
// CanFly is not set, and GetProfileAttr("CanFly") returns ''
}
Everything works fine, except for one of these profile attributes. The conditions are not met, so we don't set its value. But when we check it using GetProfileAttr... it returns 'Y' instead of ''.
I've checked the code. A lot. I've put traces everywhere, and I'm 100% sure that when the last line of the Application_Start event executes, the attribute is still empty. However, in the first Applet_Load event after the login (in the HLS Salutation Applet (HLS Home) applet), its value has already changed to 'Y'. Why!!? I've looked everywhere, but I can't find anywhere else where we'd be doing a SetProfileAttr. So far, I've ruled out:
Every browser and server script for all our applets, application, BCs and business services.
All the runtime business services (the ones defined directly in the application instead of the SRF).
The Personalization Profile business component fields.
SmartScripts (not that they would matter in this particular scenario, I just mention them to acknowledge that you can set profile attributes there too).
Workflows: every step invoking the SIS OM PMT Service method Set Profile Attribute.
Siebel magically setting its value. The profile attribute name is custom made, in Spanish, and it contains our project name and a row_id. I really don't think Siebel is using the same name for its own profile attributes :).
But wait, there is more, I left the best part for last: the problem only happens in our development environment!
It's not an SRF issue: if we promote the same SRF to our testing or production environments, it works and returns the expected value.
It's not a data problem: still with the same SRF, I can use my local thick client, connecting to our development database with the same login and password, and it works fine too.
It's not a concurrency problem: we are testing with only one user logged in. And even if we had more, they wouldn't share sessions. And even if they did, the value wouldn't be always 'Y'.
It's not a temporary glitch, or something due to a wrong incremental compilation or a corrupted SRF: we have been experiencing this for at least 6 months (obviously, in that time frame, we've had dozens of different SRF files... all of them having the same problem, but only in development, and only if you use the server and not the dedicated client... seriously...).
Where else could I search the profile attribute being set? I've read that they can be persisted to the DB, but in order to do so, you have to define them as a field in a BC based on an S_PARTY extension table, right?
Is there any way to trace profile attribute changes somehow? Maybe rising some loglevel?
How can I find out at least what's being executed after the Application_Start, before loading the first applet?
Any other ideas? I tried checking the SQL spool file too, but didn't find anything suspicious there either (i.e., any of the queries we use to check the conditions, being run twice with different parameters).
Update: following Ranjith R's suggestions, I've also checked:
Other vanilla business services which could be also invoked from a workflow to set a profile attr: User Registration > SetProfileAttr, SessionAccessService > SetProfileAttr and ISS Promotion Agreement Manager > SetProfileAttributes.
Runtime events setting profile attributes directly or using a business service (we don't have any runtime events apart from the vanilla ones).
Business services being called from DVMs (we only have vanilla data validation rules, and none of them apply to our buscomps).
Still no luck...
Ok... finally we found what's happening:
We access the URL to our server and get to the login page. This triggers a first Application_Start event, for the SADMIN user.
We set the profile attributes in that session. SADMIN is the Siebel administrator user, so yes, he hasSuperpowers and therefore we do TheApplication().SetProfileAttr("CanFly", "Y");.
The Application_Start event finishes.
We enter our username and password in the login screen to access into Siebel. This triggers a second Application_Start event, this time for our user. This is the one I was monitoring with the trace files.
We set the profile attributes again in the new session. Our user doesn't hasSuperpowers, so we don't set any value for the CanFly attribute.
The Application_Start event finishes, and CanFly is still empty.
Siebel merges both sessions into one before loading the first screen!! Or at least, it transfers over the profile attributes we had set for SADMIN.
I'm sure it happens that way, for two reasons. First, we changed the profile attribute name to include the username too. And second, instead of storing just an "Y", we are storing now the current date:
var time = (new Date()).getTime();
TheApplication().SetProfileAttr("CanFly_" + TheApplication().LoginName(), time);
We end up having CanFly_SADMIN, but no CanFly_USER, and the time value stored is the same we see in the log file for step 2... which is smaller than any of the values for the *_USER attributes.
So that's what happening. I still don't know why Siebel behaves this way, but that would be matter for another question. According to the Siebel bookshelf:
The Start event is called when the client starts and again when the user interface is first displayed.
...but it doesn't say anythign about it being called from two different sessions, different users too, and then merging them together. It must be something misconfigured in our dev environment, considering it doesn't happen in the other ones.
Does Siebel 7.8 have runtime Events? I can't recall. Runtime events have an action set for setevent, which can set/clear profile attributes.
There are still other vanilla business services which can set profile attributes, try searching in tools flat under business service methods for *rofile*tt*.
The SIS OM service can also be invoked from DVMs for from RunTime events directly, so thats also a possibility.
There is no logging system to see values of Profile Attributes changing, testing is the only way out.
I have a little problem with using Flex 4 with Coldfusion 9. I hope you can tell me what I have to fix.
I use Coldfusion 9, hosted on my development machine.
I created a table in MySQL database with 2 columns: idPlayer as integer and auto increment. 2nd column is Name.
I use a ColdFusion Builder, Apptacular, to generate solid CFC service for me. It generates PlayerService.cfc here.
Now I use Flash Builder 4's data wizard to generate data service class from PlayerService.cfc. I create a form on update method of that service.
Ok, now look at the generated code.
// Please uncomment the below line if Data Management is enabled for Player and update is used as the create function.
// var player:Player = new Player();
So I uncommented the code and run the form. After fill the data, and click update, the pop up appear like this:
Unable to invoke CFC - Field 'idPlayer' doesn't have a default value
For details, turn on Robust Exception Information in the ColdFusion Administrator
So I don't know how Apptacular generate the code to work as ORM. But it should have some way or workaround to let the system act with idPlayer has no default value to insert other columns and generate idPlayer as auto-increment value (as I set in MySQL).
Could you help me solve this?
I don't know what your Player.cfc looks like (that's where the error is actually happening), but you'll need to set the generator attribute of the id property to let Hibernate know that the database is supposed to take care of that for you. You'll most likely have the exact same error if you tried to save the object via ColdFusion, so test your Service using CF first, and then move onto Flash so that you know if your issue is really with your Flex integration, or with your CF app.