In drupal 6 to get a node field's value you would do:
$node->field_ajax_override[0]['value']
Now it is:
$node->field_ajax_override['und'][0]['value']
Is this just going to be a pain to migrate or is there a better way?
You can use echo render($content['field_ajax_override']); instead in Drupal 7 (amongst other ways)
The article Rendering Drupal 7 Fields the right way discusses why accessing variables through ['und'] is bad. See the below excerpt.
Firstly, the ['und'] element is part of the field localisation in
Drupal 7 (see this article from Gábor Hojtsy for more on that);
directly accessing that value will cause issues in any kind of
multi-lingual environment. Boo.
By accessing the field value directly you miss out on any theming that
might come courtesy of the normal field markup.
The [0][safe_value] explicitly accesses the first value of the field -
if you wanted every value from a multi-value field you'd need to do
some sort of loop.
Some fields (such as node references) won't have a safe_value element,
only a value - which can easily be printed without thought for
sanitisation. This is dangerous, not because node reference fields
contain dangerous data (they're just a nid), but because it's not a
helpful habit to get into, especially for new developers. Other fields
types 'value' may well be highly dangerous.
The article then goes on to advocate the use of field_view_field('node', $node, 'field_name'); but in most cases render($content['field']); will be sufficient, particularly if you already have access to the node you're rendering, for example in the node.tpl.php file or one of it's variations.
Related
I'm using the migrate module to copy data from several sources to a new drupal installation. So far, I'm able to replicate a lot of what I need from the examples provided with the module. I'm currently stuck on adding terms or taxonomy to newly created nodes. The example shows:
// These are related terms, which by default will be looked up by name
$this->addFieldMapping('migrate_example_beer_styles', 'terms')
->separator(',');
I've tracked down the migrate_example_beer_styles destination mapping and it seems to be the machine name for that taxonomy.
I've tried imitating this behavior with every variation of what my machine_name should be, but the terms never seem to get associated:
By id:
// where source breed_id is '1,100' - it finds mapped values accordingly
$this->addFieldMapping('breeds', 'breed_id')
->sourceMigration('BreedMigration')
->separator(',')
And, by name:
// where source breeds is 'Dogs,German Shepherd'
$this->addFieldMapping('breeds', 'breeds')
->separator(',');
Am I wrong assuming the destination mapping is the machine name for a taxonomy?
This version of the migrate module was released recently, I haven't found any other helpful examples on the web.
This question still seems to be getting some views, so I thought I'd add what else I've discovered. While the accepted answer works, you are able to map Vocabs on ID:
$this->addFieldMapping('Exact Case Sensitive Vocab Name', 'source_field_name')
->sourceMigration('ExactSourceClassName')
->arguments(array('source_type' => 'tid'))
->separator(',');
->separator(',') used for passing a delimited string of source ids. Obviously, leave that off if you're mapping an array of values.
I'm currently working with migrate module myself, and I agree that the documentation is somewhat wanting at this point. :)
The 'machine name' of a vocabulary is listed in the Vocabulary table, in the field 'module'. Try using that value. Do note that you need to feed the text into the mapping, not the ids.
This is my first post on stackoverflow, so I apologize in advance if this isn't the accepted way to submit more information concerning this issue...
I've been stumbling around with the Migrate module for the past few days and was looking for a way to do this in Drupal 7. I had a comma-delimited list of taxonomy ids within an XML field that I wanted to use, but every example I found was retrieving from an external class, or from a database source.
Anyway, through trial and error, I found that you can use a field within the migrate class, rather than reference an external term migration class.
$this->addFieldMapping('field_article_type', 'category_id')
->arguments(array('source_type' => 'tid'))
->xpath('/article/category_id')
->separator(',');
Check out the taxonomy csv import module at http://drupal.org/project/taxonomy_csv.
It was easy to use and did what it was supposed to and more.
I ended up only using the migrate module for importin gNodes and used this module for the taxonomy. It was a pleasure to use.
I don't know if I'm on the right track but I'm trying to let users of my web site create there own versions of pages on my web site.
Basically I'd like to make our documentation used as a starting point where they just add details and make a new page for themselves in the process.
I have a 'book' content type that I have changed with CCK and a 'client edits' content type that uses a nodereferencefromURL widget to link itself to the book node.
So simple version of what I'm saying is I have a link on my book pages that creates a node using client edits content type. I would like to put some fields on the client edits content type that take the values of some of the fields from the book page it is linked from.
I'm sure I'm missing something as I would have thought someone would have tried this before but I can't even find a hint on how to go about this.
All I really need is a point in the right direction if my current thinking is wrong.
Current thinking is that I use a php script to get the default value for a field on the new node add screen that drags the value for a field from the book I'm linking from.
I'm thinking this is the case because there is an option for default values for the field in cck manage fields that lets you put in a php value to return a default value for your field.
Am I on the right track or is there already a module or process that does what I'm talking about and I'm just too dumb to find it.
This sounds a little strange, are your client edits going to be a diff from the original node or just coppied data?
I would prehaps do it a more simple way, just have book nodes, and have different fields disaply depending on who edits it (enable the content_permissions module). That way you can use the node clone module to create the users copy.
You will need to make a module to contain your custom php code.
I ended up using rules to save information from the user and the cloned node into hidden fields.
One that saved the original node ID into a field when ever you create content of that type unless the url ends with Clone. This means that when you create the clone the original node ID is kept in the field.
That made it easy to use a views argument that took the node ID to make the clone appear along side the original when a user visits the original page.
The second rule trick was to compute a field that saved the "store name" from the profile of the user only when saving clone content.
This meant that there was a hidden field on the clone that stored the info so I could then use another views argument to restrict the view to only people with the same store name in their profile.
I am no good with PHP but I managed to find a snippet (can't remember where) that returns the store name of the current logged in user as the argument.
global $user;
profile_load_profile($user);
return $user->profile_store_name;
I currently have nodes setup on my site, and each node belongs to a particular menu (not primary or secondary prebuilt menues).
How can i find out which menu a node belongs to?
Maybe this is what you mean:
$trail = menu_get_active_trail();
$lastInTrail = end($trail);
$menu_name = $lastInTrail['menu_name'];
menu_get_active_trail() returns a breadcrumbs like array, the last breadcrumb represents the current node.
Cheers,
Laurens Meurs, Rotterdam
I'm a noob, so don't bash me if what I'm going to write is worthless babbling.
I think you can't do that directly, unless there's some smart module out there that would do all the nasty SQL queries necessary to check this.
Node info is stored in the SQL table "node", and is identified merely by NID (node ID, which is the node number that appears after /?q=node/ in the address). Their aliases, if any, are stored in "url_alias" table, where you can find columns "src" and "dst", identifying the original and the aliased path (for instance, src='node/123', dst='my/url/alias'). The menu links can be found in the table "menu_links", where you can find the columns "menu_name" (the machine-radable name of a menu) and "link_path" (either the node/... or the alias).
So, what you'd need to do is the following:
get the current node's NID
query "url_alias" if there's an alias for node/NID and retrieve it, otherwise leave node/NID
query the "menu_links" table for the path you've determined and retrieve "none" or the menu's machine-readable name
You could then also query the table "menu_custom" to check what's the human-readable name of the menu you've determined.
Anyway, that's a complicated query (several queries?) and I'm a MySQL ignorant, so I can't help you with the actual code you'll need to use to check all that :P.
This isn't a direct solution and I see from your reply to a previous answer that you didn't wanted the simplest solution possible, but I thought I'd mention this option. The Menu Node API module maintains a table which Drupal lacks, a node-menu relationship table.
The module does nothing on its own, but there seems to be contributed modules which build on this, so depending on how complex your problem is it might be a starting point.
http://drupal.org/node/584984
Updated: Sorry guys, didn't even realize I had posted this link. I think I intended it as a draft and simply posted it when closing tabs. That said, mingos (above) is right on.
My link is to a function menu_get_active_menu_name() that appears to provide you with an array containing the active menu for the current page. As I presume that is what you are using it for, it would be a nice way to abstract yourself away from the database calls that might cause problems down the line.
I myself have never tried it, which is probably why I didn't elaborate and post. well... at least didn't post on purpose.
...or, in other words, how to create a simple join as I would do in SQL?
Suppose I want the following information:
Just as an example:
a person's full name
a person's hobbies.
His full name is in a (content profile) node type 'name_and_address' and his hobbies are in 'hobbies'.
In SQL, I would link them together by node.uid.
I've seen a bit about using relationships, but that goes with user-node-refs.
I just want the same user from one content-type and the other.
Now how could I get his name and his hobbies in 1 view?
There is a how to here does this do the job?
If not...
Views can be extended with custom joins, filters etc. If you are lucky there will be a module for this already. Some modules even provide their own views plugins.
You can write your own views plugins, although the documentation is a little fragmented.
The other thing that should be noted is that views isn't always the answer. Sometimes writing a custom query and display handler will do what you want with much less hassle.
Look at the relationships section of the view. This allows you to relate (ie join) different types of content (ie tables). It's not especially intuitive to someone used to SQL, but this video explains much of it. http://www.drupalove.com/drupal-video/demonstration-how-use-views-2s-relationships
You could use views_embed_view() in your template files to manually specify where they appear (and by extension render one view right below another).
You could override this function in a custom module (modulename_embed_view($name, $display_id)) in order to selectively edit what data is allowed out to the page.
Ex):
function modulename_embed_view($name, $display_id) {
if (strcmp($_GET['q'], 'node/123') === 0) {
$view = views_get_view($name);
$view2 = views_get_view('second view');
$output = $view['some element'] . $view2['element'];
}
return $output;
}
I know that this is very much a hack - I just wanted to show how one might use php to manually render and modify views in your template files.
How do you change the QTY (quantity) label in UberCart (in Drupal) without actually hacking the core components? I want the label to be be months, instead of qty.
You could use the String Overrides module. Here is an excerpt from its project page:
Provides a quick and easy way to replace any text on the site.
Features:
Easily replace anything that's passed through t()
Locale support, allowing you to override strings in any language
Ability to import/export *.po files, for easy migration from the Locale module
Note that this is not a replacement to Locale as having thousands of overrides can cause more pain then benefit. Use this only if you need a few easy text changes.
I once ran into a similar issue with Ubercart in another language (German), and we "solved" it by re-translating the string. The mentioned module should do the trick in your case.
I haven't used ubercarts, but I would guess there would be an admin section to do that. Else hook_form_alter() or hook_form_FORM_ID_alter() should be able to do the trick for you.
Unfortunately, there is no setting for this in ubercart.
Doing a search for 'Qty' (case sensitive, as there are numerous 'qty' in code) in the current ubercart-6.x-2.0-rc7 release gives seven matches:
3 in theme functions, which you'd need to override in your theme
1 in a form definition, which you'd need to change via hook_form_alter as googletorp suggested
3 in table definitions, which you'd need to change via hook_tapir_table_alter and/or hook_tapir_table_header_alter (see the hooks.php file in ubercarts doc directory for these)
So you should be able to implement your changes without changing the module itself, but given the amount of work involved, I'd try schnecks suggestion first ;)