To select a template through the Wordpress REST api you normally assign the 'template' key a value. However, you don't appear to be able to select specific Elementor templates the same way. That is to say, the error only gives "elementor_canvas" and "elementor_header_footer" as options next to Wordpress defaults.
If I wanted to assign Elementor’s Full Width Page Template to a post, is there a way to do this via the Wordpress REST api or programmatically via a workaround?
def create_page(title):
post = {
'title' : title,
'status' : 'publish',
'template' : 'elementor_canvas'
}
response = requests.post(url + '/pages', headers=header, json=post)
A workaround involves creating an Elementor template then using the sortcode as the content of the post e.g.
def create_page(title):
post = {
'title' : title,
'status' : 'publish',
'content' : '[elementor-template id="1159"]'
}
Related
I want to create a full page, custom module. By this, I mean a module that is not wrapped into the main Drupal sites them. Here is my code:
myapp.module:
function myapp_menu()
{
$result = array();
$result['myapp/home'] = array(
'title' => 'My App Title', // Title of our page
'description'=> 'My App Web Site', // Description of our page
'page callback' => 'myapp_function',
'access arguments' => array('access content'), // permission to access this page
'type' => MENU_NORMAL_ITEM, // type of menu item
);
return $result;
}
function myapp_function(){
return theme('my_custom_template');
}
function myapp_theme(){
return array(
'my_custom_template' => array(
'template' => 'myapp-page',
),
);
}
myapp-page.tpl.php
Hello World
The problem is that, when the page is displayed, it is still kept within the main Drupal Sites main theme. I would like to make this page its own, full page, site. Can anyone help with doing this?
thanks
You can hack like this :
function myapp_function(){
print theme('my_custom_template');
exit;
}
Also you can use declaration options listed in https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_theme/7.x
Parameters
array $existing: An array of existing implementations that may be used
for override purposes. This is primarily useful for themes that may
wish to examine existing implementations to extract data (such as
arguments) so that it may properly register its own, higher priority
implementations.
$type: Whether a theme, module, etc. is being processed. This is
primarily useful so that themes tell if they are the actual theme
being called or a parent theme. May be one of:
'module': A module is being checked for theme implementations.
'base_theme_engine': A theme engine is being checked for a theme that
is a parent of the actual theme being used. 'theme_engine': A theme
engine is being checked for the actual theme being used. 'base_theme':
A base theme is being checked for theme implementations. 'theme': The
actual theme in use is being checked. $theme: The actual name of
theme, module, etc. that is being being processed.
$path: The directory path of the theme or module, so that it doesn't
need to be looked up.
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.
I created a new page which is assigned a custom template. When I visit that page's url I see what appears to be the default page layout (not my template) and the admin toolbar shows options pertaining to media (ex: Edit media).
After some head scratching, I deduced that somehow that url must point to a media item. I edited the page slug and "bingo" the actual page appears just as expected. When I visit the original url (from the first slug) I see the same media item.
Bottom line: It appears that coincidentally the page and the media item share the same name, and this was somehow causing WP's wires to get crossed.
My question: Can someone help me understand how/why this happens? Does wordpress create magic permalinks to everything in the media library (other than their location in wp-content/uploads/...)?
Note: The media item was uploaded normally into the media library (not FTP into the root directory, etc)
Yes, in WordPress you cannot have duplicate slugs/categories/taxonomies/tags. So if your theme allows for media files and permalinks to have their own page and the slug is the same as another one, it will usually append a number to it because the database does not like it.
media slug "example"
page slug "example" will not work since that slug exists already , if done in the admin it will automatically change the slug to "example-1".
I just had this problem and fixed it like this:
$post_s=get_posts('posts_per_page=-1');
foreach($post_s as $p){
$atts = get_posts('post_type=attachment&name='.$p->post_name.'&posts_per_page=-1&post_status=inherit');
foreach($atts as $att){
echo 'found!! '.$p->post_name;
// Update post 37
$my_post = array(
'ID' => $atts->ID,
'post_name' => $att->post_name.'-image'
);
// Update the post into the database
wp_update_post( $my_post );
}
}
This is a late answer, but I wanted to give a cleaner version of the answer that alesub gave.
function wp21418_append_to_post_name() {
// Checks to see if the option images_updated has been set or has a value of true.
if ( get_option( 'images_updated' ) === 'true' ) :
return;
endif;
// get all attachment posts.
$attachments = get_posts([
'post_type' => 'attachment',
'post_status' => 'inherit',
'name' => $p->slug,
'posts_per_page' => -1,
]);
// For each attachment, loop and update the post_name
foreach($attachments as $p){
$attachment = array(
'ID' => $p->ID,
'post_name' => $p->post_name.'-image'
);
// Update the post into the database
wp_update_post( $attachment );
}
// Once everything is looped, add the option to the database.
add_option( 'images_updated', 'true' );
}
add_action( 'after_setup_theme', 'wp21418_append_to_post_name' );
This function runs on an action hook right after the theme has setup. The first line checks to see if there is an option in the database images_updated. If that option exists, we bail on the function and it doesn't do any processing. Otherwise, if the option does not exist, it runs the function and sets the option at the very end.
This makes it so it will only run once. You don't have to remove the function after refresh. If you want to run it again, you can simply remove the if statement at the top. As a caveat: doing this will add another -image at the end of post_names even if they have -image already (e.g. -image-image)
There could be more file name checking for that situation. Will update the answer with that if someone really needs it.
I tried one of the suggested solutions, and ended up having attachment pages like /bob-image-image-image-image/.
I'd suggest that instead of using alesub or disinfor's code blindly, use a better option in the form of "Disable Media Pages" plugin.
https://github.com/joppuyo/disable-media-pages
It automatically sets all attachment slugs to an unique id, and there is the option to mangle any existing attachment slugs so they won't cause any issues in the future.
I want to create my own custom posting interface for my Wordpress blog, my reason for this is because I post multiple articles, sometimes ranging from 100-150 articles per day, and I want to simplify the process of posting an article, like batch posting articles.
I did my research and I found that Wordpress XMLRPC and MetaWeblog API is what I need.
So I tried it and I successfully post an article to my blog using this code:
<?php
include("../wp-includes/class-IXR.php");
$client = new IXR_Client('http://www.example.com/xmlrpc.php');
$content['title'] = 'Test Draft Entry using MetaWeblog API';
$content['description'] = '<p>Hello World!</p>';
if (!$client->query('metaWeblog.newPost','', 'admin',’password’, $content, false)) {
die('An error occurred - '.$client->getErrorCode().":".$client->getErrorMessage());
}
echo $client->getResponse();
?>
But for each post that I create in my Wordpress blog requires several step:
Step 1: Create a new Background with a Background type of Youtube and enter the Youtube ID of this background.
Step 2: Add a new post and attach the previously published background to this post.
Step 3: Enter a custom field called artist_id in the custom field section and add an excerpt for this post, publish the post.
So, each article needs 3 steps. So my question is, how can I use the XMLRPC to perform these actions?
For adding excerpts use
$content['mt_excerpt'] = 'Your post excerpt';
For custom fields use
$content['custom_fields'] = array(
array( 'key' => 'artist_id', 'value' => '777' ),
array( 'key' => 'background', 'value' => 'background_value' )
);
Background and youtube metaboxes will most likely add custom post meta. You can find the key for them from db or source code and use it in above code.
I need to use the nid of a node as field in a content type: i need to choose where to print it (put it before some fields but after others) and format it as i wish. the only thing i could think about is create a "fake" custom field with no widget to insert it buth with a theme formatter to display it but it seems to me that this is a little to complicated. How should i do it?
If I understand correctly, you just want to expose data to the node view. Could it be as easy as using hook_node_view() from a module?
With that, you can set a 'fake' field to be sent out to the content array of the node, which you can access in the node template.
From drupal.org:
<?php
function hook_node_view($node, $view_mode, $langcode) {
$node->content['my_additional_field'] = array(
'#markup' => $additional_field,
'#weight' => 10,
'#theme' => 'mymodule_my_additional_field',
);
}
?>