Using a $view->url of 'node/$node-class/calendar' and tabs, I provide a Calendar tab on node/$node-class. $node- is I believe an undocumented Views feature that works like $node, but for a specific content type -- keeping the Calendar tab from appearing for other content types.

Views Argument

To get the calendar tab to work properly, I have to use this custom Views Argument:

$date = getdate(time());

if(arg(0) == 'node' && is_numeric(arg(1))):
  $og_context = og_get_group_context();
  if ($og_context->nid == arg(1)) $gid = $og_context->nid;
  if (!$gid):
    $viewnode = node_load(array('nid' => arg(1)));
    $viewtype = $viewnode->type;
    if ($viewtype == 'classtrip') $gid = $viewnode->og_groups[0];
  endif;
endif;

$args[0] = $gid;

if (!$args[1]) $args[1] = $date['year'];
if (!$args[2]) $args[2] = $date['month'];
if (!$args[3]) $args[3] = 'all';

return $args;

.. the getdate() essentially simulating the URL of 'node/68338/calendar/2008/03/all' because for some reason, 'node/68338/calendar' alone gives me a calendar, but without events. A bug for a different day.

(The $viewtype .. part checks if the node we are viewing is part of a group and passes the first group there as the argument, so the block can work if we are viewing something owned by the group.)

Block

The block is tricky. This bit of code on line 20 of calendar.inc -- _calendar_views_query_alter, is causing problems:

$view->args = explode('/', str_replace($view->url .'/', '', $_GET['q']));

It's essentially overriding my $args above, including the $gid. I end up with a block calendar with a week view that says something along the lines of "March 8338" where 8338 is the last 4 digits of the group nid.

This line falls under "if ($view->build_type == 'block') {" -- but my feeble mind cannot comprehend why we would want to rely on $_GET['q'] for parsing arguments to a block. If the arguments for the block match $_GET[q], then we are likely viewing the full-size calendar already?

In any case, my solution was to comment this line out. I am setting $view->args in the Views Arguments Code and do not want it overridden without consideration.

Commenting out that line, then applying this fix -- http://drupal.org/node/227443 and the block now displays on node/$node-class and node/$node-classtrip.

Clicking on a date or using the « and » navigators brings me to that date on the full tab, which is fine in my case.

The $node-type dilemma

The last remaining problem I have is with using $node-class.

If I use 'node/$arg/calendar' -- the Calendar tab appears on every node, every content type.
If I use 'node/$node/calendar' -- again, the tab appears on every node, every content type.
If I use 'node/$group/calendar' -- no tabs/page available.
If I use '$group/calendar' -- again, no tabs or page. The block also breaks in this case.

That leaves 'node/$node-class/calendar' -- where 'class' is the content type. The tab only appears on class nodes. The block works.

.. and this brings up a new problem.

Nasty Hacks

All links generated by Views Calendar in the block are broken. They attempt to link to the literal 'node/$node-class/calendar/2008/03/all' -- instead of replacing $node-class with the proper ID.

Some consideration has been made for using node/$node/calendar and such, according to calendar.module:

/**
 * Figure out what the URL of the calendar view we're currently looking at is.
 */
function calendar_real_url($view, $args) {
  // Add non-calendar arguments to the base url.
  $parts = explode('/', $view->url);
  $bump = 0;
  foreach ($parts as $delta => $part) {
    // If one of the args is buried in the url, add it here and adjust
    // the delta values we'll compare the calendar arg positions to.
    if (in_array($part, array('$arg', '$node', '$user', '$group'))) {
      $parts[$delta] = array_shift($args);
      $bump++;
    }
  }
  foreach ($args as $delta => $arg) {
    if (!in_array($delta + $bump, calendar_arg_positions($view)) && !empty($arg)) {
      array_push($parts, $arg);
    }
  }


  return implode('/', $parts);
}

As you can see, this requires modification to support $node-type by any means. In my case, I opted to add $node-class to that array. I could have pulled a list of available content types and checked them all, or used strpos to locate $node and yank that part out of the array, but alas .. I'm not even yet certain if this is the direction I should be heading. I'm just knocking down walls..

Unfortunately, this still doesn't solve the problem entirely. The « prev, next » and iCal links of the calendar block still include the literal '$node-class' in them.

Tracking through iCal reveals what is possibly the problem.

In function calendar_ical_views_feed_argument:



    $args = calendar_ical_post_view_make_args($view, $arg, 'ical');
    $url = views_get_url($view, $args);

    $title = views_get_title($view, 'page', $args);
    if ($view->used_filters) {
      $filters = drupal_query_string_encode($view->used_filters);
    }
    return implode(calendar_ical_add_ical(url($url, $filters), $title));

views_get_url is not aware of $node-host nor $args[0] being the $gid.

The resulting iCal URL ends up looking like:

node/%24node-class/calendar/68338/2008/March/all/ical

Perhaps we should be passing $url or filtering $args through calendar_real_url first.

Out of time for now, I will figure this out tomorrow and post.

CommentFileSizeAuthor
#2 calendar_views_args.patch4.72 KBkimadactyl

Comments

kimadactyl’s picture

subscribe

kimadactyl’s picture

Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new4.72 KB

This is a patch to fix all the links on the calendar page view. This is the first patch I've ever submitted so I'm a little lost here and it might not work - needless to say my version works [1]. I didn't look at the block issues yet.

Also I made this against the 5.x-2.0-dev version.

Like I said this is my first patch, so (nice) criticism, help, etc would be great!

Kim

[1] http://queerwp.net/node/888/calendar/2008/03/all

will_in_wi’s picture

Status: Needs review » Reviewed & tested by the community

The patch works for me! Thanks!

kimadactyl’s picture

I realised it doesn't fix the breadcrumb. But that's another ticket!

