I am using simplenews module to multiple subscription for post
simplenews module provide a block section, but i need to change layout of design.
this is part of the code of "function template_preprocess_block(&$variables)"
$variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->region;
$variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module;
// Hyphens (-) and underscores (_) play a special role in theme suggestions.
// Theme suggestions should only contain underscores, because within
// drupal_find_theme_templates(), underscores are converted to hyphens to
// match template file names, and then converted back to underscores to match
// pre-processing and other function names. So if your theme suggestion
// contains a hyphen, it will end up as an underscore after this conversion,
// and your function names won't be recognized. So, we need to convert
// hyphens to underscores in block deltas for the theme suggestions.
$variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module . '__' . strtr($variables['block']->delta, '-', '_');
You can create some of the suggestions as a .tpl file in your theme, or just a basic block.tpl.php in your theme
Related
I'm using hook_theme_suggestions_HOOK_alter() to add theme hook suggestions for page.html.twig based on the content type:
function mytheme_theme_suggestions_page_alter(array &$suggestions, array $variables) {
$node = \Drupal::request()->attributes->get('node');
$suggestions[] = 'page--node--' . $node->getType();
}
Now my twig debug mode picks this up:
<!-- FILE NAME SUGGESTIONS:
* page--node--case.html.twig (new suggestion based on content type 'case')
* page--node--3.html.twig
* page--node--%.html.twig
* page--node.html.twig
x page.html.twig
-->
However, when I make a file called page--node--case.html.twig, it is not being rendered. Instead, page.html.twig is being used.
Anyone know what's going on?
I found out what was going wrong.
Apparently, when defining new suggestions, Drupal needs underscores instead of dashes. Then Drupal converts these underscores into dashes so that the actual file name will still be page--node--case.html.twig
So:
$suggestions [] = 'page--node--'.$node->gettype();
Should be: $suggestions [] = 'page__node__'.$node->gettype();
Documentation:
https://www.drupal.org/node/2186401
How can I use the localization mechanism in WordPress to get access to an existing but not-current language string?
Background: I have a custom theme where I use locale 'en_US' as the default locale and translate through a PO file to locale 'es_ES' (Spanish).
Let us say I use the construction
__('Introduction', 'my_domain');
in my code, and that I have translated 'Introduction' to the Spanish 'Introducción´ in my PO file. All this works fine.
Now to the problem: I want to insert n records in my database with all existing translations of the string 'Introduction' - one for each language; so, n = 2 in my example.
Ideally, I would write something like this:
$site_id = 123;
// Get an array of all defined locales: ['en_US', 'es_ES']
$locales = util::get_all_locales();
// Add one new record in table details for each locale with the translated target string
foreach ($locales as $locale) {
db::insert_details($site_id, 'intro',
__('Introduction', 'my_domain', $locale), $locale);
}
Only, that the 3rd parameter in __() above is pure fantasy on my part. You can only validly write
__('Introduction', 'my_domain');
to get either 'Introduction' or 'Introducción' depending on the current locale.
The outcome of the code above would ideally be that I end up with two records in my table:
SITE_ID CAT TEXT LOCALE
123 intro Introduction en_US
123 intro Introducción es_ES
I am aware that I want something that requires loading all the MO files, where normally, only the MO file for the current language is required. Maybe use of the WordPress function load_textdomain is necessary - I was just hoping there already exists a solution.
Expanding on the question by including the plugin PolyLang: is it possible to use Custom Strings to achieve the above functionality? E.g. conceptually:
pll_('Introduction', $locale)
Old question I know, but here goes -
Starting with a simple example where you know exactly what locales to load and exactly where the MO files are, you could use the MO loader directly:
<?php
$locales = array( 'en_US', 'es_ES' );
foreach( $locales as $tmp_locale ){
$mo = new MO;
$mofile = get_template_directory().'/languages/'.$tmp_locale.'.mo';
$mo->import_from_file( $mofile );
// get what you need directly
$translation = $mo->translate('Introduction');
}
This assumes your MO files are all under the theme. If you wanted to put more of this logic through the WordPress's environment you could, but it's a bit nasty. Example:
<?php
global $locale;
// pull list of installed language codes
$locales = get_available_languages();
$locales[] = 'en_US';
// we need to know the Text Domain and path of what we're translating
$domain = 'my_domain';
$mopath = get_template_directory() . '/languages';
// iterate over locales, finally restoring the original en_US
foreach( $locales as $switch_locale ){
// hack the global locale variable (better to use a filter though)
$locale = $switch_locale;
// critical to unload domain before loading another
unload_textdomain( $domain );
// call the domain loader - here using the specific theme utility
load_theme_textdomain( $domain, $mopath );
// Use translation functions as normal
$translation = __('Introduction', $domain );
}
This method is nastier because it hacks globals and requires restoring your original locale afterwards, but it has the advantage of using WordPress's internal logic for loading your theme's translations. That would be useful if they were in different locations, or if their locations were subject to filters.
I also used get_available_languages in this example, but note that you'll need the core language packs to be installed for this. It won't pick up Spanish in your theme unless you've also installed the core Spanish files.
I have created a view page which shows all the work project thumbnails by default and then there is a block included on the page which filters the view (but not using ajax) it just added the company name into the url and it filters using contexual filters. The thumbnails in the grid take you to the project node page. I would like to include the filter sidebar block on all of the urls under www.sitename.com/work, so work & work/companyname/ but not on the node page which is www.sitename.com/work/companyname/projectname.
I have tried all possible ways of doing it within the path field.
work
work/*
work/*/~
work/*/~/
work/*/~/~
Is there anyway to include this block on all paths work/companyname but not any deeper?
You could enable the core PHP Filter module. Then you can use php to set the block visibility e.g. using preg_match().
If you're not sure about regex take a look at http://www.regextester.com/.
EG to show block in admin and admin/structure but not admin/structure/blocks etc:
<?php
return preg_match('/^admin(\/structure)?(\/)?$/', $_GET['q']);;
?>
What you are looking for is support for globbing (https://github.com/begin/globbing#wildcards). Unfortunately, Drupal does not support globbing out of the box.
In modern globbing implementation, * would match on any character but /, and ** would match on any character, including /.
In order to implement this support, one would need to:
Look how PathMatcher (core/lib/Drupal/Core/Path/PathMatcher.php) service matches the path.
Extend it into own custom service where only matchPath() will be overridden.
Replace the content of matchPath() with the code below (this is a copy of the original matchPath() with some alterations).
Alter included service to use your custom path matching (for block only or whole site).
Update configuration of blocks to use ** for full path matching and * for subpath only.
/**
* {#inheritdoc}
*/
public function matchPath($path, $patterns) {
if (!isset($this->regexes[$patterns])) {
// Convert path settings to a regular expression.
$to_replace = [
// Replace newlines with a logical 'or'.
'/(\r\n?|\n)/',
'/\\\\\*\\\\\*/',
// Quote asterisks.
'/\\\\\*/',
// Quote <front> keyword.
'/(^|\|)\\\\<front\\\\>($|\|)/',
];
$replacements = [
'|',
'.*',
'[^\/]*',
'\1' . preg_quote($this->getFrontPagePath(), '/') . '\2',
];
$patterns_quoted = preg_quote($patterns, '/');
$this->regexes[$patterns] = '/^(' . preg_replace($to_replace, $replacements, $patterns_quoted) . ')$/';
}
return (bool) preg_match($this->regexes[$patterns], $path);
}
Note that this code only adds additional token replacement ** and alters what * token does (any character but /).
The Shortcode API states that you can't have square brackets in your attribute. Thus, the following would not work:
[tag attribute="[Some value]"]
In my case, the square bracket is required. What would be the best solution of getting around this problem? I've already tried escaping the content in my shortcode function, but had no luck.
I am using WordPress 3.3.1.
Use some other special character in your shortcode and replace it square brackets in your shortcode function. - Since this is not what you want, here's an alternative.
This seems to be the only thing that I can think of that will work in your case, instead of relying on the Shortcode API, you can use "apply_filters" on the content, and then use preg_replace to write your own shortcode processing function.
If the brackets appear as part of the HTML generated try to use &#...; or as part of an URL use %... .
Otherwise, if it concerns your own shortcode, just replace some other character, e.g. {} by [], inside the code of the shortcode.
If it's not your own shortcode, you might modify the plugin / core. I'd write a wrapper code in order not to break updates.
We store json in shortcode attributes. We decided to use base64_encode to hide square brackets, but we faced some problems:
Themecheck complains about base64 functions
When you want to make some replace in database, for e.g. to replace all old site urls with new site url, the regex can't see what's inside a base64 encoded string
There is another solution, using htmlentities
function encode($str) {
$str = htmlentities($str, ENT_QUOTES, 'UTF-8');
// http://www.degraeve.com/reference/specialcharacters.php
$special = array(
'[' => '[',
']' => ']',
);
$str = str_replace(array_keys($special), array_values($special), $str);
return $str;
}
function decode($str) {
return html_entity_decode($str, ENT_QUOTES, 'UTF-8');
}
$original = '[1,2,3,"&",{a:1,b:2,"c":"Результат"}]';
$encoded = encode($original);
$decoded = decode($encoded);
echo "Original:\t", $original, PHP_EOL;
echo "Shortcode:\t", '[hi abc="'. $encoded .'"]', PHP_EOL;
echo "Decoded:\t", $decoded, PHP_EOL;
echo "Equal:\t\t", ($original === $decoded) ? 'YES' : 'NO';
Output
Original: [1,2,3,"&",{a:1,b:2,"c":"Результат"}]
Shortcode: [hi abc="[1,2,3,"&",{a:1,b:2,"c":"Результат"}]"]
Decoded: [1,2,3,"&",{a:1,b:2,"c":"Результат"}]
Equal: YES
http://ideone.com/fNiOkD
I am using Drupal 6.16 with a number of modules installed. I was trying to find out if there is a way to change the output of a node when a different file extension is added to the url. For example:
http://example.com/drupal?q=foo/bar - returns a normal drupal node
http://example.com/drupal?q=foo/bar.xml - returns xml output of the node
Is this even possible with Drupal? Do I have to hack the core code to get this working?
You should not need to hack the core code. There are probably several contributed modules that can do this for you.
To output an XML version of a node, check out the Views Bonus Pack module, which extends the Views module. It has basic export capabilities, including CSV, TXT, DOC, and XML. The documentation is brief, but there is a README.txt file in the views_bonus/export/ directory that gives the basic steps for creating a feed in a view that will output XML.
You can set the path for the feed, so while I don't believe the .xml extension will work, you could set up a path with an additional component like this:
http://example.com/drupal?q=foo/bar <-- normal output
http://example.com/drupal?q=foo/bar/xml <-- XML output
To change the template file that is used for a node based on the path, you can use a preprocess function in your template.php file to add a template suggestion based on the path. This takes a bit more understanding of how the template files work, but ultimately you'll have more control of the output than you will with a view.
Here is how I fixed this.
Add the custom_url_rewrite_inbound function to check for incoming request ending with .xml. If it finds a request ending with .xml it strips that off, so that the correct data can be located by the rest of the drupal machinery. It also sets 'subsite_xml_request' to true so that the appropriate theme template can be used later.
function custom_url_rewrite_inbound (&$result, $path, $path_language) {
if(preg_match('/\.xml$/', $path)) {
$search = preg_replace('/^(.*)\.xml$/', "$1", $path);
if ($src = drupal_lookup_path('source', $search, $path_language)) {
$_REQUEST['xml_request'] = true;
$result = $src;
}
}
Modify the phptemplate_preprocess_page function in your template.php to add additional '-xml' templates.
function phptemplate_preprocess_page(&$vars) {
if ($_REQUEST['xml_request']) {
if (module_exists('path')) {
$path = str_replace('/edit','',$_GET['q']);
$alias = drupal_get_path_alias($path);
if ($alias != $_GET['q']) {
$template_filename = 'page';
foreach (explode('/', $alias) as $path_part) {
$template_filename = $template_filename . '-' . $path_part;
$vars['template_files'][] = $template_filename . '-xml';
}
$vars['template_files'][] = 'page-xml';
}
}
}
}
Create the required page-xml.tpl.php