? body-as-field-372743-171.patch
? body-as-field-372743-173.patch
? body-as-field-372743-177.patch
? body-as-field-372743-180.patch
? body-as-field-372743-184.patch
? edit_links_on_everything-473268-24.patch
? edit_links_on_everything-473268-interim.patch
? enforce_goto_action_D7_0.patch
? fields-ui_01.patch
? fields-ui_interim.patch
? installer_settings_text.patch
? installer_settings_text_02.patch
? test_redirect_login.patch
? modules/field/field.admin.inc
? modules/field/field.js
? sites/all/modules/block_class
? sites/all/modules/cck
? sites/all/modules/coder
? sites/all/modules/cvs_deploy
? sites/all/modules/viewsy
? sites/all/themes/extra_stark
? sites/default/files
? sites/default/settings.php
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.922
diff -u -p -r1.922 common.inc
--- includes/common.inc	13 Jun 2009 19:28:57 -0000	1.922
+++ includes/common.inc	16 Jun 2009 09:49:28 -0000
@@ -3651,6 +3651,14 @@ function drupal_render(&$elements) {
     $elements['#theme'] = 'markup';
   }
 
+  // If there is an edit link associated with this element but the #editable
+  // property has not been set, use the menu callback to determine whether or
+  // not it is editable by the current user.
+  if (isset($elements['#edit']) && !isset($elements['#editable']) && drupal_function_exists('menu_get_item')) {
+    $item = menu_get_item($elements['#edit']);
+    $elements['#editable'] = !empty($item['access']);
+  }
+
   // Make any final changes to the element before it is rendered. This means
   // that the $element or the children can be altered or corrected before the
   // element is rendered into the final text.