dugh’s picture

In your patch on the line that reads:

elseif($path[$x]['type'] == 'gid') {

I added 'nid' too:

 elseif($path[$x]['type'] == 'nid' || $path[$x]['type'] == 'gid') {

So that calendars for particular node types work too, view page paths like "node/$node-mynodetype/custom"

Also see the views patch at the end of this issue: http://drupal.org/node/183191

I altered that patch and this one to have views module handle the extra token names:

function views_views_url_tokens() {
  $node_types = node_get_types('names');
  foreach($node_types as $name => $type) {
    $args['$node-'.$name] = 'views_url_node';
  }
  $args['$arg'] = 'views_url_arg';
  $args['$node'] = 'views_url_node';
  $args['$user'] = 'views_url_user';
  return $args;
}

and calendar_valid_views_args in this patch now looks like:

function calendar_valid_views_args() {
  return array_keys(module_invoke_all('views_url_tokens'));
}

It still doesn't fix the breadcrumbs entirely. The links are correct, but not the link titles yet.
If I can get it all fixed, I'll attach my copy of the views module here: http://drupal.org/node/281811

karens’s picture

I'm finally getting to this. I think we can simplify all this code quite a bit. The args that need to be passed through untouched all start with '$', so testing for that should be enough, we don't need to guess all the values those args might have. No valid calendar arg will ever start with '$', so that should be enough to know it isn't something for the calendar module to worry about.

Good points on finding other places that might be affected by this, I'll try to incorporate them into the patch.

The breadcrumb is handled by Views, I'm not sure I can do anything about that, but I'll play with it to see.

karens’s picture

Status: Reviewed & tested by the community » Fixed

This issue has too many separate issues and a variety of patches to fix different things differently.

I just committed a number of fixes to make sure breadcrumbs, titles, and links work correctly when there are other arguments and filters in the view. That should take care of most of theses issues. If there are other specific problems with the latest -dev version of the code, please open new issues for each to make it easier to figure out exactly which things are still not working.

karens’s picture

BTW, I didn't use any of the code on this page, I fixed things differently, so be sure to pick up the latest code.

jason.fisher’s picture

I will load this up on testing and see how it works in our situation. Thanks again for your dedication.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

jason.fisher’s picture

Status: Closed (fixed) » Active

We're getting very close. There are some issues with the calendar block argument handling not liking the Group nid(s) setup, but I was able to work around this with the following Views Argument code. mini= will appear as node/*year*/calendar/2008/10/all instead of node/*groupnid*/calendar. This code has the calendar block derive its context from what you are viewing if possible, and then allows for navigation of the block separately from the full calendar if viewing the block on the full calendar page.

Sorry for the rambling, one of those mornings.. :)




if ($view->build_type == 'block' && $_GET['mini']) {

  $arg = explode("/", $_GET['mini']);
  $args[0] = $arg[1];
  $args[1] = $arg[3];
  $args[2] = $arg[4];
  $args[3] = $arg[5];
                                                                     
  /* fix for mini=node/year/calendar instead of mini=node/groupnid/calendar */
  if ($arg[0] == 'node' && is_numeric($arg[1]) && $arg[1] == $arg[3]):
    
	/* Can we derive context? */
    if (arg(0) == 'node' && is_numeric(arg(1))) {
	  $viewnode = node_load(array('nid' => arg(1)));
	  if ($viewnode->type == 'host') $gid = $viewnode->nid;
	  elseif ($viewnode->og_groups[0]) $gid = $viewnode->og_groups[0]; 
	}
	         
	/* Fall back to OG default */
	if (!$gid) {
		$og_context = og_get_group_context();
	    $gid = $og_context->gid;
	}
	
	if ($gid) $args[0] = $gid;
  endif;

} else {     

  $arg[0] = arg(0);
  $arg[1] = arg(1);       

  if ($view->build_type == 'block') {
    $args[1] = arg(3);
    $args[2] = arg(4);
    $args[3] = 'all';
  }  

  $date = getdate(time());

  if($arg[0] == 'node' && is_numeric($arg[1])):
	$og_context = og_get_group_context();
	if ($og_context->nid == $arg[1]) $gid = $og_context->nid;
	if (!$gid):
	  $viewnode = node_load(array('nid' => $arg[1]));
	  $viewtype = $viewnode->type;
	  if ($viewtype == 'hostevent') {
	    $gid = $viewnode->og_groups[0];
	     if ($viewnode->field_calendar_date[0]['value']) {
	       $date = getdate(date_convert($viewnode->field_calendar_date[0]["value"], 'date', 'datestamp'));
	       $args[1] = $date['year'];
	       $args[2] = $date['mon'];
	       $args[3] = 'all';
	     }
	  }
	endif;
  endif;

  $args[0] = $gid;

  if (!$args[1]) $args[1] = $date['year'];
  if (!$args[2]) $args[2] = $date['mon'];
  if (!$args[3]) $args[3] = 'all';

}

return $args;



"host" represents my group node type. "hostevent" represents the calendar event node type that the group uses to create an event.

daniorama’s picture

Version: 5.x-2.0-rc » 6.x-2.x-dev

A solution is still needed for D6... any ideas?

karens’s picture

Status: Active » Fixed

I think I've fixed as much as I can control on this end. I just committed some fixes to get the calendar to keep track of other arguments when it creates its links, and if you precede the calendar argument with gid argument that is populated, it works exactly as it should. All of this will go into the next release, hopefully later today.

What's left is finding the right way to set a default value when there is no gid in the url, like when the view is in a block. You need to provide a default gid argument in that case, using some php code or however you do it.

You should post your question on the OG issue queue about the best way to set a default value for the gid since that's outside the scope of what the Calendar module can do.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.