Drupal: Dynamic View using Arguments - drupal

For a current project i need to setup a specific view to display a gallery detailpage. It should work like this:
1. User clicked a node (costum-post-type: gallery)
2. User received an overview page with linked images
3. User clicked an image
4. User received the gallery page (gallerific view)
Step 1-3 are done. But how can I get Drupal to build a detail page using the data of the overview page?
For Example something like this: http://example.com/gallery-1/detail or http://example.com/gallery-2/detail.
/gallery-n is the overview page with linked images and detail is the detailpage of /gallery-n.
Hope you'll understand what i mean?!
EDIT
On the overview page i have a bunch of thumbails which each are linked to the detail gallery (jquery galleriffic) page.

If I'm correct understand your problem you should do this things.
1. Create view1 for page with linked images. It should be page display with http://example.com/images/%nid
where %nid is nid argument of gallery.
2. Create view2 for gallery detailed page. it should be page display with http://example.com/%nid/detail
3. Theme that views as you want.
4. For view1 for image field use override output in field settings to make it links to %nid/detail
P.S. Use relationships where needed. If description is not clear, fill free to ask.

You can try something like this, in a custom module you make (or maybe already have):
where you set the path to the page you want in the menu and set it as a callback that calls a function and then you can render whatever you want, or call whatever you want.
function MODULENAME_menu() {
$items = array();
$items['gallery/%/detail'] = array(
'title' => 'Gallery Detail',
'page callback' => 'MODULENAME_gallery_detail_page',
'page arguments' => array(1),
'access callback' => TRUE,
'type' => MENU_CALLBACK
);
return $items;
}
function MODULENAME_gallery_detail_page($gallery_id) {
// Here you can render the view as a page, using the gallery
// id which you passed as a parameter to this function.
// So Change MYCUSTOMVIEW to the view you want to render
$view = views_get_view('MYCUSTOMVIEW');
print views_build_view('page', $view, array(), false, false);
}
Just change MODULENAME with the name of your module. You might need to do some work when calling the views_build_view, but it should be a start, you can ask some more questions if you like and I'll help out.

Related

Silverstripe tumblr-like Post Types