@@ -3904,6 +3912,9 @@ function drupal_common_theme() {
     'links' => array(
       'arguments' => array('links' => NULL, 'attributes' => array('class' => 'links')),
     ),
+    'edit_link' => array(
+      'arguments' => array('link' => NULL, 'element' => NULL),
+    ),
     'image' => array(
       'arguments' => array('path' => NULL, 'alt' => '', 'title' => '', 'attributes' => NULL, 'getsize' => TRUE),
     ),
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.328
diff -u -p -r1.328 menu.inc
--- includes/menu.inc	10 Jun 2009 21:52:36 -0000	1.328
+++ includes/menu.inc	16 Jun 2009 09:49:29 -0000
@@ -766,7 +766,7 @@ function menu_get_object($type = 'node',
 }
 
 /**
- * Render a menu tree based on the current path.
+ * Returns a menu tree based on the current path.
  *
  * The tree is expanded based on the current path and dynamic paths are also
  * changed according to the defined to_arg functions (for example the 'My account'
@@ -775,28 +775,30 @@ function menu_get_object($type = 'node',
  * @param $menu_name
  *   The name of the menu.
  * @return
- *   The rendered HTML of that menu on the current page.
+ *   An array representing the menu on the current page, suitable for
+ *   rendering with drupal_render().
  */
 function menu_tree($menu_name) {
-  $menu_output = &drupal_static(__FUNCTION__, array());
+  $menu_tree = &drupal_static(__FUNCTION__, array());
 
-  if (!isset($menu_output[$menu_name])) {
+  if (!isset($menu_tree[$menu_name])) {
     $tree = menu_tree_page_data($menu_name);
-    $menu_output[$menu_name] = menu_tree_output($tree);
+    $menu_tree[$menu_name] = menu_tree_unrendered($tree);
   }
-  return $menu_output[$menu_name];
+  return $menu_tree[$menu_name];
 }
 
 /**
- * Returns a rendered menu tree.
+ * Returns an array representing a menu, suitable for rendering.
  *
  * @param $tree
  *   A data structure representing the tree as returned from menu_tree_data.
  * @return
- *   The rendered HTML of that data structure.
+ *  A structured array representing the menu, suitable for rendering with
+ *  drupal_render().
  */
-function menu_tree_output($tree) {
-  $output = '';
+function menu_tree_unrendered($tree) {
+  $content = '';
   $items = array();
 
   // Pull out just the menu items we are going to render so that we
@@ -819,13 +821,28 @@ function menu_tree_output($tree) {
     $extra_class = implode(' ', $extra_class);
     $link = theme('menu_item_link', $data['link']);
     if ($data['below']) {
-      $output .= theme('menu_item', $link, $data['link']['has_children'], menu_tree_output($data['below']), $data['link']['in_active_trail'], $extra_class);
+      $content .= theme('menu_item', $link, $data['link']['has_children'], menu_tree_output($data['below']), $data['link']['in_active_trail'], $extra_class);
     }
     else {
-      $output .= theme('menu_item', $link, $data['link']['has_children'], '', $data['link']['in_active_trail'], $extra_class);
+      $content .= theme('menu_item', $link, $data['link']['has_children'], '', $data['link']['in_active_trail'], $extra_class);
     }
   }
-  return $output ? theme('menu_tree', $output) : '';
+  return array(
+    '#theme' => 'menu_tree',
+    '#menu' => $content,
+  );
+}
+
+/**
+ * Returns a rendered menu tree.
+ *
+ * @param $tree
+ *   A data structure representing the tree as returned from menu_tree_data.
+ * @return
+ *   The rendered HTML of that data structure.
+ */
+function menu_tree_output($tree) {
+  return drupal_render(menu_tree_unrendered($tree));
 }
 
 /**
@@ -1260,7 +1277,7 @@ function theme_menu_item_link($link) {
  * @ingroup themeable
  */
 function theme_menu_tree($tree) {
-  return '<ul class="menu">' . $tree . '</ul>';
+  return !empty($tree['#menu']) ? '<ul class="menu">' . $tree['#menu'] . '</ul>' : '';
 }
 
 /**
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.495
diff -u -p -r1.495 theme.inc
--- includes/theme.inc	13 Jun 2009 19:34:57 -0000	1.495
+++ includes/theme.inc	16 Jun 2009 09:49:30 -0000
@@ -729,16 +729,22 @@ function theme() {
   }
   else {
     // The theme call is a template.
-    $variables = array(
-      'template_files' => array()
-    );
+    $variables = array();      
     if (!empty($info['arguments'])) {
+      // Populate the variables with arguments passed to the theme function.
+      // Note that the first argument may be treated specially by template
+      // preprocess functions, so it must go into the variables array before
+      // anything else does.
       $count = 0;
       foreach ($info['arguments'] as $name => $default) {
         $variables[$name] = isset($args[$count]) ? $args[$count] : $default;
         $count++;
       }
     }
+    // Add an empty array of template files as a default; preprocess functions
+    // will be able to modify this. We include it last, as per the comment
+    // above.
+    $variables += array('template_files' => array());
 
     // default render function and extension.
     $render_function = 'theme_render_template';
@@ -767,7 +773,12 @@ function theme() {
     foreach (array('preprocess functions', 'process functions') as $template_phase) {
       foreach ($info[$template_phase] as $template_function) {
         if (drupal_function_exists($template_function)) {
-          call_user_func_array($template_function, $args);
+          $result = call_user_func_array($template_function, $args);
+          // Allow process functions to abort rendering the item by returning
+          // FALSE.
+          if ($result === FALSE) {
+            return '';
+          }
         }
       }
     }
@@ -1309,6 +1320,28 @@ function theme_links($links, $attributes
 }
 
 /**
+ * Return a themed edit link for an element on a page.
+ *
+ * @param $link
+ *   An array representing the edit link to be themed, in the format expected
+ *   by theme_links(); e.g., the array can have keys including 'title', 'href',
+ *   'html', etc.
+ * @param $element
+ *   An array representing the editable page element.
+ * @return
+ *   A themed HTML string representing the edit link.
+ *
+ * @see theme_links()
+ */
+function theme_edit_link($link, $element) {
+  // Construct a CSS class which associates this edit link with the region on
+  // the page that it edits.
+  $class = 'edit-link edit-at-' . str_replace('/', '-', $link['href']);
+  drupal_add_js(!empty($_REQUEST['edit_mode']) ? 'misc/edit.mode.js' : 'misc/editable.js');
+  return theme('links', array($class => $link), array('class' => 'links edit-links'));
+}
+
+/**
  * Return a themed image.
  *
  * @param $path
@@ -1859,6 +1892,37 @@ function template_preprocess(&$variables
   // Initialize html class attribute for the current hook.
   $variables['classes_array'] = array($hook);
 
+  // If the first item passed to the theme function is an editable page
+  // element which the current user has access to, populate useful variables
+  // for constructing edit links and other editable markup.
+  $element = reset($variables);
+  $variables['is_editable'] = is_array($element) && isset($element['#edit']) && !empty($element['#editable']);
+  // Do not show edit links when the user is already on the page that is being
+  // linked to.
+  $show_edit_links = $variables['is_editable'] && isset($_GET['q']) && $element['#edit'] != $_GET['q'];
+  // Add appropriate CSS classes that define this element as editable and
+  // associate it with its edit link.
+  if ($variables['is_editable']) {
+    $variables['classes_array'][] = 'editable-region editable-at-' . str_replace('/', '-', $element['#edit']);
+  }
+  // Define the default edit link.
+  $variables['edit_url'] = $show_edit_links ? url($element['#edit'], array('query' => drupal_get_destination())) : '';
+  if ($show_edit_links) {
+    $variables['edit_link_text'] = isset($element['#edit_text']) ? $element['#edit_text'] : t('Edit this item');
+    $variables['edit_link_info'] = array(
+      'title' => $variables['edit_link_text'],
+      'href' => $element['#edit'],
+      // Refer users back to the current page after they have completed their
+      // edits.
+      'query' => drupal_get_destination(),
+    );
+  }
+  else {
+    $variables['edit_link_text'] = '';
+    $variables['edit_link_info'] = '';
+  }
+  $variables['edit_link'] = $show_edit_links ? theme('edit_link', $variables['edit_link_info'], $element) : '';
+
   // Set default variables that depend on the database.
   $variables['is_admin']            = FALSE;
   $variables['is_front']            = FALSE;
@@ -1958,7 +2022,10 @@ function template_preprocess_page(&$vari
   $variables['main_menu']         = theme_get_setting('toggle_main_menu') ? menu_main_menu() : array();
   $variables['secondary_menu']    = theme_get_setting('toggle_secondary_menu') ? menu_secondary_menu() : array();
   $variables['search_box']        = (theme_get_setting('toggle_search') ? drupal_render(drupal_get_form('search_theme_form')) : '');
-  $variables['site_name']         = (theme_get_setting('toggle_name') ? filter_xss_admin(variable_get('site_name', 'Drupal')) : '');
+  // TODO: Remove. This is just a quick hack to give a rough feel for the
+  // "edit mode" in the D7UX proposal.
+  $edit_mode_link = !empty($_REQUEST['edit_mode']) ? l(t('global edit mode: On'), $_GET['q']) : l(t('global edit mode: Off'), $_GET['q'], array('query' => 'edit_mode=1'));
+  $variables['site_name']         = (theme_get_setting('toggle_name') ? t('!site_name (!edit_mode)', array('!site_name' => filter_xss_admin(variable_get('site_name', 'Drupal')), '!edit_mode' => $edit_mode_link)) : '');
   $variables['site_slogan']       = (theme_get_setting('toggle_slogan') ? filter_xss_admin(variable_get('site_slogan', '')) : '');
   $variables['css']               = drupal_add_css();
   $variables['styles']            = drupal_get_css();
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.345
diff -u -p -r1.345 block.module
--- modules/block/block.module	12 Jun 2009 09:02:55 -0000	1.345
+++ modules/block/block.module	16 Jun 2009 09:49:31 -0000
@@ -276,6 +276,8 @@ function block_get_blocks_by_region($reg
       $build[$key] += array(
         '#theme_wrapper' => 'block',
         '#block' => $block,
+        '#edit' => 'admin/build/block/configure/' . $block->module . '/' . $block->delta,
+        '#edit_text' => t('Configure this block'),
         '#weight' => ++$weight,
       );
     }
@@ -829,6 +831,22 @@ function block_flush_caches() {
 function template_preprocess_block(&$variables) {
   $block_counter = &drupal_static(__FUNCTION__, array());
   $variables['block'] = $variables['elements']['#block'];
+
+  // Create the $content variable that templates expect. If the block is
+  // empty, do not show it.
+  $variables['content'] = $variables['elements']['#children'];
+  if (empty($variables['content'])) {
+    // TODO: This is necessary to match the behavior in _block_render_blocks()
+    // when $block->content contains HTML output rather than a structured
+    // array. The inconsistency is ugly, though. It also means that the array
+    // of blocks per region inserted into the page via block_page_alter() can
+    // contain a larger number of blocks than actually will display on the
+    // page. (This part actually might not be bad, though; it means that other
+    // modules have a chance to insert content into these "empty" blocks and
+    // therefore make them appear after all, if they want to.)
+    return FALSE;
+  }
+
   // All blocks get an independent counter for each region.
   if (!isset($block_counter[$variables['block']->region])) {
     $block_counter[$variables['block']->region] = 1;
@@ -837,9 +855,6 @@ function template_preprocess_block(&$var
   $variables['block_zebra'] = ($block_counter[$variables['block']->region] % 2) ? 'odd' : 'even';
   $variables['block_id'] = $block_counter[$variables['block']->region]++;
 
-  // Create the $content variable that templates expect.
-  $variables['content'] = $variables['elements']['#children'];
-
   $variables['classes_array'][] = 'block-' . $variables['block']->module;
 
   $variables['template_files'][] = 'block-' . $variables['block']->region;
Index: modules/block/block.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.tpl.php,v
retrieving revision 1.3
diff -u -p -r1.3 block.tpl.php
--- modules/block/block.tpl.php	12 Jun 2009 09:02:55 -0000	1.3
+++ modules/block/block.tpl.php	16 Jun 2009 09:49:31 -0000
@@ -30,6 +30,15 @@
  * - $logged_in: Flags true when the current user is a logged-in member.
  * - $is_admin: Flags true when the current user is an administrator.
  *
+ * Edit variables:
+ * - $is_editable: TRUE when the block is editable by the current user.
+ * - $edit_link: An already-themed link to the edit page for the block; may be
+ *   empty.
+ * - $edit_url: The full URL to edit the block; may be empty.
+ * - $edit_link_text: A caption for the link to edit the block; may be empty.
+ * - $edit_link_info: An array of information describing the link to edit the
+ *   block; may be empty.
+ *
  * @see template_preprocess()
  * @see template_preprocess_block()
  * @see template_process()
@@ -43,4 +52,8 @@
   <div class="content">
     <?php print $content ?>
   </div>
+
+  <?php if ($edit_link): ?>
+    <?php print $edit_link; ?>
+  <?php endif; ?>
 </div>
Index: modules/menu/menu.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v
retrieving revision 1.192
diff -u -p -r1.192 menu.module
--- modules/menu/menu.module	27 May 2009 18:33:58 -0000	1.192
+++ modules/menu/menu.module	16 Jun 2009 09:49:31 -0000
@@ -149,6 +149,10 @@ function menu_theme() {
       'file' => 'menu.admin.inc',
       'arguments' => array('title' => NULL, 'name' => NULL, 'description' => NULL),
     ),
+    'menu_editable' => array(
+      'arguments' => array('element' => NULL),
+      'template' => 'menu-editable',
+    ),
   );
 }
 
@@ -293,6 +297,30 @@ function menu_block_view($delta = '') {
 }
 
 /**
+ * Implement hook_page_alter().
+ */
+function menu_page_alter(&$page) {
+  // Search for every non-empty menu block on the page.
+  // TODO: This works, but cries out for something like hook_block_alter()...
+  foreach (element_children($page) as $region) {
+    $blocks = &$page[$region];
+    foreach (element_children($blocks) as $id) {
+      if (isset($blocks[$id]['content']['#theme'])) {
+        $block = $blocks[$id]['#block'];
+        $content = &$blocks[$id]['content'];
+        if ($content['#theme'] == 'menu_tree' && !empty($content['#menu'])) {
+          // If we have a non-empty menu tree, wrap it in a theme function
+          // that will display an edit link.
+          $content['#theme_wrapper'] = 'menu_editable';
+          $content['#edit'] = 'admin/build/menu-customize/' . $block->delta;
+          $content['#edit_text'] = t('Edit this menu');
+        }
+      }
+    }
+  }
+}
+
+/**
  * Implement hook_node_insert().
  */
 function menu_node_insert($node) {
@@ -488,3 +516,11 @@ function menu_get_menus($all = TRUE) {
 
   return $query->execute()->fetchAllKeyed();
 }
+
+/**
+ * TODO: Comment.
+ */
+function template_preprocess_menu_editable(&$variables) {
+  // Create the $content variable that templates expect.
+  $variables['content'] = $variables['element']['#children'];
+}
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1070
diff -u -p -r1.1070 node.module
--- modules/node/node.module	12 Jun 2009 08:39:38 -0000	1.1070
+++ modules/node/node.module	16 Jun 2009 09:49:32 -0000
@@ -1122,6 +1122,8 @@ function node_build($node, $teaser = FAL
   $build += array(
     '#theme' => 'node',
     '#node' => $node,
+    '#edit' => 'node/' . $node->nid . '/edit',
+    '#edit_text' => t('Edit this @type', array('@type' => drupal_strtolower(node_type_get_name($node)))),
     '#teaser' => $teaser,
   );
   return $build;
Index: modules/node/node.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.tpl.php,v
retrieving revision 1.12
diff -u -p -r1.12 node.tpl.php
--- modules/node/node.tpl.php	28 May 2009 16:44:06 -0000	1.12
+++ modules/node/node.tpl.php	16 Jun 2009 09:49:32 -0000
@@ -47,6 +47,15 @@
  *   teaser listings.
  * - $id: Position of the node. Increments each time it's output.
  *
+ * Edit variables:
+ * - $is_editable: TRUE when the node is editable by the current user.
+ * - $edit_link: An already-themed link to the edit page for the node; may be
+ *   empty.
+ * - $edit_url: The full URL to edit the node; may be empty.
+ * - $edit_link_text: A caption for the link to edit the node; may be empty.
+ * - $edit_link_info: An array of information describing the link to edit the
+ *   node; may be empty.
+ *
  * Node status variables:
  * - $teaser: Flag for the teaser state.
  * - $page: Flag for the full page state.
@@ -89,6 +98,10 @@
 
   <?php print $links; ?>
 
+  <?php if (!$page && $edit_link): ?>
+    <?php print $edit_link; ?>
+  <?php endif; ?>
+
   <?php print $comments; ?>
 
-</div>
\ No newline at end of file
+</div>
Index: modules/system/system.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.css,v
retrieving revision 1.54
diff -u -p -r1.54 system.css
--- modules/system/system.css	11 Apr 2009 22:19:45 -0000	1.54
+++ modules/system/system.css	16 Jun 2009 09:49:33 -0000
@@ -490,6 +490,17 @@ table.sticky-header {
 }
 
 /*
+** Highlighted regions for editable.js
+*/
+.active-editable-region {
+  outline: solid red 2px;
+}
+
+.active-editable-link a:hover {
+  color: red;
+}
+
+/*
 ** Installation clean URLs
 */
 #clean-url.install {
Index: themes/garland/block.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/themes/garland/block.tpl.php,v
retrieving revision 1.7
diff -u -p -r1.7 block.tpl.php
--- themes/garland/block.tpl.php	12 Jun 2009 09:02:55 -0000	1.7
+++ themes/garland/block.tpl.php	16 Jun 2009 09:49:33 -0000
@@ -8,4 +8,9 @@
 <?php endif;?>
 
   <div class="content"><?php print $content ?></div>
+
+  <?php if ($edit_link): ?>
+    <?php print $edit_link; ?>
+  <?php endif; ?>
+
 </div>
Index: themes/garland/node.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/themes/garland/node.tpl.php,v
retrieving revision 1.10
diff -u -p -r1.10 node.tpl.php
--- themes/garland/node.tpl.php	28 May 2009 16:44:07 -0000	1.10
+++ themes/garland/node.tpl.php	16 Jun 2009 09:49:33 -0000
@@ -28,6 +28,10 @@
       <div class="links"><?php print $links; ?></div>
     <?php endif; ?>
 
+    <?php if (!$page && $edit_link): ?>
+      <?php print $edit_link; ?>
+    <?php endif; ?>
+
     <?php print $comments; ?>
 
   </div>
Index: themes/garland/style.css
===================================================================
RCS file: /cvs/drupal/drupal/themes/garland/style.css,v
retrieving revision 1.57
diff -u -p -r1.57 style.css
--- themes/garland/style.css	31 May 2009 00:51:41 -0000	1.57
+++ themes/garland/style.css	16 Jun 2009 09:49:33 -0000
@@ -290,6 +290,10 @@ table .form-button, table .form-submit {
   margin-bottom: 2.5em;
 }
 
+.edit-link {
+  font-size: 0.8em;
+}
+
 /**
  * Layout
  */
Index: themes/garland/template.php
===================================================================
RCS file: /cvs/drupal/drupal/themes/garland/template.php,v
retrieving revision 1.22
diff -u -p -r1.22 template.php
--- themes/garland/template.php	2 Jun 2009 03:57:22 -0000	1.22
+++ themes/garland/template.php	16 Jun 2009 09:49:33 -0000
@@ -47,6 +47,9 @@ function garland_preprocess_page(&$vars)
   if (!empty($site_fields)) {
     $site_fields[0] = '<span>' . $site_fields[0] . '</span>';
   }
+  // TODO: Remove. This is just a quick hack to give a rough feel for the
+  // "edit mode" in the D7UX proposal.
+  $site_fields[0] = $vars['site_name'];
   $vars['site_html'] = implode(' ', $site_fields);
 
   // Hook into color.module
