首先,我将概述我如何理解您的设置以及我的假设,因为没有看到任何代码,很难准确地遵循:
我假设您使用的是最新的 Drupal 7,带有最新的节点参考和标志模块。如果你不是最新的,你应该是,如果你使用的是低于 D7 的任何东西,这很可能是行不通的。使用 D8 你可能没问题,但我还没有机会测试它。
您有用户可以创建的内容类型Applicant Profile
,我的假设是他们可以创建多个配置文件?
Apply Now
假设这Job
是一种内容类型,您的标志设置为显示在您的广告工作上。
当用户单击Apply Now
aJob
时,他们会被带到标志确认表单,该表单要求他们选择Applicant Profile
并填写一些文本。
如果以上所有情况都是正确的,那么就没有办法自动准确地选择正确的应用程序配置文件,因为它们可以创建多个(并且可能希望在任意选择上选择一个),但是您可以做出一些有根据的猜测.
字段设置
我不确定您是如何Applicant Profiles
在选择框中显示的,您可能只是依赖Applicant Name
节点引用的字段设置中的内容类型复选框...如果是这样,您应该切换到使用视图来选择项目显示。通过这种方式,您可以更好地控制列表的生成方式......其中包括能够控制显示顺序。您将在节点引用字段的字段设置表单底部找到以下部分。但是,在您可以使用它之前,您需要创建一个references
视图。
您应该定义此视图,使其适用于您的个人资料内容类型,并按顶部的最新内容排序。编辑视图后,添加references
显示。将此显示设置为将 UID 作为上下文参数,如果没有传递参数,则从登录用户那里获取其值。然后将您的视图设置为显示每个应用程序配置文件所需的任何文本,并确保您正在过滤以仅显示 UID 拥有的那些配置文件。
定制代码
如果您要创建自己的定制模块来最好地描述(并保持包含)您正在进行的更改,那么这将是下一步的最佳选择。通常,开发人员要么使用项目名称(用于核心项目模块),要么使用您可能正在构建的附加组件的名称。如果您已经有一个可能符合要求的定制模块,您可以将以下代码合并到该模块中。如果模块已经hook_form_alter
实现,只需将块复制if ( $form_id === 'flag_confirm' ) { ... }
到该钩子中。请记住,您必须替换HOOK_
为模块的名称。例如,我最近调用了一个模块,tate_microsites
所以钩子是tate_microsites_form_alter
.
注意:如果您还没有创建任何定制模块,您还可以将此代码复制到您网站的主题中template.php
(确保替换HOOK_
为您的主题名称 ie bartik_form_alter
)。
/**
* Implements hook_form_alter().
*
* Steps in, finds the flag confirmation form, and causes the
* 'Applicant Name' field to select its second most item.
*/
function HOOK_form_alter(&$form, &$form_state, $form_id) {
if ( $form_id === 'flag_confirm' ) {
/// make sure our form has the field we are looking for
if ( !empty($form['field_applicant_name']) ) {
$und = LANGUAGE_NONE;
/// grab out the possible options, rendered by our view
$options = &$form['field_applicant_name'][$und]['#options'];
/// shift on to avoid the _none option
next($options);
/// Set the default value to the second item, using its key.
$form['field_applicant_name'][$und]['#default_value'] = key($options);
}
}
}
一旦此代码进入您的站点,请记住清除缓存,然后访问相关表单,您应该会看到列表中的第一个真实项目已被选中。这假设用户将想要选择他们最近创建的配置文件,但看到选择框仍然可以访问,如果他们愿意,他们可以选择另一个。
故障排除
如果您发现上述方法不起作用,您需要确保$form_id
和字段名称是正确的,并且您已替换HOOK_
为放置代码的正确名称。如果您使用的是特定语言,您可能需要将使用更改LANGUAGE_NONE
为您选择的语言。如果仍然失败,请确保您已清除缓存并且没有任何其他可能导致清漆、memcache 或 APC 等问题的缓存系统。
工作
只是为了解释我是如何得出这个解决方案的——因为大多数简单的 Drupal 修改的模式通常是相同的——首先你需要选择你的钩子。在这种情况下,因为我们希望修改字段的行为方式,所以您首先要查看的位置始终是hook_form_alter
or hook_field_preprocess
。这次我选择了前者,因为我知道我希望对字段项目进行完全计算,而当我们form_alter
遇到这种情况时,情况就是如此。如果您不知道有哪些 Drupal hooks 可用,您通常可以使用关键字“drupal hook”以及您尝试的任何其他内容搜索 Google,以发现大量信息。但是,也有这个列表,它绝不是详尽的,尤其是当您考虑到来自已安装模块的 contrib 钩子时。
无论如何,一旦使用正确的钩子,我通常最初会执行以下操作:
function HOOK_form_alter(&$form, &$form_state, $form_id) {
watchdog(__FUNCTION__ . ':' . $form_id, '<xmp>' . print_r($form, TRUE) . '</xmp>');
}
注意:显然,如果您安装了任何调试模块,则可以改用它们的调试消息处理,但这通常是一个快速的后备。
使用上述代码并清除缓存后,您应该执行将触发调试消息的操作。在这种情况下,我们需要访问我们正在处理的表单。之后,我们的调试消息应该在看门狗中可用(请记住,这仅在您启用日志记录时才有效)。
有了这个输出,我们应该能够找出两件事,我们需要定位的表单 id——在这种情况下是flag_confirm
——以及字段的构造,谁的输出应该如下所示:
[field_applicant_name] => Array
(
[#type] => container
[#attributes] => Array
(
[class] => Array
(
[0] => field-type-node-reference
[1] => field-name-field-applicant-name
[2] => field-widget-options-select
)
)
[#weight] => 1
[#tree] => 1
[#language] => und
[und] => Array
(
[#entity] => stdClass Object
(
[flagging_id] =>
[flag_name] => apply_now
[fid] => 2
[entity_type] => comment
[entity_id] => undefined
[uid] =>
[sid] =>
)
[#entity_type] => flagging
[#bundle] => apply_now
[#field_name] => field_applicant_name
[#language] => und
[#field_parents] => Array
(
)
[#columns] => Array
(
[0] => nid
)
[#title] => Applicant Name
[#description] =>
[#required] =>
[#delta] => 0
[#type] => select
[#default_value] => Array
(
)
[#multiple] =>
[#options] => Array
(
[_none] => - None -
[297541] => Pebbl Profile
[297543] => Another profile
)
[#value_key] => nid
[#element_validate] => Array
(
[0] => options_field_widget_validate
)
[#properties] => Array
(
[strip_tags] => 1
[optgroups] => 1
[empty_option] => option_none
[filter_xss] =>
)
[#after_build] => Array
(
[0] => field_form_element_after_build
)
)
[#access] => 1
)
通过这个输出和与Drupal Form API的交叉引用,您应该能够看到最终结果是如何计算的。两个关键元素是#default_value
和#options
。
更新
好吧,再一次,没有看到更多的视图和其他项目;建议很难。但是,只要您在标志确认表单中有您的字段,即呈现可供选择的可能应用程序,您仍然可以使用以下内容form_alter
来修改该字段。
如果您的字段当前列出了所有可能的配置文件,那么只要您有某种方法可以确定当前登录用户拥有哪个配置文件,您就可以浏览选项并选择所需的一个(就像我上面的代码一样,尽管是列表中的第一项)。
/**
* Implements hook_form_alter().
*
* Steps in, finds the flag confirmation form, and causes the
* 'Applicant Name' field to select its second most item.
*/
function HOOK_form_alter(&$form, &$form_state, $form_id) {
global $user; /// access to the $user object
if ( $form_id === 'flag_confirm' ) {
/// make sure our form has the field we are looking for
if ( !empty($form['field_applicant_name']) ) {
$und = LANGUAGE_NONE;
/// grab out the possible options, rendered by our view
$options = &$form['field_applicant_name'][$und]['#options'];
/// start with nothing selected
$selected = '';
/// here you could implement your search code
foreach ( $options as $application_nid => $option ) {
if ( ... ) {
$selected = $application_nid;
/// update the select box to only have one option
$form['field_applicant_name'][$und]['#options'] = array(
"$selected" => $option
);
break;
}
}
if ( $selected ) {
/// Set the default value to the correct application
$form['field_applicant_name'][$und]['#default_value'] = $selected;
/// Because this field has been auto selected, and only has one option
/// you might as well hide it from the user.
$form['field_applicant_name']['#access'] = 0;
}
}
}
}
显然在上面你必须...
用你的逻辑来选择正确的应用程序。但这完全取决于您如何在系统中建立这种关系。您确实有权访问该$user
对象,但您可能必须进行某种其他类型的数据库查找或加载以获取查找正确应用程序所需的所有信息。node_load
每个都完全有可能并与进行$application_nid
比较,但是我不建议这样做,尤其是在应用程序列表可能变大的情况下。相反,如果您需要加载额外信息进行比较,您应该使用EntityFieldQuery来定位应用程序本身,然后将其与选项列表中的项目进行比较。$user->uid
$application->uid
以上仍然不是最佳的做事方式,因为默认情况下根据当前登录用户生成选项列表会更好(这意味着只有一个项目可供选择,这可以使用视图实现,然后自动选择)或依赖标记关系并忽略用户直接选择应用程序。但是,至少没有看到您尝试视图的示例导出和屏幕截图(您在评论中提到的关于同时显示应用程序和音高的内容),我真的无法提供更多帮助。