Is there a way to get a list of products with their current canonical url on command line?
class Mage_Shell_UrlTest extends Mage_Shell_Abstract
{
public function run()
{
$productCollection = Mage::getResourceModel('catalog/product_collection')
->addStoreFilter()
->addUrlRewrite()
->addAttributeToSelect('*')
->setPageSize(10) // just for testing
->addFieldToFilter('visibility',Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
->addAttributeToFilter('status', array(
'eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED
));
Mage::getSingleton('cataloginventory/stock')
->addInStockFilterToCollection($productCollection);
foreach ($productCollection as $product) {
$url = $product->getUrlModel()->getUrl($product, array('_ignore_category' => true));
echo PHP_EOL . $url . PHP_EOL; // debug output
}
}
}
$shell = new Mage_Shell_UrlTest();
$shell->run();
I run it with php -f magento/shell/urlTest.php and this gives me something like this:
http://www.domain.com/urlTest.php/catalog/product/view/_ignore_category/1/id/307/s/any_valid_product_url_key
By default magento uses the same code to get the canonical url in Mage_Catalog_Block_Product_View::_prepareLayout() so the code should be fine. The only difference is for which store the code is executed.
It doesn't work in shell scripts because they are executed for the admin store (see Mage_Shell_Abstract::__construct() where Mage::app() is initialized). You could use Mage::app()->setCurrentStore('default'); where you need to replace default by your store and the right urls should be printed.
I maybe do not understand properly what you mean by "canonical url" but if you mean the url of the product with its ID and the key at the end that is normally the "canonical url" for magento as it is supposed to be unique at a moment, you should just take away the params of the getUrl. If you do not want the key, you can still use :
$url = substr($url, 0, strrpos('/s/'));
I hope it helps, if not, please precise the result you want.
Related
I need to update values in all posts of a wordpress installation on a regular base. I was gooing to use shortcodes to insert the request into the wordpress post. Then use a custom functions.php that holds all the variables that need to be updated from time to time.
I got it working. Somehow but not the way I intended to use it. I'm a total beginner. Please consider this when answering my questions.
I want to have a function that reads what comes after honda_ and displays the correct value in wordpress without having to create a separate shortcode for each variable.
When entering [honda_link] wordpress should display the value from honda_link. When entering [honda_longlink] the value from honda_longlink variable should get displayed. I don't want to create a shortcode for each value.
I came up with this as a working solution...
// Honda
function honda() {
$honda_link = 'www.honda.com';
$honda_longlink = 'http://www.honda.com';
$honda_free = 'Free';
$honda_new = '23.688 $';
$honda_mileage = '00';
return $honda_link;
}
add_shortcode('neu', 'honda_link');
I tried some approaches by using an array but it ultimately failed all the time. I also tried it with if statements but wasn't able to get the right value displayed.
Someone willing to help a noob? I think I need to see a working example in order to understand it. The code snippets I have been looking at (that do something similiar but not the same I want to achieve) did confuse me more than they helped me.
I came up with this / Which works in a way but... This isn't very comfortable to use.
add_shortcode('HONDA','HONDA_TEST');
function HONDA_TEST($atts = array(), $content = null, $tag){
shortcode_atts(array(
'var1' => 'default var1',
'var2' => false,
'var3' => false,
'var4' => false
), $atts);
if ($atts['var2'])
return 'honda2';
else if ($atts['var3'])
return 'honda3';
else if ($atts['var4'])
return 'honda4';
else
return 'honda1';
}
So now when using:
[HONDA var1="novalue"][/HONDA]
[HONDA var2="novalue"][/HONDA]
[HONDA var3="novalue"][/HONDA]
[HONDA var4="novalue"][/HONDA]
it shows:
honda1
honda2
honda3
honda4
and so on.
Is there a better way to achieve the intended goal from post #1 ? Any way I could import the $variables from 1st post in bulk for example?
I don't have a working WP setup right now to test, but could you try this:
add_shortcode('HONDA','HONDA_TEST');
function HONDA_TEST($atts = array(), $content = null, $tag){
$atts = shortcode_atts(array(
'model' => 1,
), $atts);
$myHondas = [1 => 'honda1', 'honda2', 'honda3'];
return isset($myHondas[$atts['model']]) ? $myHondas[$atts['model']] : 'unknown model id';
}
And use it with [HONDA model="1"], [HONDA model="2"]
I have the below function to create active trail functionality. So if I were to have /blog as a "parent" and a post of /blog/mypost, when on mypost the blog link would show as highlighted. I don't want to have to make menu items for all the blog posts. The problem is when caching is turned on (not using settings.local.php and debug turned off) the getRequestUri isn't changing on some pages. It seems to be cached depending on the page. It works fine with page caching turned off but I'd like to get this working with caching. Is there a better way to check for the current path and apply the active class?
function mytheme_preprocess_menu(&$variables, $hook) {
if($variables['theme_hook_original'] == 'menu__main'){
$node = \Drupal::routeMatch()->getParameter('node');
if($node){
$current_path = \Drupal::request()->getRequestUri();
$items = $variables['items'];
foreach ($items as $key => $item) {
// If current path starts with a part of another path i.e. a parent, set active to li.
if (0 === strpos($current_path, $item['url']->toString())) {
// Add active link.
$variables['items'][$key]['attributes']['class'] .= ' menu-item--active-trail';
}
}
}
}
}
I've also tried putting this into a module to try and see if I can get the current path to then do the twig logic in the menu--main.twig.html template but I have the same problem.
function highlight_menu_sections_template_preprocess_default_variables_alter(&$variables) {
$variables['current_path'] = $_SERVER['REQUEST_URI'];
}
After a very long time trying all sorts of things, I found an excellent module which addresses exactly this problem. Install and go, not configuration, it just works:
https://www.drupal.org/project/menu_trail_by_path
Stable versions for D7 and D8.
I tried declaring an active path as part of a custom menu block, and even then my declared trail gets cached. Assuming it's related to the "There is no way to set the active link - override the service if you need more control." statement in this changelog, though why MenuTreeParameters->setActiveTrail() exists is anybody's guess.
For the curious (and for me when I search for this later!), here's my block's build() function:
public function build() {
$menu_tree = \Drupal::menuTree();
$parameters = new MenuTreeParameters();
$parameters->setRoot('menu_link_content:700c69e6-785b-4db7-be49-73188b47b5a3')->setMinDepth(1)->setMaxDepth(1)->onlyEnabledLinks();
// An array of routes and menu_link_content ids to set as active
$define_active_mlid = array(
'view.press_releases.page_1' => 385
);
$route_name = \Drupal::request()->get(RouteObjectInterface::ROUTE_NAME);
if (array_key_exists($route_name, $define_active_mlid)) {
$menu_link = \Drupal::entityTypeManager()->getStorage('menu_link_content')->loadByProperties(array('id' => $define_active_mlid[$route_name]));
$link = array_shift($menu_link);
$parameters->setActiveTrail(array('menu_link_content:' . $link->uuid()));
}
$footer_tree = $menu_tree->load('footer', $parameters);
$manipulators = array(
array('callable' => 'menu.default_tree_manipulators:checkAccess'),
array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
);
$tree = $menu_tree->transform($footer_tree, $manipulators);
$menu = $menu_tree->build($tree);
return array(
'menu' => $menu,
);
}
[adding a new answer since this is a completely different approach than my earlier one]
If a CSS-based solution is acceptable, this seems to work okay:
.page-node-type-press-release {
a[data-drupal-link-system-path="press-room/press-releases"] {
// active CSS styles here
}
}
I'm stuck trying to get joomla full article to render in a tab. The tab is working. I just canĀ“t render the article content. This is where I am now.
This is helper.php
public static function getArticle($articleId)
{
JModelLegacy::addIncludePath(JPATH_SITE.'/components/com_content/models', 'ContentModel');
$model = JModelLegacy::getInstance('Article', 'ContentModel', array('ignore_request' => true));
$article = $model->getItem((int) $articleId);
$fullarticle = $item->fulltext;
$itemsHtml = '<div>'. $fullarticle .'</div>';
return $itemsHtml;
}
And this is in default.php
...code...
else if ($list_of_tabs['use'][$i][0] == 'article'){
echo '<div class="tab-pane '.$active.'" id="'.$i.$rid.'">'.
modJpTabsHelper::getArticle($list_of_tabs['article'][$i], $params) .
'</div>';
}
...code...
If you need more info. Don't hesitate to ask.
What are you trying to achieve: to write your own Joomla! extension which displays articles in a tab or you just need to display your J! articles in a tab?
If it's a latter, then there are already some nice and free (as in a "free bear") add-ons written just for that.
You are trying to use the model part of an MVC as a thing to render.
You should use the MVC system - using a controller to gathering the model and the view, and then you can render the model with the attached view, via the controller.
So you use something like (I've not tested this - you will need to correct it).
$filter=array('id' => $i->query['id']);
$options=array('filter_fields' => $filter,'ignore_request' => true);
$ctl = new ContentModelController();
$view = $ctl->getView( 'Article');
$model = $ctl->getModel( 'Article','',$options);
you may need to set params from application, eg..
$model->setState('params', JApplication::getInstance('site')->getParams());
then continue
$view->setModel( $model, true );
$result = $view->display();
Make sure that you have JLoader::import'ed any classes/classpaths - j. tends to fail silently if they aren't found, which can be difficult to trace.
Sorry, it's only a partial solution - but hopefully it may put you on the right track.
Here was the problem:
$fullarticle = $item->fulltext;
Article object from model was in variable $article not $item:
$article = $model->getItem((int) $articleId);
So getting property fulltext from article object should be:
$fullarticle = $article->fulltext;
I'm trying to write a product filter extension for opencart.
I assign size, color etc. options to the url like this:
index.php?route=product/category&path=59_63&size=57&color=black
The problem is when I click another color on the page the link goes like this:
index.php?route=product/category&path=59_63&size=57&color=black&color=brown
As you can see there are duplicated color arguments and it messes up the category listing.
How can I remove same arguments if there is?
The original opencart's link builder function:
public function link($route, $args = '', $connection = 'NONSSL') {
if ($connection == 'NONSSL') {
$url = $this->url;
} else {
$url = $this->ssl;
}
$url .= 'index.php?route=' . $route;
if ($args) {
$url .= str_replace('&', '&', '&' . ltrim($args, '&'));
}
return $this->rewrite($url);
}
There is not enough information to provide a correct answer, but I'll take a guess.
The problem seems to be with $args. It seems that you are taking $args from the URL and append to it your new color parameter.
If URL is index.php?route=product/category&path=59_63&size=57&color=black, then $args is path=59_63&size=57&color=black
You append to it color=brown and $args becomes path=59_63&size=57&color=black&color=brown.
If this is the case, you can do something like this:
parse_str($args,$url_params);
$url_params['color'] = 'brown'; //-- overwrites color=black with color=brown
$args = http_build_query($url_params);
Then pass $args to your link() function.
you don't have to remove duplicate parameters.
uou have not to add it.
use http_build_query() to create a query string
This is really nothing to do with opencart's link builder, it's done outside of that so as not to make any core changes. You need to set the value when you use $this->url->link in your controller code for your category. When you are getting all of the colors that you will use for filters, be sure to unset the color attribute passed into the second parameter of the link
I need to make a simple site search with pagination in it; could anyone tell me how to do it without affecting the URL structure? Currently I'm using the default CodeIgniter URL structure and I have removed index.php from it. Any suggestions?
You could just use a url like /search/search_term/page_number.
Set your route like this:
$route['search/:any'] = "search/index";
And your controller like this:
function index()
{
$search_term = $this->uri->rsegment(3);
$page = ( ! $this->uri->rsegment(4)) ? 1 : $this->uri->rsegment(4);
// some VALIDATION and then do your search
}
Just to update this question. It is probably best to use the following function:
$uri = $this->uri->uri_to_assoc()
and the result will then put everything into an associative array like so:
[array]
(
'name' => 'joe'
'location' => 'UK'
'gender' => 'male'
)
Read more about the URI Class at CodeIgniter.com
Don't quite understand what you mean by "affecting the url structure". Do you mean you'd want pagination to occur without the URL changing at all?
The standard pagination class in CI would allow you to setup pagination so that the only change in the URL would be a number on the end
e.g if you had 5 results to a page your urls might be
http://www.example.com/searchresults
and then page 2 would be
http://www.example.com/searchresults/5
and page 3 would be
http://www.example.com/searchresults/10
and so on.
If you wanted to do it without any change to the URL then use ajax I guess.
Code Igniter disables GET queries by default, but you can build an alternative if you want the url to show the search string.
Your url can be in the notation
www.yoursite.com/index.php/class/function/request1:value1/request2:value2
$request = getRequests();
echo $request['request1'];
echo $request['request2'];
function getRequests()
{
//get the default object
$CI =& get_instance();
//declare an array of request and add add basic page info
$requestArray = array();
$requests = $CI->uri->segment_array();
foreach ($requests as $request)
{
$pos = strrpos($request, ':');
if($pos >0)
{
list($key,$value)=explode(':', $request);
if(!empty($value) || $value='') $requestArray[$key]=$value;
}
}
return $requestArray ;
}
source: http://codeigniter.com/wiki/alternative_to_GET/