I am trying to create a back-end interface for silverstripe that gives the CMS user the option to choose between a set of Post Types (like tumblr) in Silverstripe3. So they can choose to create a News Post, Video Post, Gallery Post, etc.
I initially started off giving all Posts the necessary fields for each Type and adding an enum field that allowed the user to choose the Post Type. I then used the forTemplate method to set the template dependent upon which Post Type was chosen.
class Post extends DataObject {
static $db = array(
'Title' => 'Varchar(255),
'Entry' => 'HTMLText',
'Type' => 'enum('Video, Photo, Gallery, Music')
);
static $many_many = array(
'Videos' => 'SiteVideo',
'Photos' => 'SitePhoto,
'Songs' => 'SiteMp3'
);
public function forTemplate() {
switch ($this->Type) {
case 'Video':
return $this->renderWith('VideoPost');
break;
case 'Photo':
return $this->renderWith('ImagePost');
break;
etc...
}
function getCMSFields($params=null) {
$fields = parent::getCMSFields($params);
...
$videosField = new GridField(
'Videos',
'Videos',
$this->Videos()->sort('SortOrder'),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Videos', $photosField);
$photosField = new GridField(
'Photos',
'Photos',
$this->Photos()->sort('SortOrder'),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Videos', $photosField);
return $fields;
}
}
I would rather the user be able to choose the Post Type in the backend and only the appropriate tabs show up. So if you choose Video, only the Video GridField tab would show up. If you choose Photo Type only the Photo's GridField would show.Then I would like to be able to call something like
public function PostList() {
Posts::get()
}
and be able to output all PostTypes sorted by date.
Does anyone know how this might be accomplished? Thanks.
Well the first part can be accomplished using javascript. Check out this tutorial and the docs let me know if you have questions on it.
The second part would be trickier but I think you could do something with the page controller. Include a method that outputs a different template based on the enum value but you would have to set links somewhere.
I managed this with DataObjectManager in 2.4.7 as I had numerous DataObjects and all were included in one page but I'm not sure if that is feasible in SS3.
return $this->renderWith(array('CustomTemplate'));
This line of code will output the page using a different template. You need to include it in a method and then call that method when the appropriate link is clicked.

Create drupal (sub-)menu

OK, so I have a weird thing to do, I'd appreciate any help. When you go to the Drupal admin panel and click Structure, you get a menu which contains Blocks, Content types, Menus and so on.
Is there a way I can programatically build one of those menus based on the path? For example if I have my module named test and all sub-actions of my module are located at www.drupalsite.com/admin/test/action_name, can I build my menu with all the /test/action_name there exist in the current module?
I know there's the option of hard-coding the menu, but I want to avoid it if possible.
It's hard to be that descriptive without some more information but you'd just need to implement hook_menu() and loop through your list of actions, creating a menu item for each. Every time the menu is rebuilt your menu hook will be called and the current list of actions will be built as menu links. Something like this:
function mymodule_menu() {
$actions = mymodule_get_actions_list();
foreach ($actions as $action) {
$items['admin/test/' . $action->name] = array(
'title' => $action->name,
'access arguments' => array('some permission'),
'page callback' => 'mymodule_callback',
'page_arguments' => array($action->name)
);
}
return $items;
}
function mymodule_callback($action_name) {
// Load the action and display the page
}
After you call your custom code to create one of these actions, be sure to call menu_rebuild() so your hook runs and the new action is added to menu.

Menu path with wildcard

You can't use wildcards in menu paths? A quick summary of my problem (which I've made sure makes sense, so you're not wasting your time): I have a menu which i'm showing on node pages of a certain content-type. My path to a node page would be like...
events/instal2010
...where instal2010 would be the name of an event (event is the content-type).
I'm using the Context and Menu Block modules to place a menu in the sidebar on that page...
Event (the default active item)
Programme
Visitor info
Book tickets
... where the path for Programme would be
events/instal2010/programme
So for this to work for many different events, those menu items need a wildcard in their path, e.g.
events/*/programme
Perhaps it's time to ditch menus and just use a block with php to determine what page we're on from the URL.
Any advice from experienced hands would be awsome, thanks.
You cannot create menu items with wildcards from the administrative interface of Drupal, but you can create menu items with wildcards in a module. I would recommend creating a custom module that uses hook_menu() to create the menu items. An example implementation would look something like:
function YOURMODULE_menu() {
$items = array();
$items['events/%/programme'] = array(
'title' => 'Programme',
'description' => 'Loads a program page',
'page callback' => 'YOUR CUSTOM FUNCTION NAME', // Custom function used to perform any actions, display the page, etc
'page arguments' => array(1), // Passes wildcard (%) to your page callback function
'access callback' => TRUE, // Change if you want to control access
'type' => MENU_NORMAL_ITEM, // Creates a link in the menu
'menu_name' => 'primary-links' // Adds the link to your primary links menu, change if needed
);
return $items;
}
In $items['events/%/programme'] = array(, the % is the wildcard and it will be passed to your page callback function. It may be helpful to read more about hook_menu() and the Anatomy of hook_menu may also help as well.

Drupal 6 - force page view to display a different view?

Kind-of a crazy question here...
I have a view display that's set up as a page. It looks great in theme A (desktop), but terrible in theme B (mobile). So I made a different version of the view for theme B. Since the desktop/mobile 'sites' are the same just with different themes, the url for this page will be the same regardless of hte theme selected.
So I would like to be able to point the user to:
mysite/this_crazy_view
and have the returned page select the proper view depending on which theme it's in. I know that if I were using blocks I would just assign the appropriate blocks to the page in question on a theme-by-theme basis, but since the displays are using page display I don't know what the right approach would be.
I would rather not rebuild the views as blocks if I can help it (if it can't be helped, so be it...) so I was hoping there was some way to conditionally load the view via the tpl.php file or something like that...
The code I'm using in my module (per #Clive 's recommendation below) is:
<?php
function bandes_custom_hook_menu() {
$items['charley_test'] = array(
'title' => 'Title',
'access arguments' => array('access content'),
'page callback' => 'bandes_custom_set_page_view',
'type' => MENU_NORMAL_ITEM );
return $items;
}
function bandes_custom_set_page_view() {
global $theme_key;
$view_name = $theme_key == 'mobile_jquery' ? 'course_views_mobile' : 'course_views';
$display_id = 'page_5';
return views_embed_view($view_name, $display_id);
}
?>
I've cleared the cache a number of times and tried a variety of different paths in the $items array. The course_views and course_views_mobile both definitely work on their own.
I was also wondering if I could just create a views-view--course-views--page-5.tpl.php which contains almost nothing aside from the views_embed_view(course_views_mobile, page_5) part? (Only on one of the two themes...)
Actually I think the answer was simpler than all of the above. The redirect thing was giving me fits, so I removed the module, reset the paths to what I had been using, and tried the template/theme approach instead.
This is: views-view--course-views--page-5.tpl.php, only used on the mobile theme, but referring to the non-mobile view (kinda gives me a headache, but it works)
<?php
//get the view
print "IM IN YR VUE, MESSING THNGZ UP!"; //yeah, I'm going to remove this part...
$view_name="course_views_mobile";
$display_id="page_5";
print views_embed_view($view_name, $display_id);
?>
Any reason that shouldn't work? (Or why it is a really bad idea?)
Me again :)
I just thought of an easy-ish way around this actually; if you can change the URL of your views to something other than the path you want to access them at (any path would do) you could implement a hook_menu() function in a custom module for that path, to make the choice depending on your theme:
function MYMODULE_hook_menu() {
$items['this_crazy_view'] = array(
'title' => 'Title',
'access arguments' => array('access content'),
'page callback' => 'MYMODULE_crazy_view_page',
'type' => MENU_CALLBACK // or MENU_NORMAL_ITEM if you want it to appear in menus as usual
);
return $items; // Forgot to add this orginally
}
function MYMODULE_crazy_view_page() {
global $theme_key;
$view_name = $theme_key == 'foo' ? 'theView' : 'theOtherView';
$display_id = 'page_1'; // Or whatever the page display is called
return views_embed_view($view_name, $display_id);
}
That should do the trick

Drupal pass argument to page

I have a custom Drupal module displaying some data in a table. Each row has a link which if clicked will delete the relevant row. Specifically, when the link is clicked it will take the user to a confirmation page. This page is really just a drupal form which says 'are you sure' with two buttons: 'Yes', 'No'. I figure I will need to pass the rowID to the confirmation page.
My question: What is the typically way to pass data to a new page in Drupal 7? I guess I could just add the rowID to the URL and use the $_GET[] from the confirmation page... I don't think this is very safe and was wondering if there was a better 'Drupal' way.
Thanks!
You'd use something like the following
<?php
function yourmod_menu() {
// for examlple
$items['yourmod/foo/%/delete'] = array(
'title' => 'Delete a foo',
'page callback' => 'drupal_get_form',
'page arguments' => array('youmode_foo_delete_confirm', 2), // 2 is the position of foo_id
'access arguments' => array('delete foo rows'),
'type' => MENU_CALLBACK,
);
return $items;
}
function yourmod_foo_delete_confirm($form, &$form_state, $foo_id) {
// load the row
$foo = yourmod_get_foo($foo_id);
// build your form, if you need to add anything to the confirm form
// ....
// Then use drupal's confirm form
return confirm_form($form,
t('Are you sure you want to delete the foo %title?',
array('%title' => $foo->title)),
'path/to/redirect',
t('Some description.'),
t('Delete'),
t('Cancel'));
}
?>
You can look here for examples of how core modules do it (have look at node_delete_confirm)
The simplest solution would be to use an existing module created for this purpose:
http://drupal.org/project/entityreference_prepopulate (for entity references)
http://drupal.org/project/nodereference_url (for node references)
http://drupal.org/project/prepopulate (for other form values)
You can configure which form values can be set from the URL, then rewrite the fields displayed in your table to generate the necessary links.
If the data are nodes, you can make the link node/%/delete where % is the nid. Drupal knows how to handle the delete page, as its a core path. Then, the delete confirmation follows the rest of the system and is very 'Drupal'.
I am not sure if this changed at all in Drupal 7, but this is what I did for countless modules.

Resources