FINAL suepr merge step : added all modules to this super repos
This commit is contained in:
285
sites/all/modules/contrib/seo/metatag/CHANGELOG.txt
Normal file
285
sites/all/modules/contrib/seo/metatag/CHANGELOG.txt
Normal file
@@ -0,0 +1,285 @@
|
||||
Metatag 7.x-1.x-dev, xxxx-xx-xx
|
||||
-------------------------------
|
||||
#1995284 by DamienMcKenna: Replace $_SERVER['REQUEST_URI'] with request_uri().
|
||||
By DamienMcKenna: Updated the README.txt's Credits section to match the project
|
||||
page.
|
||||
#1978708 by DamienMcKenna: Added a note to the README.txt, hook_install and
|
||||
hook_requirements to mention that RDF can cause validation errors for the
|
||||
Open Graph meta tag output.
|
||||
#1977640 by dsdeiz: Fixed a comment typo.
|
||||
#1978730 by DamienMcKenna: Added an installation note to read the README.txt
|
||||
file.
|
||||
#1978568 by DamienMcKenna: Strip line breaks in all tag output.
|
||||
#1961354 by DamienMcKenna, thesame: Optionally provide additional permissions
|
||||
so that access to modify each meta tag can be controlled individually, see
|
||||
README.txt for more details.
|
||||
#1933678 by DamienMcKenna: Default Context configurations for the user login and
|
||||
registration pages.
|
||||
#1816856 by DamienMcKenna: Default Context configuration for the main forum
|
||||
page.
|
||||
#1292612 by DamienMcKenna: Default Context configuration for the main blog
|
||||
page.
|
||||
#1988346 by DamienMcKenna: Form permissions were being overridden thus making
|
||||
the Metatag fieldset visible when it shouldn't have been.
|
||||
#1994352 by AmbikaFR: Two strings were not translatable.
|
||||
#1970064 by Jorrit: Metatag:Panels did not load the data correctly.
|
||||
#1994634 by DamienMcKenna: DrupalTextMetaTag::getValue fails if
|
||||
$options['instance'] element doesn't exist.
|
||||
#1994630 by DamienMcKenna: Cleanup/filter all meta tag output.
|
||||
By DamienMcKenna: Moved hook_requirements to the top of metatag.install.
|
||||
#1982164 by DamienMcKenna: Added hook_requirements note to ensure that Entity
|
||||
Translation is up-to-date.
|
||||
#2020565 by DamienMcKenna: Save the correct language value on initial entity
|
||||
creation.
|
||||
#1876034 by DamienMcKenna: Updated a comment to indicate that there was a
|
||||
problem with Metatag itself when saving records via node_save(), not
|
||||
Workbench Moderation after all.
|
||||
#2024277 by greggles, DamienMcKenna: Don't output a meta tag if the string is
|
||||
blank, but still allow "0" to be output when needed.
|
||||
#1999936 by DamienMcKenna: Fixed poor logic for checking if a valid language
|
||||
was available in metatag_metatags_values().
|
||||
#2024277 by DamienMcKenna: Follow-up to fix all meta tag output.
|
||||
#1498764 by nick_schuch, DamienMcKenna: Added the Revisit-After meta tag.
|
||||
#1671846 by benys, DamienMcKenna: Expose meta tags as tokens.
|
||||
#1830952 by DYdave, DamienMcKenna: Allow token types and patterns to be altered.
|
||||
#1859136 by plopesc, DamienMcKenna: Properly update meta tag records.
|
||||
#2045855 by czigor: Fix translation of meta tag info labels.
|
||||
#1572474 by PieIsGood, Dan Reinders, DamienMcKenna: Entity revision support.
|
||||
#2051401 by cha0s: Remove errant dpm() left in from earlier testing.
|
||||
#2037677 by adnasa, DamienMcKenna, tsvenson: UX improvement for the token popup.
|
||||
#1985932 by kolier: Correct the taxonomy term token on Panels pages.
|
||||
#2033723 by som30ind, DamienMcKenna: Fixed occasional error saving array values,
|
||||
e.g. the ROBOTS tag.
|
||||
#1959830 by DamienMcKenna: Added a note to README.txt about Node Form Panes.
|
||||
#2061511 by amanire: Verify view display 'path' option exists before using it.
|
||||
#1776836 by kobee, DamienMcKenna: Added the Standout meta tag.
|
||||
#2095397 by DamienMcKenna: Allow method to skip skipping metatag_entity_view().
|
||||
#2095501 by DamienMcKenna: Logic mistake in metatag_metatags_delete_multiple()
|
||||
meant records were never deleted.
|
||||
|
||||
|
||||
Metatag 7.x-1.0-beta7, 2013-04-22
|
||||
---------------------------------
|
||||
#1970946 by laura s: Twitter Cards no longer requires SSL.
|
||||
#1971406 by alextataurov, DamienMcKenna: Correct check to see if i18n is
|
||||
installed.
|
||||
#1955898 by DamienMcKenna: Clicking 'cancel' when editing a per-path
|
||||
configuration would cause the config to be deleted.
|
||||
#1955894 by plopesc: It wasn't possible to remove values from the
|
||||
Metatag:Context editor.
|
||||
#1972038 by DamienMcKenna: Context admin page didn't display the '<front>' path
|
||||
correctly.
|
||||
#1970064 by DamienMcKenna: Metatag:Context did not load the data correctly.
|
||||
#1970518 by John Morahan: Incorrect syntax in metatag.info.
|
||||
#1972932 by chrisjlee: Typo in hook_requirements.
|
||||
By DamienMcKenna: Removed trailing space in some files.
|
||||
#1951118 by DamienMcKenna: Display a runtime hook_requirements error message if
|
||||
the old metatag.entity_translation.inc file is still present.
|
||||
By DamienMcKenna: Removed some tabs that snook in.
|
||||
#1973254 by plopesc: Added functional tests for Metatag:Context.
|
||||
#1284756 by dsdeiz: Add instructions to metatag.migrate.inc explaining how to
|
||||
use the Migrate integration.
|
||||
#1954106 by DamienMcKenna: Simplified the project's name to just 'Metatag'.
|
||||
#1974870 by DamienMcKenna: Moved all modules to the 'SEO' package.
|
||||
|
||||
|
||||
Metatag 7.x-1.0-beta6, 2013-04-14
|
||||
---------------------------------
|
||||
#1961448 by DamienMcKenna: Disable the fb:app_id field if fb_social is present.
|
||||
#1282620 by idflood, evanbarter, mgifford, Lukas von Blarer, Peacog, zterry95,
|
||||
DamienMcKenna: Configuration translation through integration with the i18n
|
||||
module.
|
||||
#1498740 by devuo: Merged Diogo's metatag_panels module.
|
||||
#1804356 by Dave Reid: Merged Dave's metatag_views module.
|
||||
#1909224 by DamienMcKenna: Fixed sloppy code in metatag_metatags_form_submit().
|
||||
#1969428 by DamienMcKenna: Changed the DC 'property' attribute to 'name'.
|
||||
#1284756 by dsdeiz: Update Migrate integration for compatibility with v2.5,
|
||||
support additional entity types.
|
||||
#1953724 by DamienMcKenna, joshf, wiifm, twistor: PostgreSQL compatibility for
|
||||
recent updates.
|
||||
#1295524 by DamienMcKenna: Temporary fix for the [node:summary] token not
|
||||
working.
|
||||
#1952190 by DamienMcKenna: Only run queries involving taxonomy data if the
|
||||
Taxonomy module is enabled.
|
||||
|
||||
|
||||
Metatag 7.x-1.0-beta5, 2013-03-23
|
||||
---------------------------------
|
||||
#1844638 by DamienMcKenna: Updated help messages around update 7004, when ran
|
||||
via Drush it will no longer used Batch API.
|
||||
#1844764 by Devin Carlson, DamienMcKenna: Fix arg placeholders in t() calls.
|
||||
#1846516 by Staratel: Incorrect arguments for watchdog().
|
||||
#1846516 by DamienMcKenna: Further incorrect arguments for watchdog().
|
||||
#1844638 by DamienMcKenna: Correctly used drupal_is_cli() instead of just
|
||||
php_sapi_name().
|
||||
#1846978 by edulterado: Corrected the theme function name used with the
|
||||
Twitter Cards submodule.
|
||||
#1307804 by juampy: Support for Select_or_Other for use with the OpenGraph
|
||||
'type' field.
|
||||
#1854522 by DamienMcKenna: Redundant return statements in the MetaTag classes.
|
||||
#1852600 by DamienMcKenna: Only use the first page argument in the Views and
|
||||
Panels preprocessors if it is numerical.
|
||||
#1850014 by plopesc: Not all contexts that may be shown on the admin page will
|
||||
have a path condition defined.
|
||||
#1846080 by DamienMcKenna: Only support entities that have the 'metatags'
|
||||
option specifically enabled.
|
||||
#1857116 by DamienMcKenna: Purge {metatag} records for a few known unsupported
|
||||
entities that old versions would have saved.
|
||||
#1857116 by DamienMcKenna: Don't purge 'file' {metatag} records until #1857334
|
||||
is decided.
|
||||
#1857360 by DamienMcKenna: Purge {metatag} records for nodes, taxonomy terms
|
||||
and users that were purged but where the APIs of older versions failed to
|
||||
remove them.
|
||||
#1857116 by DamienMcKenna: Purge {metatag} records for Profile2.
|
||||
#1852600 by helmo: Typo in Views integration function.
|
||||
#1852022 by DamienMcKenna: Don't export the {metatag_config}.cid field.
|
||||
#1862570 by DamienMcKenna: Purge any empty values that may have been added by
|
||||
very early releases.
|
||||
#1862570 by DamienMcKenna: Follow-up to correctly handle the serialized empty
|
||||
array.
|
||||
#1864340 by cdoyle, DamienMcKenna: Incorrect output for certain Twitter Card
|
||||
tags.
|
||||
#1865170 by DamienMcKenna: Fix metatag_requirements() return array when the
|
||||
Page Title module is also installed.
|
||||
#1722564 by DamienMcKenna: Provide a hook_requirements() message and README.txt
|
||||
note about a possible conflict with the Exclude Node Title module.
|
||||
#1284756 by damiankloip, sylus, alanburke, lancee: Migrate module integration.
|
||||
#1865228 by greggles, DamienMcKenna: Added the rel=author link meta tag.
|
||||
#1866122 by DamienMcKenna: Added the twitter:site:id and twitter:creator:id
|
||||
meta tags.
|
||||
#1866980 by makangus: Corrected metatag_features_revert().
|
||||
#1862818 by DYdave, DamienMcKenna: Added documentation for
|
||||
hook_metatag_config_default().
|
||||
#1778534 by DamienMcKenna: Added the original-source meta tag.
|
||||
#1886170 by DamienMcKenna: Typo in the API docs regarding enabling metatag
|
||||
support in custom entities.
|
||||
#1871020 by DamienMcKenna: Compatibility problem with Workbench_Moderation.
|
||||
#1773926 by Dave Reid: Fixed token validation fails on config edit if the
|
||||
instance context is not an entity type.
|
||||
#1814736 by plach, Dave Reid: metatag_page_build() did not check if the
|
||||
global:frontpage metatag configuration is disabled.
|
||||
#1871852: Fixed metatag_update_7005() did not check if the watchdog table
|
||||
exists.
|
||||
#1891082 by bago, Dave Reid: Fixed metatag_config_instance_label() failed to
|
||||
recurse properly.
|
||||
#1915284: Fixed metatag_html_head_alter() stopped removing duplicate tags too
|
||||
soon. Fixed duplicate canonical links when global redirect is enabled.
|
||||
#1845326 by DamienMcKenna, Peacog: Resolved language handling problems to
|
||||
correctly identify the langcode to properly work with or without
|
||||
Entity_Translation.
|
||||
#1876042 by DamienMcKenna: Rename variables to use $entity_id instead of $id
|
||||
and $entity_type instead of $type.
|
||||
#1859136 by splatio, DamienMcKenna, multpix: Feeds integration - allow meta tag
|
||||
fields to be the target for data imported using the Feeds module.
|
||||
#1880302 by olli, DamienMcKenna: Resolve problems with Features integration.
|
||||
#1923030 by krlucas, DamienMcKenna: Only run metatag_entity_update() on
|
||||
supported entities.
|
||||
#1844638 by DamienMcKenna, mikeytown2: Remove unnecessary duplicate {metatag}
|
||||
records, fix language values for all entities.
|
||||
#1935084 by DamienMcKenna: Remove unnecessary items from metatag_hook_info()
|
||||
that was causing problems with PHP 5.4.
|
||||
#1791720 by kbasarab: Added the news_keywords meta tag.
|
||||
#1934492 by juampy, DamienMcKenna: Added a page for reverting meta tags for
|
||||
specific entity or bundle.
|
||||
#1386320: Note a known issue of using custom template files that do not output
|
||||
the $page['content'] variable.
|
||||
#1917902 by DamienMcKenna: Ensure strings returned from token replacement of
|
||||
text fields ([node:summary]) is passed through the appropriate text filters.
|
||||
#1919070 by DamienMcKenna: Fix any records that may have been corrupted by e.g.
|
||||
#1871020.
|
||||
#1861656 by DamienMcKenna, torrance123: Optionally load the global meta tags on
|
||||
all pages, enabled by default.
|
||||
#1871798 by mstrelan: Clear the Context plugin cache when metatag_context is
|
||||
enabled so that the new plugin becomes available.
|
||||
#1932192 by DamienMcKenna: Only run metatag_entity_view() once per page view.
|
||||
#1900434 by Dustin Currie, j0rd, DamienMcKenna: Added several new OpenGraph meta
|
||||
tags, including ones for videos, location and contact information.
|
||||
#1883118 by DamienMcKenna: Improve the help message on Metatag:Context's Path
|
||||
field as neither relative nor absolute URLs will work.
|
||||
#1945114 by SergO, DamienMcKenna: A query from #1919070 was missing the
|
||||
preproccess wrapper around the table name.
|
||||
#1908586 by DamienMcKenna: Added a line to README.txt explaining how to
|
||||
customize the tokens used to generate the meta tags.
|
||||
#1350610 by DamienMcKenna: metatag_update_7001 needed to drop the primary key
|
||||
before customizing it.
|
||||
#1859136 by DamienMcKenna: Fixed scenarios when updating an entity there are two
|
||||
copies of the data submitted, e.g. Feeds integration.
|
||||
#1308790 by DamienMcKenna: Documented that [current-user] tokens should not be
|
||||
used.
|
||||
#1318294 by DamienMcKenna: Documented how to use Imagecache Token to resize
|
||||
images that are being used as tokens for meta tags.
|
||||
#1871534 by DamienMcKenna: Documented how some browser plugins can make the page
|
||||
title appear to be wrapped with doublequotes though the output doesn't
|
||||
actually show them.
|
||||
|
||||
|
||||
Metatag 7.x-1.0-beta4, 2012-11-17
|
||||
---------------------------------
|
||||
#1842764 by DamienMcKenna: Work around problems in metatag_entity_load()
|
||||
stemming from an outdated database schema, leave a message suggesting the
|
||||
site admin run the database updates.
|
||||
#1842868 by DamienMcKenna: Changed metatag_update_7003 to automatically assign
|
||||
the correct language per entity, added update_7004 to fix records updated in
|
||||
beta3, fixed the language selection for loading meta tags so sites without
|
||||
translation functionality continue to work correctly.
|
||||
#1842868 by DamienMcKenna: Changed update 7003 again so it *only* adds the new
|
||||
field, changed update 7004 so it will update all records using Batch API.
|
||||
#1843676 by DamienMcKenna: Changed the hook_requirements message to an INFO
|
||||
message if Page_Title is also installed, will freak people out less.
|
||||
|
||||
|
||||
Metatag 7.x-1.0-beta3, 2012-11-16
|
||||
---------------------------------
|
||||
#1688286 by colan, DamienMcKenna: Support for Entity Translation.
|
||||
#1835030 by DamienMcKenna: Documentation and hook_requirements note re Drupal
|
||||
core v7.17.
|
||||
#1840402 by DamienMcKenna, paperdhc: Corrected use of array_pop().
|
||||
#1841404 by mh86: Don't attempt to load meta tags for unsupported entities, and
|
||||
don't support configuration-only entities.
|
||||
#1841564 by peximo: Correctly identify the content language being used on the
|
||||
homepage.
|
||||
#1841774 by DamienMcKenna: Provide a warning via hook_requirements if the Page
|
||||
Title module is also enabled, due to the possibilities of complications and
|
||||
unexpected results.
|
||||
#1363476 by DamienMcKenna: Workaround to trigger metatag_entity_view() if the
|
||||
current CTools (Panels, Panelizer, etc) page is an entity display page.
|
||||
#1842052 by DamienMcKenna: Don't process unsupported entities being displayed
|
||||
via Views.
|
||||
#1664322 by nico059, kerasai, miechiel, idflood, DamienMcKenna, alexweber:
|
||||
Twitter Cards meta tags.
|
||||
#1842198 by DamienMcKenna: Move the 'advanced' fieldset under the others.
|
||||
#1840236 by weri, Marty2081: Only revert the requested feature, not all
|
||||
features.
|
||||
|
||||
|
||||
Metatag 7.x-1.0-beta2, 2012-10-30
|
||||
---------------------------------
|
||||
#1817580 by DamienMcKenna: Removed code that was enabling debug mode on all
|
||||
Contexts.
|
||||
#1818240 by DamienMcKenna: Added $instance value to the drupal_alter() call in
|
||||
metatag_metatags_view().
|
||||
#1817984 by DamienMcKenna, alexweber: Documented
|
||||
hook_metatag_metatags_view_alter().
|
||||
#1818252 by DamienMcKenna: There was no caching on the front page's meta tags.
|
||||
#1818516 by DamienMcKenna: Incorrect variable check in metatag_page_build().
|
||||
#1818762 by DamienMcKenna: Updated hook_hook_info().
|
||||
#1466292 by DamienMcKenna: Listed hooks in metatag.api.php and everywhere the
|
||||
hooks are triggered there's a comment to say what the hook is.
|
||||
#1818984 by DamienMcKenna: Add the $instance value to metatag_context's
|
||||
triggering of hook_metatag_metatags_view.
|
||||
#1819000 by DamienMcKenna: Don't load default meta tags if no active contexts
|
||||
define meta tags.
|
||||
#1819448 by DamienMcKenna: Error on admin page if any meta tags were disabled.
|
||||
#1818958 by DamienMcKenna: The $cid_parts array should contain all relevant
|
||||
entity variables.
|
||||
#1820362 by DamienMcKenna: $cid_parts should use base_path() instead of '/'.
|
||||
#1820374 by DamienMcKenna: Front page $cid_parts did not include the full URL.
|
||||
#1822726 by DamienMcKenna: Ensure the CTools exportables system is loaded.
|
||||
#1818300 by eugene.ilyin, DamienMcKenna: Improved Features integration.
|
||||
#1151936 by DamienMcKenna, maximpodorov: Workaround to trigger
|
||||
metatag_entity_view() if the current Views page is an entity display page.
|
||||
|
||||
|
||||
Metatag 7.x-1.0-beta1, 2012-10-19
|
||||
---------------------------------
|
||||
First mostly-stable release.
|
339
sites/all/modules/contrib/seo/metatag/LICENSE.txt
Normal file
339
sites/all/modules/contrib/seo/metatag/LICENSE.txt
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
205
sites/all/modules/contrib/seo/metatag/README.txt
Normal file
205
sites/all/modules/contrib/seo/metatag/README.txt
Normal file
@@ -0,0 +1,205 @@
|
||||
Metatag
|
||||
-------
|
||||
This module allows you to automatically provide structured metadata, aka "meta
|
||||
tags", about your website and web pages.
|
||||
|
||||
In the context of search engine optimization, providing an extensive set of
|
||||
meta tags may help improve your site's & pages' ranking, thus may aid with
|
||||
achieving a more prominent display of your content within search engine
|
||||
results. Additionally, using meta tags can help control the summary content
|
||||
that is used within social networks when visitors link to your site,
|
||||
particularly the Open Graph submodule for use with Facebook (see below).
|
||||
|
||||
This version of the module only works with Drupal 7.15 and newer.
|
||||
|
||||
|
||||
Features
|
||||
------------------------------------------------------------------------------
|
||||
The primary features include:
|
||||
|
||||
* The current supported basic meta tags are ABSTRACT, DESCRIPTION, CANONICAL,
|
||||
COPYRIGHT, GENERATOR, IMAGE_SRC, KEYWORDS, PUBLISHER, REVISIT-AFTER, ROBOTS,
|
||||
SHORTLINK and the page's TITLE tag.
|
||||
|
||||
* Multi-lingual support using the Entity Translation module.
|
||||
|
||||
* Translation support using the Internationalization (i18n) module.
|
||||
|
||||
* Full support for entity revisions and workflows based upon revision editing,
|
||||
e.g. Revisioning module.
|
||||
|
||||
* Per-path control over meta tags using the "Metatag: Context" submodule
|
||||
(requires the Context module).
|
||||
|
||||
* Integration with the Views module allowing meta tags to be controlled for
|
||||
individual Views pages, with each display in the view able to have different
|
||||
meta tags, by using the "Metatag: Views" submodule.
|
||||
|
||||
* Integration with the Panels module allowing meta tags to be controlled for
|
||||
individual Panels pages, by using the "Metatag: Panels" submodule.
|
||||
|
||||
* The fifteen Dublin Core Basic Element Set 1.1 meta tags may be added by
|
||||
enabling the "Metatag: Dublin Core" submodule.
|
||||
|
||||
* The Open Graph Protocol meta tags, as used by Facebook, may be added by
|
||||
enabling the "Metatag: Open Graph" submodule.
|
||||
|
||||
* The Twitter Cards meta tags may be added by enabling the "Metatag: Twitter
|
||||
Cards" submodule.
|
||||
|
||||
* An API allowing for additional meta tags to be added, beyond what is provided
|
||||
by this module - see metatag.api.php for full details.
|
||||
|
||||
* Support for the Migrate module for migrating data from another system - see
|
||||
metatag.migrate.inc for full details.
|
||||
|
||||
* Support for the Feeds module for importing data from external data sources or
|
||||
file uploads.
|
||||
|
||||
|
||||
Configuration
|
||||
------------------------------------------------------------------------------
|
||||
1. On the People Permissions administration page ("Administer >> People
|
||||
>> Permissions") you need to assign:
|
||||
|
||||
- The "Administer meta tags" permission to the roles that are allowed to
|
||||
access the meta tags admin pages to control the site defaults.
|
||||
|
||||
- The "Edit meta tags" permission to the roles that are allowed to change
|
||||
meta tags on each individual page (node, term, etc).
|
||||
|
||||
2. The main admininistrative page controls the site-wide defaults, both global
|
||||
settings and defaults per entity (node, term, etc), in addition to those
|
||||
assigned specifically for the front page:
|
||||
admin/config/search/metatags
|
||||
|
||||
3. Each supported entity object (nodes, terms, users) will have a set of meta
|
||||
tag fields available for customization on their respective edit page, these
|
||||
will inherit their values from the defaults assigned in #2 above. Any
|
||||
values that are not overridden per object will automatically update should
|
||||
the defaults be updated.
|
||||
|
||||
4. As the meta tags are output using Tokens, it may be necessary to customize
|
||||
the token display for the site's entities (content types, vocabularies,
|
||||
etc). To do this go to e.g. admin/structure/types/manage/article/display, in
|
||||
the "Custom Display Settings" section ensure that "Tokens" is checked (save
|
||||
the form if necessary), then to customize the tokens go to:
|
||||
admin/structure/types/manage/article/display/token
|
||||
|
||||
|
||||
Internationalization: i18n.module
|
||||
------------------------------------------------------------------------------
|
||||
All default configurations may be translated using the Internationalization
|
||||
(i18n) module. The custom strings that are assigned to e.g. the "Global: Front
|
||||
page" configuration will show up in the Translate Interface admin page
|
||||
(admin/config/regional/translate/translate) and may be customized per language.
|
||||
|
||||
|
||||
Fine Tuning
|
||||
------------------------------------------------------------------------------
|
||||
* By default Metatag will load the global default values for all pages that do
|
||||
not have meta tags assigned via the normal entity display or via Metatag
|
||||
Context. This may be disabled by setting the variable 'metatag_load_all_pages'
|
||||
to FALSE through one of the following methods:
|
||||
* Use Drush to set the value:
|
||||
drush vset metatag_load_all_pages FALSE
|
||||
* Hardcode the value in the site's settings.php file:
|
||||
$conf['metatag_load_all_pages'] = FALSE;
|
||||
To re-enable this option simply set the value to TRUE.
|
||||
* By default users will be able to edit meta tags on forms based on the 'Edit
|
||||
meta tags' permission. The 'metatag_extended_permissions' variable may be set
|
||||
to TRUE to give each individual meta tag a separate permission. This allows
|
||||
fine-tuning of the site's editorial control, and for rarely-used fields to be
|
||||
hidden from most users. Note: The 'Edit meta tags' permission is still
|
||||
required otherwise none of the meta tag fields will display at all. The
|
||||
functionality may be disabled again by either removing the variable or
|
||||
setting it to FALSE.
|
||||
|
||||
|
||||
Developers
|
||||
------------------------------------------------------------------------------
|
||||
Full API documentation is available in metatag.api.php.
|
||||
|
||||
To enable Metatag support in custom entities, add 'metatag' => TRUE to either
|
||||
the entity or bundle definition in hook_entity_info(); see metatag.api.php for
|
||||
further details and example code.
|
||||
|
||||
|
||||
Troubleshooting / Known Issues
|
||||
------------------------------------------------------------------------------
|
||||
* When using custom page template files, e.g. page--front.tpl.php, it is
|
||||
important to ensure that the following code is present in the template file:
|
||||
<?php render($page['content']); ?>
|
||||
or
|
||||
<?php render($page['content']['metatags']); ?>
|
||||
Without one of these being present the meta tags will not be displayed.
|
||||
* Versions of Drupal older than v7.17 were missing necessary functionality for
|
||||
taxonomy term pages to work correctly.
|
||||
* Using Metatag with values assigned for the page title and the Page Title
|
||||
module simultaneously can cause conflicts and unexpected results.
|
||||
* Using the Exclude Node Title module will cause the [node:title] token to be
|
||||
empty on node pages, so using [current-page:title] will work around the
|
||||
issue. Note: it isn't possible to "fix" this as it's a by-product of what
|
||||
Exclude Node Title does - it removes the node title from display.
|
||||
* When customizing the meta tags for user pages, it is strongly recommended to
|
||||
not use the [current-user] tokens, these pertain to the person *viewing* the
|
||||
page and not e.g. the person who authored a page.
|
||||
* If images being displayed in image tags need to be resized to fit a specific
|
||||
requirements, use the Imagecache Token module to customize the value.
|
||||
* Certain browser plugins, e.g. on Chrome, can cause the page title so be
|
||||
displayed with additional doublequotes, e.g. instead of:
|
||||
<title>The page title | My cool site</title>
|
||||
it will show:
|
||||
<title>"The page title | My cool site"</title>
|
||||
The solution is to remove the browser plugin - the page's actual output is not
|
||||
affected, it is just a problem in the browser.
|
||||
* The core RDF module is known to cause validation problems for Open Graph meta
|
||||
tags output by the Metatag:OpenGraph module. Unless it is actually needed for
|
||||
the site, it may be worthwhile to disable the RDF module to avoid any
|
||||
possible problems for the Open Graph integration.
|
||||
|
||||
|
||||
Related modules
|
||||
------------------------------------------------------------------------------
|
||||
Some modules are available that extend Metatag with additional functionality:
|
||||
|
||||
* Domain Meta Tags
|
||||
http://drupal.org/project/domain_meta
|
||||
Integrates with the Domain Access module, so each site of a multi-domain
|
||||
install can separately control their meta tags.
|
||||
|
||||
* Select or Other
|
||||
http://drupal.org/project/select_or_other
|
||||
Enhances the user experience of the metatag_opengraph submodule by allowing
|
||||
the creation of custom Open Graph types.
|
||||
|
||||
* Imagecache Token
|
||||
http://drupal.org/project/imagecache_token
|
||||
Provide tokens to load fields using an image style preset, for when meta tags
|
||||
need to fix exact requirements.
|
||||
|
||||
* Node Form Panes
|
||||
https://drupal.org/project/node_form_panes
|
||||
Create custom node-edit forms and control the location of the Metatag fields.
|
||||
|
||||
|
||||
Credits / Contact
|
||||
------------------------------------------------------------------------------
|
||||
Currently maintained by Damien McKenna [1] and Dave Reid [2]; all initial
|
||||
development was by Dave Reid.
|
||||
|
||||
Ongoing development is sponsored by Mediacurrent [3] and Palantir.net [4]. All
|
||||
initial development was sponsored by Acquia [5] and Palantir.net.
|
||||
|
||||
The best way to contact the authors is to submit an issue, be it a support
|
||||
request, a feature request or a bug report, in the project issue queue:
|
||||
http://drupal.org/project/issues/metatag
|
||||
|
||||
|
||||
References
|
||||
------------------------------------------------------------------------------
|
||||
1: http://drupal.org/user/108450
|
||||
2: http://drupal.org/user/53892
|
||||
3: http://www.mediacurrent.com/
|
||||
4: http://www.palantir.net/
|
||||
5: http://www.acquia.com/
|
BIN
sites/all/modules/contrib/seo/metatag/arrow-down.png
Normal file
BIN
sites/all/modules/contrib/seo/metatag/arrow-down.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 140 B |
BIN
sites/all/modules/contrib/seo/metatag/arrow-right.png
Normal file
BIN
sites/all/modules/contrib/seo/metatag/arrow-right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 139 B |
82
sites/all/modules/contrib/seo/metatag/metatag.admin.css
Normal file
82
sites/all/modules/contrib/seo/metatag/metatag.admin.css
Normal file
@@ -0,0 +1,82 @@
|
||||
div.metatag-config-label {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
div.metatag-config-label > a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.metatag-config-label.collapsed {
|
||||
background-image: url('arrow-right.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center left;
|
||||
}
|
||||
|
||||
.metatag-config-label.expanded {
|
||||
background-image: url('arrow-down.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center left;
|
||||
}
|
||||
|
||||
table.metatag-config-overview > tbody > tr > td:first-child {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
table.metatag-config-overview > tbody > tr > td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.metatag-config-overview tbody div.indent {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
table.metatag-config-overview tr.disabled > td:first-child a {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
div.metatag-config-details {
|
||||
color: #666;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
div.metatag-config-details p {
|
||||
margin: 0.75em 0;
|
||||
}
|
||||
|
||||
div.metatag-config-details div.inheritance {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.metatag-config-details table.metatag-value-summary {
|
||||
border: none;
|
||||
width: auto;
|
||||
margin: 0.75em 0;
|
||||
}
|
||||
|
||||
div.metatag-config-details table.metatag-value-summary td {
|
||||
padding: 0 0.5em 0 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
div.metatag-config-details table.metatag-value-summary tr,
|
||||
div.metatag-config-details table.metatag-value-summary tr td:last-child {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.metatag-config-details table.metatag-value-summary tr td:first-child {
|
||||
font-weight: bold;
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
/*div.metatag-config-details ul {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
div.metatag-config-details ul li {
|
||||
line-height: 105%;
|
||||
}
|
||||
|
||||
div.metatag-config-details > p {
|
||||
margin: 0.25em 0;
|
||||
}*/
|
534
sites/all/modules/contrib/seo/metatag/metatag.admin.inc
Normal file
534
sites/all/modules/contrib/seo/metatag/metatag.admin.inc
Normal file
@@ -0,0 +1,534 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Administration page callbacks for the metatag module.
|
||||
*/
|
||||
|
||||
function _metatag_config_sort($a, $b) {
|
||||
$return = NULL;
|
||||
$a_contexts = explode(':', $a->instance);
|
||||
$b_contexts = explode(':', $b->instance);
|
||||
for ($i = 0; $i < max(count($a_contexts), count($b_contexts)); $i++) {
|
||||
$a_context = isset($a_contexts[$i]) ? $a_contexts[$i] : '';
|
||||
$b_context = isset($b_contexts[$i]) ? $b_contexts[$i] : '';
|
||||
if ($a_context == $b_context) {
|
||||
continue;
|
||||
}
|
||||
elseif ($a_context == 'global') {
|
||||
$return = -1;
|
||||
}
|
||||
elseif ($a_context == '') {
|
||||
$return = -1;
|
||||
}
|
||||
else {
|
||||
$return = strcmp($a_context, $b_context);
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
function _metatag_config_overview_indent($text, $instance) {
|
||||
$parents = metatag_config_get_parent_instances($instance);
|
||||
array_shift($parents);
|
||||
|
||||
// Add indentation to the leading cell.
|
||||
if (!empty($parents)) {
|
||||
$prefix = array_fill(0, count($parents), '<div class="indent">');
|
||||
$suffix = array_fill(0, count($parents), '</div>');
|
||||
$text = implode('', $prefix) . $text . implode('', $suffix);
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
function metatag_config_overview() {
|
||||
ctools_include('export');
|
||||
|
||||
$metatags = metatag_get_info('tags');
|
||||
|
||||
$configs = ctools_export_crud_load_all('metatag_config');
|
||||
ksort($configs);
|
||||
//uasort($configs, '_metatag_config_sort');
|
||||
|
||||
$rows = array();
|
||||
foreach ($configs as $config) {
|
||||
$row = array();
|
||||
|
||||
// Style disabled configurations differently.
|
||||
if (!empty($config->disabled)) {
|
||||
$row['class'][] = 'disabled';
|
||||
}
|
||||
|
||||
$details = '<div class="metatag-config-label collapsed"><a href="#" class="toggle-details">' . check_plain(metatag_config_instance_label($config->instance)) . '</a></div>';
|
||||
$details .= '<div class="metatag-config-details js-hide">';
|
||||
|
||||
$inherits = array();
|
||||
$parents = metatag_config_get_parent_instances($config->instance);
|
||||
array_shift($parents);
|
||||
foreach (array_reverse($parents) as $parent) {
|
||||
if (!isset($configs[$parent])) {
|
||||
$rows[$parent] = array(
|
||||
_metatag_config_overview_indent('<div class="metatag-config-label">' . check_plain(metatag_config_instance_label($parent)) . '</div>', $parent),
|
||||
'',
|
||||
);
|
||||
}
|
||||
else {
|
||||
$inherits[$parent] = metatag_config_instance_label($parent);
|
||||
if (!empty($configs[$parent]->disabled)) {
|
||||
$inherits[$parent] .= ' ' . t('(disabled)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show how this config inherits from its parents.
|
||||
if (!empty($inherits)) {
|
||||
$details .= '<div class="inheritance"><p>' . t('Inherits meta tags from: @parents', array('@parents' => implode(', ', $inherits))) . '</p></div>';
|
||||
}
|
||||
|
||||
// Add a summary of the configuration's defaults.
|
||||
$summary = array();
|
||||
foreach ($config->config as $metatag => $data) {
|
||||
// Skip meta tags that were disabled.
|
||||
if (empty($metatags[$metatag])) {
|
||||
continue;
|
||||
}
|
||||
$summary[] = array(
|
||||
check_plain($metatags[$metatag]['label']) . ':',
|
||||
check_plain(metatag_get_value($metatag, $data, array('raw' => TRUE))),
|
||||
);
|
||||
}
|
||||
if (!empty($summary)) {
|
||||
$details .= theme('table', array(
|
||||
'rows' => $summary,
|
||||
'attributes' => array('class' => array('metatag-value-summary')),
|
||||
));
|
||||
}
|
||||
else {
|
||||
$details .= '<p class="warning">No overridden default meta tags</p>';
|
||||
$row['class'][] = 'warning';
|
||||
}
|
||||
|
||||
// Close the details div
|
||||
$details .= '</div>';
|
||||
|
||||
// Add indentation to the leading cell based on how many parents the config has.
|
||||
$details = _metatag_config_overview_indent($details, $config->instance);
|
||||
|
||||
$row['data']['details'] = $details;
|
||||
|
||||
$operations = array();
|
||||
if (metatag_config_access('disable', $config)) {
|
||||
$operations['edit'] = array(
|
||||
'title' => ($config->export_type & EXPORT_IN_DATABASE) ? t('Edit') : t('Override'),
|
||||
'href' => 'admin/config/search/metatags/config/' . $config->instance,
|
||||
);
|
||||
}
|
||||
if (metatag_config_access('enable', $config)) {
|
||||
$operations['enable'] = array(
|
||||
'title' => t('Enable'),
|
||||
'href' => 'admin/config/search/metatags/config/' . $config->instance . '/enable',
|
||||
'query' => array(
|
||||
'token' => drupal_get_token('enable-' . $config->instance),
|
||||
) + drupal_get_destination(),
|
||||
);
|
||||
}
|
||||
if (metatag_config_access('disable', $config)) {
|
||||
$operations['disable'] = array(
|
||||
'title' => t('Disable'),
|
||||
'href' => 'admin/config/search/metatags/config/' . $config->instance . '/disable',
|
||||
'query' => array(
|
||||
'token' => drupal_get_token('disable-' . $config->instance),
|
||||
) + drupal_get_destination(),
|
||||
);
|
||||
}
|
||||
if (metatag_config_access('revert', $config)) {
|
||||
$operations['revert'] = array(
|
||||
'title' => t('Revert'),
|
||||
'href' => 'admin/config/search/metatags/config/' . $config->instance . '/revert',
|
||||
);
|
||||
}
|
||||
if (metatag_config_access('delete', $config)) {
|
||||
$operations['delete'] = array(
|
||||
'title' => t('Delete'),
|
||||
'href' => 'admin/config/search/metatags/config/' . $config->instance . '/delete',
|
||||
);
|
||||
}
|
||||
$operations['export'] = array(
|
||||
'title' => t('Export'),
|
||||
'href' => 'admin/config/search/metatags/config/' . $config->instance . '/export',
|
||||
);
|
||||
$row['data']['operations'] = array(
|
||||
'data' => array(
|
||||
'#theme' => 'links',
|
||||
'#links' => $operations,
|
||||
'#attributes' => array('class' => array('links', 'inline')),
|
||||
),
|
||||
);
|
||||
|
||||
$rows[$config->instance] = $row;
|
||||
}
|
||||
|
||||
$build['config_table'] = array(
|
||||
'#theme' => 'table',
|
||||
'#header' => array(
|
||||
'type' => t('Type'),
|
||||
'operations' => t('Operations'),
|
||||
),
|
||||
'#rows' => $rows,
|
||||
'#empty' => t('No meta tag defaults available yet.'),
|
||||
'#attributes' => array(
|
||||
'class' => array('metatag-config-overview'),
|
||||
),
|
||||
'#attached' => array(
|
||||
'js' => array(
|
||||
drupal_get_path('module', 'metatag') . '/metatag.admin.js',
|
||||
),
|
||||
'css' => array(
|
||||
drupal_get_path('module', 'metatag') . '/metatag.admin.css',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an FAPI #options array for the instance select field.
|
||||
*/
|
||||
function _metatag_config_instance_get_available_options() {
|
||||
$options = array();
|
||||
$instances = metatag_config_instance_info();
|
||||
|
||||
foreach ($instances as $instance => $instance_info) {
|
||||
if (metatag_config_load($instance)) {
|
||||
continue;
|
||||
}
|
||||
$parents = metatag_config_get_parent_instances($instance, FALSE);
|
||||
array_shift($parents);
|
||||
if (!empty($parents)) {
|
||||
$parent = reset($parents);
|
||||
$parent_label = isset($instances[$parent]['label']) ? $instances[$parent]['label'] : t('Unknown');
|
||||
if (!isset($options[$parent_label])) {
|
||||
$options[$parent_label] = array();
|
||||
if (!metatag_config_load($parent)) {
|
||||
$options[$parent_label][$parent] = t('All');
|
||||
}
|
||||
}
|
||||
$options[$parent_label][$instance] = $instance_info['label'];
|
||||
unset($options[$parent]);
|
||||
}
|
||||
else {
|
||||
$options[$instance] = $instance_info['label'];
|
||||
}
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
function metatag_config_add_form($form, &$form_state) {
|
||||
$form['instance'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Type'),
|
||||
'#description' => t('Select the type of default meta tags you would like to add.'),
|
||||
'#options' => _metatag_config_instance_get_available_options(),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
$form['config'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => array(),
|
||||
);
|
||||
|
||||
$form['actions']['#type'] = 'actions';
|
||||
$form['actions']['save'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Add and configure'),
|
||||
);
|
||||
$form['actions']['cancel'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Cancel'),
|
||||
'#href' => isset($_GET['destination']) ? $_GET['destination'] : 'admin/config/search/metatags',
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
function metatag_config_add_form_submit($form, &$form_state) {
|
||||
form_state_values_clean($form_state);
|
||||
$config = (object) $form_state['values'];
|
||||
metatag_config_save($config);
|
||||
$form_state['redirect'] = 'admin/config/search/metatags/config/' . $config->instance;
|
||||
}
|
||||
|
||||
function metatag_config_edit_form($form, &$form_state, $config) {
|
||||
$form['cid'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => !empty($config->cid) ? $config->cid : NULL,
|
||||
);
|
||||
$form['instance'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $config->instance,
|
||||
);
|
||||
|
||||
$contexts = explode(':', $config->instance);
|
||||
$options['context'] = $contexts[0];
|
||||
if ($contexts[0] != 'global') {
|
||||
// The context part of the instance may not map to an entity type, so allow
|
||||
// the token_get_entity_mapping() function to fallback to the provided type.
|
||||
if ($token_type = token_get_entity_mapping('entity', $contexts[0], TRUE)) {
|
||||
$options['token types'] = array($token_type);
|
||||
}
|
||||
else {
|
||||
$options['token types'] = array($contexts[0]);
|
||||
}
|
||||
// Allow hook_metatag_token_types_alter() to modify the defined tokens.
|
||||
drupal_alter('metatag_token_types', $options);
|
||||
}
|
||||
|
||||
// Ensure that this configuration is properly compared to its parent 'default'
|
||||
// configuration values.
|
||||
if (count($contexts) > 1) {
|
||||
// If the config is something like 'node:article' or 'taxonomy_term:tags'
|
||||
// then the parent default config is 'node' or 'taxonomy_term'.
|
||||
$default_instance = $contexts;
|
||||
array_pop($default_instance);
|
||||
$default_instance = implode(':', $default_instance);
|
||||
$options['defaults'] = metatag_config_load_with_defaults($default_instance);
|
||||
}
|
||||
elseif ($contexts[0] != 'global') {
|
||||
// If the config is something like 'node' or 'taxonomy_term' then the
|
||||
// parent default config is 'global'.
|
||||
$options['defaults'] = metatag_config_load_with_defaults('global');
|
||||
}
|
||||
else {
|
||||
// If the config is 'global' than there are no parent defaults.
|
||||
$options['defaults'] = array();
|
||||
}
|
||||
|
||||
metatag_metatags_form($form, $config->instance, $config->config, $options);
|
||||
$form['metatags']['#type'] = 'container';
|
||||
|
||||
$form['actions']['#type'] = 'actions';
|
||||
$form['actions']['save'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
);
|
||||
$form['actions']['cancel'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Cancel'),
|
||||
'#href' => isset($_GET['destination']) ? $_GET['destination'] : 'admin/config/search/metatags',
|
||||
);
|
||||
|
||||
$form['#submit'][] = 'metatag_config_edit_form_submit';
|
||||
return $form;
|
||||
}
|
||||
|
||||
function metatag_config_edit_form_submit($form, &$form_state) {
|
||||
// Build the configuration object and save it.
|
||||
form_state_values_clean($form_state);
|
||||
$config = (object) $form_state['values'];
|
||||
// @todo Consider renaming the config field from 'config' to 'metatags'
|
||||
$config->config = $config->metatags;
|
||||
unset($config->metatags);
|
||||
metatag_config_save($config);
|
||||
|
||||
$label = metatag_config_instance_label($config->instance);
|
||||
drupal_set_message(t('The meta tag defaults for @label have been saved.', array('@label' => $label)));
|
||||
|
||||
$form_state['redirect'] = 'admin/config/search/metatags';
|
||||
}
|
||||
|
||||
function metatag_config_enable($config) {
|
||||
if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'enable-' . $config->instance)) {
|
||||
return MENU_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
ctools_export_crud_enable('metatag_config', $config);
|
||||
|
||||
$label = metatag_config_instance_label($config->instance);
|
||||
drupal_set_message(t('The meta tag defaults for @label have been enabled.', array('@label' => $label)));
|
||||
drupal_goto();
|
||||
}
|
||||
|
||||
function metatag_config_disable($config) {
|
||||
if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'disable-' . $config->instance)) {
|
||||
return MENU_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
ctools_export_crud_disable('metatag_config', $config);
|
||||
|
||||
$label = metatag_config_instance_label($config->instance);
|
||||
drupal_set_message(t('The meta tag defaults for @label have been disabed.', array('@label' => $label)));
|
||||
drupal_goto();
|
||||
}
|
||||
|
||||
function metatag_config_delete_form($form, &$form_state, $config) {
|
||||
$form['cid'] = array('#type' => 'value', '#value' => $config->cid);
|
||||
$form['instance'] = array('#type' => 'value', '#value' => $config->instance);
|
||||
|
||||
$label = metatag_config_instance_label($config->instance);
|
||||
$delete = metatag_config_access('delete', $config);
|
||||
$title = $delete ? t('Are you sure you want to delete the meta tag defaults for @label?', array('@label' => $label)) : t('Are you sure you want to revert the meta tag defaults for @label?', array('@label' => $label));
|
||||
|
||||
return confirm_form(
|
||||
$form,
|
||||
$title,
|
||||
'admin/config/search/metatags',
|
||||
t('This action cannot be undone.')
|
||||
);
|
||||
}
|
||||
|
||||
function metatag_config_delete_form_submit($form, &$form_state) {
|
||||
$config = metatag_config_load($form_state['values']['instance']);
|
||||
metatag_config_delete($config->instance);
|
||||
|
||||
$label = metatag_config_instance_label($config->instance);
|
||||
$delete = metatag_config_access('delete', $config);
|
||||
$title = $delete ? t('The meta tag defaults for @label have been deleted.', array('@label' => $label)) : t('The meta tag defaults for @label have been reverted.', array('@label' => $label));
|
||||
drupal_set_message($title);
|
||||
|
||||
$form_state['redirect'] = 'admin/config/search/metatags';
|
||||
}
|
||||
|
||||
function metatag_config_export_form($config) {
|
||||
ctools_include('export');
|
||||
return drupal_get_form('ctools_export_form', ctools_export_crud_export('metatag_config', $config), t('Export'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Form constructor to revert nodes to their default metatags.
|
||||
*
|
||||
* @see metatag_bulk_revert_form_submit()
|
||||
* @ingroup forms
|
||||
*/
|
||||
function metatag_bulk_revert_form() {
|
||||
// Get the list of entity:bundle options
|
||||
$options = array();
|
||||
foreach (entity_get_info() as $entity_type => $entity_info) {
|
||||
foreach (array_keys($entity_info['bundles']) as $bundle) {
|
||||
if (metatag_entity_supports_metatags($entity_type, $bundle)) {
|
||||
$options[$entity_type . ':' . $bundle] =
|
||||
$entity_info['label'] . ': ' . $entity_info['bundles'][$bundle]['label'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$form['update'] = array(
|
||||
'#type' => 'checkboxes',
|
||||
'#required' => TRUE,
|
||||
'#title' => t('Select the entities to revert'),
|
||||
'#options' => $options,
|
||||
'#default_value' => array(),
|
||||
'#description' => t('All meta tags will be removed for all content of the selected entities.'),
|
||||
);
|
||||
|
||||
$form['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Revert'),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form submit handler for metatag reset bulk revert form.
|
||||
*
|
||||
* @see metatag_batch_revert_form()
|
||||
* @see metatag_bulk_revert_batch_finished()
|
||||
*/
|
||||
function metatag_bulk_revert_form_submit($form, &$form_state) {
|
||||
$batch = array(
|
||||
'title' => t('Bulk updating metatags'),
|
||||
'operations' => array(),
|
||||
'finished' => 'metatag_bulk_revert_batch_finished',
|
||||
'file' => drupal_get_path('module', 'metatag') . '/metatag.admin.inc',
|
||||
);
|
||||
|
||||
// Set a batch operation per entity:bundle.
|
||||
foreach (array_filter($form_state['values']['update']) as $option) {
|
||||
list($entity_type, $bundle) = explode(':', $option);
|
||||
$batch['operations'][] = array('metatag_bulk_revert_batch_operation', array($entity_type, $bundle));
|
||||
}
|
||||
|
||||
batch_set($batch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch callback: delete custom metatags for selected bundles.
|
||||
*/
|
||||
function metatag_bulk_revert_batch_operation($entity_type, $bundle, &$context) {
|
||||
if (!isset($context['sandbox']['current'])) {
|
||||
$context['sandbox']['count'] = 0;
|
||||
$context['sandbox']['current'] = 0;
|
||||
}
|
||||
|
||||
// Query the selected entity table.
|
||||
$entity_info = entity_get_info($entity_type);
|
||||
$query = new EntityFieldQuery();
|
||||
$query->entityCondition('entity_type', $entity_type)
|
||||
->propertyCondition($entity_info['entity keys']['id'], $context['sandbox']['current'], '>')
|
||||
->propertyOrderBy($entity_info['entity keys']['id']);
|
||||
if ($entity_type != 'user') {
|
||||
/**
|
||||
* Entities which do not define a bundle such as User fail returning no results.
|
||||
* @see http://drupal.org/node/1054168#comment-5266208
|
||||
*/
|
||||
$query->entityCondition('bundle', $bundle);
|
||||
}
|
||||
// Get the total amount of entities to process.
|
||||
if (!isset($context['sandbox']['total'])) {
|
||||
$context['sandbox']['total'] = $query->count()->execute();
|
||||
$query->count = FALSE;
|
||||
|
||||
// If there are no bundles to revert, stop immediately.
|
||||
if (!$context['sandbox']['total']) {
|
||||
$context['finished'] = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Process 25 entities per iteration.
|
||||
$query->range(0, 25);
|
||||
$result = $query->execute();
|
||||
$ids = !empty($result[$entity_type]) ? array_keys($result[$entity_type]) : array();
|
||||
foreach ($ids as $id) {
|
||||
$metatags = metatag_metatags_load($entity_type, $id);
|
||||
if (!empty($metatags)) {
|
||||
db_delete('metatag')->condition('entity_type', $entity_type)
|
||||
->condition('entity_id', $id)
|
||||
->execute();
|
||||
metatag_metatags_cache_clear($entity_type, $id);
|
||||
$context['results'][] = t('Reverted metatags for @bundle with id @id.', array(
|
||||
'@bundle' => $entity_type . ': ' . $bundle,
|
||||
'@id' => $id,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$context['sandbox']['count'] += count($ids);
|
||||
$context['sandbox']['current'] = max($ids);
|
||||
|
||||
if ($context['sandbox']['count'] != $context['sandbox']['total']) {
|
||||
$context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch finished callback.
|
||||
*/
|
||||
function metatag_bulk_revert_batch_finished($success, $results, $operations) {
|
||||
if ($success) {
|
||||
if (!count($results)) {
|
||||
drupal_set_message(t('No metatags were reverted.'));
|
||||
}
|
||||
else {
|
||||
$message = theme('item_list', array('items' => $results));
|
||||
drupal_set_message($message);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$error_operation = reset($operations);
|
||||
drupal_set_message(t('An error occurred while processing @operation with arguments : @args',
|
||||
array('@operation' => $error_operation[0], '@args' => print_r($error_operation[0], TRUE))));
|
||||
}
|
||||
}
|
42
sites/all/modules/contrib/seo/metatag/metatag.admin.js
Normal file
42
sites/all/modules/contrib/seo/metatag/metatag.admin.js
Normal file
@@ -0,0 +1,42 @@
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.metatagUIConfigListing = {
|
||||
attach: function (context) {
|
||||
// Hide elements to be visible if JavaScript is enabled.
|
||||
$('.js-show').show();
|
||||
|
||||
// Make the leaf arrow clickable.
|
||||
$('.metatag-config-label').hover(function(){
|
||||
$(this).css({'cursor':'pointer'});
|
||||
})
|
||||
.click(function(){
|
||||
$(this).find('a.toggle-details', context).trigger('click');
|
||||
});
|
||||
|
||||
// Show or hide the summary
|
||||
$('table.metatag-config-overview a.toggle-details', context).click(function(event) {
|
||||
$(this).parent('div').siblings('div.metatag-config-details').each(function() {
|
||||
if ($(this).hasClass('js-hide')) {
|
||||
$(this).slideDown('slow').removeClass('js-hide');
|
||||
}
|
||||
else {
|
||||
$(this).slideUp('slow').addClass('js-hide');
|
||||
}
|
||||
});
|
||||
|
||||
// Change the expanded or collapsed state of the instance label.
|
||||
if ($(this).parent('div').hasClass('collapsed')) {
|
||||
$(this).parent('div').removeClass('collapsed').addClass('expanded');
|
||||
}
|
||||
else {
|
||||
$(this).parent('div').removeClass('expanded').addClass('collapsed');
|
||||
}
|
||||
|
||||
// This event may be triggered by a parent element click - so we don't
|
||||
// want the click to bubble up otherwise we get recursive click events.
|
||||
event.stopPropagation();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
286
sites/all/modules/contrib/seo/metatag/metatag.api.php
Normal file
286
sites/all/modules/contrib/seo/metatag/metatag.api.php
Normal file
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* API documentation for the Metatag module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* To enable Metatag support in custom entities, add 'metatags' => TRUE to the
|
||||
* entity definition in hook_entity_info(), e.g.:
|
||||
*
|
||||
* /**
|
||||
* * Implements hook_entity_info().
|
||||
* *
|
||||
* * Taken from the Examples module.
|
||||
* * /
|
||||
* function entity_example_entity_info() {
|
||||
* $info['entity_example_basic'] = array(
|
||||
* 'label' => t('Example Basic Entity'),
|
||||
* 'controller class' => 'EntityExampleBasicController',
|
||||
* 'base table' => 'entity_example_basic',
|
||||
* 'uri callback' => 'entity_example_basic_uri',
|
||||
* 'fieldable' => TRUE,
|
||||
* 'metatags' => TRUE,
|
||||
* 'entity keys' => array(
|
||||
* 'id' => 'basic_id' , // The 'id' (basic_id here) is the unique id.
|
||||
* 'bundle' => 'bundle_type' // Bundle will be determined by the 'bundle_type' field
|
||||
* ),
|
||||
* 'bundle keys' => array(
|
||||
* 'bundle' => 'bundle_type',
|
||||
* ),
|
||||
* 'static cache' => TRUE,
|
||||
* 'bundles' => array(
|
||||
* 'first_example_bundle' => array(
|
||||
* 'label' => 'First example bundle',
|
||||
* 'admin' => array(
|
||||
* 'path' => 'admin/structure/entity_example_basic/manage',
|
||||
* 'access arguments' => array('administer entity_example_basic entities'),
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* 'view modes' => array(
|
||||
* 'tweaky' => array(
|
||||
* 'label' => t('Tweaky'),
|
||||
* 'custom settings' => FALSE,
|
||||
* ),
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* return $info;
|
||||
* }
|
||||
*
|
||||
* The definition of each bundle may be handled separately, thus support may be
|
||||
* disabled for the entity as a whole but enabled for individual bundles. This
|
||||
* is handled via the 'metatags' value on the bundle definition, e.g.:
|
||||
*
|
||||
* 'bundles' => array(
|
||||
* 'first_example_bundle' => array(
|
||||
* 'label' => 'First example bundle',
|
||||
* 'metatags' => TRUE,
|
||||
* 'admin' => array(
|
||||
* 'path' => 'admin/structure/entity_example_basic/manage',
|
||||
* 'access arguments' => array('administer entity_example_basic entities'),
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides a default configuration for Metatag intances.
|
||||
*
|
||||
* This hook allows modules to provide their own Metatag instances which can
|
||||
* either be used as-is or as a "starter" for users to build from.
|
||||
*
|
||||
* This hook should be placed in MODULENAME.metatag.inc and it will be auto-
|
||||
* loaded. MODULENAME.metatag.inc *must* be in the same directory as the
|
||||
* .module file which *must* also contain an implementation of
|
||||
* hook_ctools_plugin_api, preferably with the same code as found in
|
||||
* metatag_ctools_plugin_api().
|
||||
*
|
||||
* The $config->disabled boolean attribute indicates whether the Metatag
|
||||
* instance should be enabled (FALSE) or disabled (TRUE) by default.
|
||||
*
|
||||
* @return
|
||||
* An associative array containing the structures of Metatag instances, as
|
||||
* generated from the Export tab, keyed by the Metatag config name.
|
||||
*
|
||||
* @see metatag_metatag_config_default()
|
||||
* @see metatag_ctools_plugin_api()
|
||||
*/
|
||||
function hook_metatag_config_default() {
|
||||
$configs = array();
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'config1';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'title' => array('value' => '[current-page:title] | [site:name]'),
|
||||
'generator' => array('value' => 'Drupal 7 (http://drupal.org)'),
|
||||
'canonical' => array('value' => '[current-page:url:absolute]'),
|
||||
'shortlink' => array('value' => '[current-page:url:unaliased]'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'config2';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'title' => array('value' => '[user:name] | [site:name]'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
return $configs;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_default_alter(&$config) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_delete($entity_type, $entity_ids, $revision_ids, $langcode) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_insert($config) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_instance_info() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_instance_info_alter(&$info) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_load() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_load_presave() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_presave($config) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_config_update($config) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_info() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_info_alter(&$info) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_load_entity_from_path_alter(&$path, $result) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter metatags before being cached.
|
||||
*
|
||||
* This hook is invoked prior to the meta tags for a given page are cached.
|
||||
*
|
||||
* @param array $output
|
||||
* All of the meta tags to be output for this page in their raw format. This
|
||||
* is a heavily nested array.
|
||||
* @param string $instance
|
||||
* An identifier for the current page's page type, typically a combination
|
||||
* of the entity name and bundle name, e.g. "node:story".
|
||||
*/
|
||||
function hook_metatag_metatags_view_alter(&$output, $instance) {
|
||||
if (isset($output['description']['#attached']['drupal_add_html_head'][0][0]['#value'])) {
|
||||
$output['description']['#attached']['drupal_add_html_head'][0][0]['#value'] = 'O rly?';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_page_cache_cid_parts_alter(&$cid_parts) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function hook_metatag_presave(&$metatags, $entity_type, $entity_id, $revision_id, $langcode) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows modules to alter the defined list of tokens available
|
||||
* for metatag patterns replacements.
|
||||
*
|
||||
* By default only context (for example: global, node, etc...)
|
||||
* related tokens are made available to metatag patterns replacements.
|
||||
* This hook allows other modules to extend the default declared tokens.
|
||||
*
|
||||
* @param array $options
|
||||
* (optional) An array of options including the following keys and values:
|
||||
* - token types: An array of token types to be passed to theme_token_tree().
|
||||
* - context: An identifier for the configuration instance type, typically
|
||||
* an entity name or object name, e.g. node, views, taxonomy_term.
|
||||
*
|
||||
* @see metatag_config_edit_form()
|
||||
* @see metatag_field_attach_form()
|
||||
*/
|
||||
function hook_metatag_token_types_alter(&$options) {
|
||||
// Watchout: $options['token types'] might be empty
|
||||
if (!isset($options['token types'])) {
|
||||
$options['token types'] = array();
|
||||
}
|
||||
|
||||
if ($options['context'] == 'config1'){
|
||||
$options['token types'] += array('token_type1','token_type2');
|
||||
}
|
||||
elseif ($options['context'] == 'config2'){
|
||||
$options['token types'] += array('token_type3','token_type4');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows modules to alter defined token patterns and values before replacement.
|
||||
*
|
||||
* The metatag module defines default token patterns replacements depending on
|
||||
* the different configuration instances (contexts, such as global, node, ...).
|
||||
* This hook provides an opportunity for other modules to alter the patterns or
|
||||
* the values for replacements, before tokens are replaced (token_replace).
|
||||
*
|
||||
* See facetapi and facetapi_bonus modules for an example of implementation.
|
||||
*
|
||||
* @param $pattern
|
||||
* A string potentially containing replaceable tokens. The pattern could also
|
||||
* be altered by reference, allowing modules to implement further logic, such
|
||||
* as tokens lists or masks/filters.
|
||||
* @param $types
|
||||
* Corresponds to the 'token data' property of the $options object.
|
||||
* (optional) An array of keyed objects. For simple replacement scenarios
|
||||
* 'node', 'user', and others are common keys, with an accompanying node or
|
||||
* user object being the value. Some token types, like 'site', do not require
|
||||
* any explicit information from $data and can be replaced even if it is
|
||||
* empty.
|
||||
*
|
||||
* @see DrupalTextMetaTag::getValue()
|
||||
*/
|
||||
function hook_metatag_pattern_alter(&$pattern, &$types) {
|
||||
if (strpos($pattern, 'token_type1') !== FALSE) {
|
||||
$types['token_type1'] = "data to be used in hook_tokens for replacement";
|
||||
}
|
||||
if (strpos($pattern, 'token_type2') !== FALSE) {
|
||||
// Load something or do some operations.
|
||||
$types['token_type2'] = array("Then fill in the array with the right data");
|
||||
// $pattern could also be altered, for example, strip off [token_type3].
|
||||
$pattern = str_replace('[token_type3]', '', $pattern);
|
||||
}
|
||||
}
|
87
sites/all/modules/contrib/seo/metatag/metatag.features.inc
Normal file
87
sites/all/modules/contrib/seo/metatag/metatag.features.inc
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Features integration for the Metatag module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_features_export().
|
||||
*/
|
||||
function metatag_features_export($data, &$export, $module_name = '', $type = 'metatag') {
|
||||
$pipe = array();
|
||||
|
||||
foreach ($data as $name) {
|
||||
if (metatag_config_load($name)) {
|
||||
$export['features'][$type][$name] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
$export['dependencies']['metatag'] = 'metatag';
|
||||
|
||||
return $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_render().
|
||||
*/
|
||||
function metatag_features_export_render($module_name, $data, $export = NULL) {
|
||||
$code = array();
|
||||
$code[] = ' $config = array();';
|
||||
$code[] = '';
|
||||
|
||||
foreach ($data as $key => $name) {
|
||||
if (is_object($name)) {
|
||||
$name = $name->instance;
|
||||
}
|
||||
if ($config = metatag_config_load($name)) {
|
||||
$export = new stdClass();
|
||||
$export->instance = $config->instance;
|
||||
$export->config = $config->config;
|
||||
$export = features_var_export($export, ' ');
|
||||
$key = features_var_export($name);
|
||||
$code[] = " // Exported Metatag config instance: {$name}.";
|
||||
$code[] = " \$config[{$key}] = {$export};";
|
||||
$code[] = "";
|
||||
}
|
||||
}
|
||||
$code[] = ' return $config;';
|
||||
$code = implode("\n", $code);
|
||||
return array('metatag_export_default' => $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_revert().
|
||||
*/
|
||||
function metatag_features_revert($module) {
|
||||
if ($feature_conf = features_get_default('metatag', $module)) {
|
||||
foreach (array_keys($feature_conf) as $config) {
|
||||
if ($conf = metatag_config_load($config)) {
|
||||
db_delete('metatag_config')->condition('instance', $config)->execute();
|
||||
}
|
||||
unset($feature_conf[$config]['cid']);
|
||||
$object = new stdClass();
|
||||
$object->cid = NULL;
|
||||
$object->instance = $config;
|
||||
$object->config = $feature_conf[$config]['config'];
|
||||
metatag_config_save($object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_options().
|
||||
*/
|
||||
function metatag_features_export_options() {
|
||||
$instances = metatag_config_instance_info();
|
||||
foreach ($instances as $key => $instance) {
|
||||
$options[$key] = $key;
|
||||
};
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_rebuild().
|
||||
*/
|
||||
function metatag_features_rebuild($module) {
|
||||
metatag_features_revert($module);
|
||||
}
|
53
sites/all/modules/contrib/seo/metatag/metatag.feeds.inc
Normal file
53
sites/all/modules/contrib/seo/metatag/metatag.feeds.inc
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Feeds mapping implementation for the Metatag module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_feeds_processor_targets_alter().
|
||||
*/
|
||||
function metatag_feeds_processor_targets_alter(&$targets, $entity_type, $bundle) {
|
||||
if (metatag_entity_supports_metatags($entity_type)) {
|
||||
$info = metatag_get_info();
|
||||
foreach ($info['tags'] as $name => $tag) {
|
||||
$targets['meta_' . $name] = array(
|
||||
'name' => 'Meta tag: ' . check_plain($tag['label']),
|
||||
'callback' => 'metatag_feeds_set_target',
|
||||
'description' => $tag['description'],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to set value of a metatag tag.
|
||||
*/
|
||||
function metatag_feeds_set_target($source, $entity, $target, $value) {
|
||||
// Don't do anything if we weren't given any data.
|
||||
if (empty($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Strip the prefix that was added above.
|
||||
$name = str_replace('meta_', '', $target);
|
||||
|
||||
// Load full metatag object if exists and has not been already loaded.
|
||||
if (!isset($entity->metatags) && !empty($entity->feeds_item->entity_id) && is_numeric($entity->feeds_item->entity_id)) {
|
||||
$entity_type = $entity->feeds_item->entity_type;
|
||||
$entity_id = $entity->feeds_item->entity_id;
|
||||
$entities = entity_load($entity_type, array($entity_id));
|
||||
if (!empty($entities)) {
|
||||
$stored_entity = reset($entities);
|
||||
$metatags = metatag_metatags_load($entity_type, $entity_id);
|
||||
if (!empty($stored_entity) && !empty($metatags)) {
|
||||
$stored_entity_language = metatag_entity_get_language($entity_type, $stored_entity);
|
||||
$entity->metatags = isset($metatags[$stored_entity_language]) ? $metatags[$stored_entity_language] : array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assign the value.
|
||||
$entity->metatags[$name]['value'] = $value;
|
||||
}
|
||||
|
18
sites/all/modules/contrib/seo/metatag/metatag.i18n.inc
Normal file
18
sites/all/modules/contrib/seo/metatag/metatag.i18n.inc
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Internationalization (i18n) hooks.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_i18n_string_info().
|
||||
*/
|
||||
function metatag_i18n_string_info() {
|
||||
$groups['metatag'] = array(
|
||||
'title' => t('Metatag'),
|
||||
'description' => t('Configurable metatags.'),
|
||||
'format' => FALSE,
|
||||
'list' => FALSE,
|
||||
);
|
||||
return $groups;
|
||||
}
|
272
sites/all/modules/contrib/seo/metatag/metatag.inc
Normal file
272
sites/all/modules/contrib/seo/metatag/metatag.inc
Normal file
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
|
||||
interface DrupalMetaTagInterface {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $info
|
||||
* The information about the meta tag from metatag_get_info().
|
||||
*/
|
||||
function __construct(array $info, array $data = array());
|
||||
|
||||
function getForm();
|
||||
|
||||
//function validateForm();
|
||||
|
||||
//function processForm();
|
||||
|
||||
function getValue();
|
||||
|
||||
function getElement();
|
||||
|
||||
function tidyValue($value);
|
||||
}
|
||||
|
||||
class DrupalDefaultMetaTag implements DrupalMetaTagInterface {
|
||||
|
||||
protected $info;
|
||||
protected $data = array('value' => '');
|
||||
|
||||
function __construct(array $info, array $data = NULL) {
|
||||
$this->info = $info;
|
||||
if (isset($data)) {
|
||||
$this->data = $data;
|
||||
}
|
||||
}
|
||||
|
||||
public function getForm(array $options = array()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getValue(array $options = array()) {
|
||||
return tidyValue($this->data['value']);
|
||||
}
|
||||
|
||||
public function getElement(array $options = array()) {
|
||||
$element = isset($this->info['element']) ? $this->info['element'] : array();
|
||||
|
||||
$value = $this->getValue($options);
|
||||
if (strlen($value) === 0) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$element += array(
|
||||
'#theme' => 'metatag',
|
||||
'#tag' => 'meta',
|
||||
'#id' => 'metatag_' . $this->info['name'],
|
||||
'#name' => $this->info['name'],
|
||||
'#value' => $value,
|
||||
);
|
||||
|
||||
// Add header information if desired.
|
||||
if (!empty($this->info['header'])) {
|
||||
$element['#attached']['drupal_add_http_header'][] = array($this->info['header'], $value);
|
||||
}
|
||||
|
||||
return array(
|
||||
'#attached' => array('drupal_add_html_head' => array(array($element, $element['#id']))),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unwanted formatting from a meta tag.
|
||||
*
|
||||
* @param $value string
|
||||
* The meta tag value to be tidied up.
|
||||
*
|
||||
* @return string
|
||||
* The meta tag value after it has been tidied up.
|
||||
*/
|
||||
public function tidyValue($value) {
|
||||
// Convert any HTML entities into regular characters.
|
||||
$value = decode_entities($value);
|
||||
|
||||
// Remove any HTML code that might have been included.
|
||||
$value = strip_tags($value);
|
||||
|
||||
// Strip errant whitespace.
|
||||
$value = str_replace(array("\r\n", "\n", "\r", "\t"), ' ', $value);
|
||||
$value = str_replace(' ', ' ', $value);
|
||||
$value = str_replace(' ', ' ', $value);
|
||||
$value = trim($value);
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Text-based meta tag controller.
|
||||
*/
|
||||
class DrupalTextMetaTag extends DrupalDefaultMetaTag {
|
||||
|
||||
public function getForm(array $options = array()) {
|
||||
$options += array(
|
||||
'token types' => array(),
|
||||
);
|
||||
|
||||
$form['value'] = isset($this->info['form']) ? $this->info['form'] : array();
|
||||
|
||||
$form['value'] += array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->info['label'],
|
||||
'#description' => !empty($this->info['description']) ? $this->info['description'] : '',
|
||||
'#default_value' => isset($this->data['value']) ? $this->data['value'] : '',
|
||||
'#element_validate' => array('token_element_validate'),
|
||||
'#token_types' => $options['token types'],
|
||||
'#maxlength' => 1024,
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
public function getValue(array $options = array()) {
|
||||
$options += array(
|
||||
'instance' => '',
|
||||
'token data' => array(),
|
||||
'clear' => TRUE,
|
||||
'sanitize' => TRUE,
|
||||
'raw' => FALSE,
|
||||
);
|
||||
|
||||
$name = "metatag:" . $options["instance"] . ":" . $this->info["name"];
|
||||
|
||||
$value = metatag_translate($name, $this->data['value']);
|
||||
if (empty($options['raw'])) {
|
||||
// Give other modules the opportunity to use hook_metatag_pattern_alter()
|
||||
// to modify defined token patterns and values before replacement.
|
||||
drupal_alter('metatag_pattern', $value, $options['token data']);
|
||||
$value = token_replace($value, $options['token data'], $options);
|
||||
}
|
||||
return $this->tidyValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Link type meta tag controller.
|
||||
*/
|
||||
class DrupalLinkMetaTag extends DrupalTextMetaTag {
|
||||
|
||||
public function getElement(array $options = array()) {
|
||||
$element = isset($this->info['element']) ? $this->info['element'] : array();
|
||||
|
||||
$value = $this->getValue($options);
|
||||
if (strlen($value) === 0) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$element += array(
|
||||
'#theme' => 'metatag_link_rel',
|
||||
'#tag' => 'link',
|
||||
'#id' => 'metatag_' . $this->info['name'],
|
||||
'#name' => $this->info['name'],
|
||||
'#value' => $value,
|
||||
);
|
||||
|
||||
if (!isset($this->info['header']) || !empty($this->info['header'])) {
|
||||
// Also send the generator in the HTTP header.
|
||||
// @todo This does not support 'rev' or alternate link headers.
|
||||
$element['#attached']['drupal_add_http_header'][] = array('Link', '<' . check_plain($value) . '>;' . drupal_http_header_attributes(array('rel' => $element['#name'])), TRUE);
|
||||
}
|
||||
|
||||
return array(
|
||||
'#attached' => array('drupal_add_html_head' => array(array($element, $element['#id']))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Title meta tag controller.
|
||||
*
|
||||
* This extends DrupalTextMetaTag as we need to alter variables in
|
||||
* template_preprocess_html() rather output a normal meta tag.
|
||||
*/
|
||||
class DrupalTitleMetaTag extends DrupalTextMetaTag {
|
||||
|
||||
public function getElement(array $options = array()) {
|
||||
$element = array();
|
||||
$value = check_plain($this->getValue($options));
|
||||
$element['#attached']['metatag_set_preprocess_variable'][] = array('html', 'head_title', $value);
|
||||
$element['#attached']['metatag_set_preprocess_variable'][] = array('html', 'head_array', array('title' => $value));
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiple value meta tag controller.
|
||||
*/
|
||||
class DrupalListMetaTag extends DrupalDefaultMetaTag {
|
||||
|
||||
function __construct(array $info, array $data = NULL) {
|
||||
// Ensure that the $data['value] argument is an array.
|
||||
if (empty($data['value'])) {
|
||||
$data['value'] = array();
|
||||
}
|
||||
$data['value'] = (array) $data['value'];
|
||||
|
||||
parent::__construct($info, $data);
|
||||
}
|
||||
|
||||
public function getForm(array $options = array()) {
|
||||
$form['value'] = isset($this->info['form']) ? $this->info['form'] : array();
|
||||
|
||||
$form['value'] += array(
|
||||
'#type' => 'checkboxes',
|
||||
'#title' => $this->info['label'],
|
||||
'#description' => !empty($this->info['description']) ? $this->info['description'] : '',
|
||||
'#default_value' => isset($this->data['value']) ? $this->data['value'] : array(),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
public function getValue(array $options = array()) {
|
||||
$values = array_keys(array_filter($this->data['value']));
|
||||
sort($values);
|
||||
$value = implode(', ', $values);
|
||||
return $this->tidyValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Date interval meta tag controller.
|
||||
*/
|
||||
class DrupalDateIntervalMetaTag extends DrupalDefaultMetaTag {
|
||||
|
||||
public function getForm(array $options = array()) {
|
||||
$form['value'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('@title interval', array('@title' => $this->info['label'])),
|
||||
'#default_value' => isset($this->data['value']) ? $this->data['value'] : '',
|
||||
'#element_validate' => array('element_validate_integer_positive'),
|
||||
'#maxlength' => 4,
|
||||
'#description' => isset($this->info['description']) ? $this->info['description'] : '',
|
||||
);
|
||||
$form['period'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('@title interval type', array('@title' => $this->info['label'])),
|
||||
'#default_value' => isset($this->data['period']) ? $this->data['period'] : '',
|
||||
'#options' => array(
|
||||
'' => t('- none -'),
|
||||
'day' => t('Day(s)'),
|
||||
'week' => t('Week(s)'),
|
||||
'month' => t('Month(s)'),
|
||||
'year' => t('Year(s)'),
|
||||
),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
public function getValue(array $options = array()) {
|
||||
$value = '';
|
||||
if (!empty($this->data['value'])) {
|
||||
$interval = intval($this->data['value']);
|
||||
if (!empty($interval) && !empty($this->data['period'])) {
|
||||
$period = $this->data['period'];
|
||||
$value = format_plural($interval, '@count ' . $period, '@count ' . $period . 's');
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
}
|
24
sites/all/modules/contrib/seo/metatag/metatag.info
Normal file
24
sites/all/modules/contrib/seo/metatag/metatag.info
Normal file
@@ -0,0 +1,24 @@
|
||||
name = Metatag
|
||||
description = "Adds support and an API to implement meta tags."
|
||||
package = SEO
|
||||
core = 7.x
|
||||
|
||||
; This requires Drupal 7.15 or newer.
|
||||
dependencies[] = system (>=7.15)
|
||||
|
||||
; CTools and Token are also required.
|
||||
dependencies[] = ctools
|
||||
dependencies[] = token
|
||||
|
||||
configure = admin/config/search/metatags
|
||||
|
||||
files[] = metatag.inc
|
||||
files[] = metatag.migrate.inc
|
||||
files[] = metatag.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
924
sites/all/modules/contrib/seo/metatag/metatag.install
Normal file
924
sites/all/modules/contrib/seo/metatag/metatag.install
Normal file
@@ -0,0 +1,924 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Install, update, and uninstall functions for the metatag module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function metatag_requirements($phase) {
|
||||
$requirements = array();
|
||||
// Ensure translations don't break during installation.
|
||||
$t = get_t();
|
||||
|
||||
if ($phase == 'runtime') {
|
||||
// Work out the release of D7 that is currently running.
|
||||
list($major, $minor) = explode('.', VERSION);
|
||||
// Strip off any suffixes on the version string, e.g. "17-dev".
|
||||
if (strpos('-', $minor)) {
|
||||
list($minor, $suffix) = explode('-', $minor);
|
||||
}
|
||||
|
||||
// Releases of Drupal older than 7.15 did not have entity_language(), which
|
||||
// is now required.
|
||||
if ($minor < 15) {
|
||||
$requirements['metatag'] = array(
|
||||
'severity' => REQUIREMENT_WARNING,
|
||||
'title' => 'Metatag',
|
||||
'value' => $t('Upgrade Drupal core to v7.15 or newer'),
|
||||
'description' => $t("This older version of Drupal core is missing functionality necessary for the module's multilingual support, it must be upgraded to at least version 7.15."),
|
||||
);
|
||||
}
|
||||
// Releases of Drupal older than 7.17 did not trigger hook_entity_view on
|
||||
// term pages, so recommend updating.
|
||||
elseif ($minor < 17) {
|
||||
$requirements['metatag'] = array(
|
||||
'severity' => REQUIREMENT_WARNING,
|
||||
'title' => 'Metatag',
|
||||
'value' => $t('Upgrade Drupal core to v7.17 or newer'),
|
||||
'description' => $t('Your older version of Drupal core is missing functionality necessary for taxonomy term pages to work correctly, it is strongly recommended to upgrade to the latest release.'),
|
||||
);
|
||||
}
|
||||
// Everything's OK.
|
||||
else {
|
||||
$requirements['metatag'] = array(
|
||||
'severity' => REQUIREMENT_OK,
|
||||
'title' => 'Metatag',
|
||||
'value' => $t('Drupal core is compatible'),
|
||||
'description' => $t('Older versions of Drupal core were missing functionality necessary for taxonomy term pages to work correctly, but this version <em>will</em> work correctly.'),
|
||||
);
|
||||
}
|
||||
|
||||
// Add a note if Page Title is also installed.
|
||||
if (module_exists('page_title')) {
|
||||
$requirements['metatag_page_title'] = array(
|
||||
'severity' => REQUIREMENT_INFO,
|
||||
'title' => 'Metatag',
|
||||
'value' => $t('Possible conflicts with Page Title module'),
|
||||
'description' => $t('The Metatag module is able to customize page titles so running the Page Title module simultaneously can lead to complications.'),
|
||||
);
|
||||
}
|
||||
|
||||
// Add a note if Page Title is also installed.
|
||||
if (module_exists('exclude_node_title')) {
|
||||
$requirements['metatag_exclude_node_title'] = array(
|
||||
'severity' => REQUIREMENT_INFO,
|
||||
'title' => 'Metatag',
|
||||
'value' => $t('Possible conflicts with Exclude Node Title module'),
|
||||
'description' => $t('The Metatag module\'s default settings for content types (nodes) uses [node:title] for the page title. Unfortunately, Exclude Node Title hides this so the page title ends up blank. It is recommended to <a href="!config">change the "title" field\'s default value</a> to "[current-page:title]" instead of "[node:title]" for any content types affected by Exclude Node Title.', array('!config' => 'admin/config/search/metatags')),
|
||||
);
|
||||
}
|
||||
|
||||
// Add a note if the deprecated metatag.entity_translation.inc file still
|
||||
// exists.
|
||||
$filename = 'metatag.entity_translation.inc';
|
||||
if (file_exists(dirname(__FILE__) . '/' . $filename)) {
|
||||
$requirements['metatag_deprecated_et_file'] = array(
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
'title' => 'Metatag',
|
||||
'value' => $t('Unwanted :filename file found', array(':filename' => $filename)),
|
||||
'description' => $t("The :filename file was removed in v7.x-1.0-beta5 but it still exists in the site's Metatag module's directory and will cause problems. This file needs to be removed. The file's path in the Drupal directory structure is:<br /><code>!short_path</code><br />The file's full path is:<br /><code>!full_path</code>", array(':filename' => $filename, '!short_path' => drupal_get_path('module', 'metatag') . '/' . $filename, '!full_path' => dirname(__FILE__) . $filename)),
|
||||
);
|
||||
}
|
||||
|
||||
// Check that Entity_Translation is current.
|
||||
if (module_exists('entity_translation')) {
|
||||
$rev = db_query("SELECT schema_version FROM {system} WHERE name = :module", array(':module' => 'entity_translation'))->fetchColumn();
|
||||
if ($rev < 7004) {
|
||||
$requirements['metatag_et_old'] = array(
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
'title' => 'Metatag',
|
||||
'value' => $t('<a href="@url">Entity_Translation</a> is out of date and requires updating', array('@url' => 'http://drupal.org/project/entity_translation')),
|
||||
'description' => $t('The Entity_Translation module is out of date and needs to be updated in order to be compatible with Metatag.'),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_schema().
|
||||
*/
|
||||
function metatag_schema() {
|
||||
$schema['metatag_config'] = array(
|
||||
'description' => 'Storage of meta tag configuration and defaults.',
|
||||
'export' => array(
|
||||
'key' => 'instance',
|
||||
'key name' => 'Instance',
|
||||
'primary key' => 'cid',
|
||||
'identifier' => 'config',
|
||||
'default hook' => 'metatag_config_default',
|
||||
'api' => array(
|
||||
'owner' => 'metatag',
|
||||
'api' => 'metatag',
|
||||
'minimum_version' => 1,
|
||||
'current_version' => 1,
|
||||
),
|
||||
'cache defaults' => TRUE,
|
||||
'default cache bin' => 'cache_metatag',
|
||||
),
|
||||
'fields' => array(
|
||||
'cid' => array(
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'The primary identifier for a metatag configuration set.',
|
||||
'no export' => TRUE,
|
||||
),
|
||||
'instance' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'The machine-name of the configuration, typically entity-type:bundle.',
|
||||
),
|
||||
'config' => array(
|
||||
'type' => 'blob',
|
||||
'size' => 'big',
|
||||
'not null' => TRUE,
|
||||
'serialize' => TRUE,
|
||||
'description' => 'Serialized data containing the meta tag configuration.',
|
||||
'translatable' => TRUE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('cid'),
|
||||
'unique keys' => array(
|
||||
'instance' => array('instance'),
|
||||
),
|
||||
);
|
||||
|
||||
$schema['metatag'] = array(
|
||||
'fields' => array(
|
||||
'entity_type' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 32,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'The entity type this data is attached to.',
|
||||
),
|
||||
'entity_id' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'description' => 'The entity id this data is attached to.',
|
||||
),
|
||||
'revision_id' => array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'default' => 0,
|
||||
'description' => 'The revision_id for the entity object this data is attached to.',
|
||||
),
|
||||
'language' => array(
|
||||
'type' => 'varchar',
|
||||
'length' => 32,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'The language of the tag.',
|
||||
),
|
||||
'data' => array(
|
||||
'type' => 'blob',
|
||||
'size' => 'big',
|
||||
'not null' => TRUE,
|
||||
'serialize' => TRUE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('entity_type', 'entity_id', 'revision_id', 'language'),
|
||||
);
|
||||
|
||||
$schema['cache_metatag'] = drupal_get_schema_unprocessed('system', 'cache');
|
||||
$schema['cache_metatag']['description'] = t('Cache table for the generated meta tag output.');
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function metatag_install() {
|
||||
drupal_set_message(t("Thank you for installing the Metatag module. It is recommended to read the module's <a href=\"!url\" title=\"Read the Metatag module's documentation\">README.txt</a> file as there are some known issues that may afffect this site.", array('!url' => url(drupal_get_path('module', 'metatag') . '/README.txt'))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function metatag_uninstall() {
|
||||
// This variable is created via hook_enable.
|
||||
variable_del('metatag_schema_installed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_enable().
|
||||
*/
|
||||
function metatag_enable() {
|
||||
variable_set('metatag_schema_installed', TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_disable().
|
||||
*/
|
||||
// function metatag_disable() {
|
||||
// }
|
||||
|
||||
/**
|
||||
* Disable the deprecated metatag_ui module which has been merged into metatag.
|
||||
*/
|
||||
function metatag_update_7000() {
|
||||
if (module_exists('metatag_ui')) {
|
||||
module_disable(array('metatag_ui'), FALSE);
|
||||
drupal_uninstall_modules(array('metatag_ui'), FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the "{metatag_config}.cid column cannot be NULL" error.
|
||||
*/
|
||||
function metatag_update_7001() {
|
||||
$table_name = 'metatag_config';
|
||||
$field_name = 'cid';
|
||||
$field_spec = array(
|
||||
'type' => 'serial',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'description' => 'The primary identifier for a metatag configuration set.',
|
||||
);
|
||||
$keys = array('primary key' => array($field_name));
|
||||
|
||||
// Before making any changes, drop the existing primary key. Unforunately
|
||||
// there is no API way to check if a primary key exists, so if it doesn't
|
||||
// exist the db_drop_primary_key() call will fail.
|
||||
try {
|
||||
db_drop_primary_key($table_name);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
drupal_set_message('Caught an exception: ', $e->getMessage());
|
||||
}
|
||||
|
||||
// Rejig the field, and turn on the primary key again.
|
||||
db_change_field($table_name, $field_name, $field_name, $field_spec, $keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the deprecated metatag_ui module which has been merged into metatag,
|
||||
* again.
|
||||
*/
|
||||
function metatag_update_7002() {
|
||||
if (module_exists('metatag_ui')) {
|
||||
module_disable(array('metatag_ui'), FALSE);
|
||||
drupal_uninstall_modules(array('metatag_ui'), FALSE);
|
||||
drupal_set_message(t('The deprecated Metatag UI module has been disabled.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the {metatag}.language field.
|
||||
*/
|
||||
function metatag_update_7003() {
|
||||
// Set the target table and field name.
|
||||
$table_name = 'metatag';
|
||||
$field_name = 'language';
|
||||
|
||||
// Don't add the new field if it already exists.
|
||||
if (!db_field_exists($table_name, $field_name)) {
|
||||
// Describe the new field.
|
||||
$field_spec = array(
|
||||
'type' => 'varchar',
|
||||
'length' => 32,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
'description' => 'The language of the tag',
|
||||
);
|
||||
|
||||
// Add it and update the primary key.
|
||||
db_add_field($table_name, $field_name, $field_spec);
|
||||
db_drop_primary_key($table_name);
|
||||
db_add_primary_key($table_name, array('entity_type', 'entity_id', 'language'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaced by updates 7009, 7010, 7011, 7012 and 7013.
|
||||
*/
|
||||
function metatag_update_7004() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Removing wrong metatag watchdog entries that break the admin/reports/dblog
|
||||
* page.
|
||||
*/
|
||||
function metatag_update_7005() {
|
||||
if (db_table_exists('watchdog')) {
|
||||
db_delete('watchdog')
|
||||
->condition('type', 'metatag')
|
||||
->condition('variables', serialize('info'))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove {metatag} records that were added by old versions of the module for
|
||||
* entities that don't actually support Metatag. A more complete version of
|
||||
* this will be added later on after it's (hopefully) guaranteed that all
|
||||
* modules have updated to the correct API usage.
|
||||
*/
|
||||
function metatag_update_7006() {
|
||||
$entity_types = array(
|
||||
// Core.
|
||||
'comment',
|
||||
'menu_link',
|
||||
'taxonomy_vocabulary',
|
||||
// Some contrib entities.
|
||||
'mailchimp_list',
|
||||
'profile2',
|
||||
'profile2_type',
|
||||
'redirect',
|
||||
'rules_config',
|
||||
'wysiwyg_profile',
|
||||
);
|
||||
foreach ($entity_types as $entity_type) {
|
||||
$num_deleted = db_delete('metatag')
|
||||
->condition('entity_type', $entity_type)
|
||||
->execute();
|
||||
if ($num_deleted > 0) {
|
||||
drupal_set_message(t('Removed @count meta tag record(s) for the @type entity type, it does not support meta tags.', array('@count' => $num_deleted, '@type' => $entity_type)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove {metatag} records for objects that have been deleted; older versions
|
||||
* of Metatag may have failed to purge these.
|
||||
*/
|
||||
function metatag_update_7007() {
|
||||
$nodes = db_query("SELECT m.entity_id
|
||||
FROM {metatag} m
|
||||
LEFT OUTER JOIN {node} n
|
||||
ON m.entity_id=n.nid
|
||||
WHERE m.entity_type='node'
|
||||
AND n.nid IS NULL")
|
||||
->fetchCol();
|
||||
if (count($nodes) > 0) {
|
||||
$deleted = db_delete('metatag')
|
||||
->condition('entity_type', 'node')
|
||||
->condition('entity_id', $nodes)
|
||||
->execute();
|
||||
if ($deleted > 0) {
|
||||
drupal_set_message(t('Removed @count meta tag record(s) for nodes that had been purged.', array('@count' => $deleted)));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('There were no meta tag records to purge for removed nodes. This is a good thing :)'));
|
||||
}
|
||||
}
|
||||
|
||||
$users = db_query("SELECT m.entity_id
|
||||
FROM {metatag} m
|
||||
LEFT OUTER JOIN {users} u
|
||||
ON m.entity_id=u.uid
|
||||
WHERE m.entity_type='user'
|
||||
AND u.uid IS NULL")
|
||||
->fetchCol();
|
||||
if (count($users) > 0) {
|
||||
$deleted = db_delete('metatag')
|
||||
->condition('entity_type', 'user')
|
||||
->condition('entity_id', $users)
|
||||
->execute();
|
||||
if ($deleted > 0) {
|
||||
drupal_set_message(t('Removed @count meta tag record(s) for users that had been purged.', array('@count' => $deleted)));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('There were no meta tag records to purge for removed users. This is a good thing :)'));
|
||||
}
|
||||
}
|
||||
|
||||
// Only run this if the Taxonomy module is enabled.
|
||||
if (module_exists('taxonomy')) {
|
||||
$terms = db_query("SELECT m.entity_id
|
||||
FROM {metatag} m
|
||||
LEFT OUTER JOIN {taxonomy_term_data} t
|
||||
ON m.entity_id=t.tid
|
||||
WHERE m.entity_type='taxonomy_term'
|
||||
AND t.tid IS NULL")
|
||||
->fetchCol();
|
||||
if (count($terms) > 0) {
|
||||
$deleted = db_delete('metatag')
|
||||
->condition('entity_type', 'taxonomy_term')
|
||||
->condition('entity_id', $terms)
|
||||
->execute();
|
||||
if ($deleted > 0) {
|
||||
drupal_set_message(t('Removed @count meta tag record(s) for taxonomy terms that had been purged.', array('@count' => $deleted)));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('There were no meta tag records to purge for removed taxonomy terms. This is a good thing :)'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any empty records that may be hanging around from old releases.
|
||||
*/
|
||||
function metatag_update_7008() {
|
||||
$conditions = db_or()
|
||||
->isNull('data')
|
||||
->condition('data', '')
|
||||
->condition('data', serialize(array()));
|
||||
$deleted = db_delete("metatag")
|
||||
->condition($conditions)
|
||||
->execute();
|
||||
if ($deleted > 0) {
|
||||
drupal_set_message(t('Purged @count empty meta tag record(s).', array('@count' => $deleted)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix {metatag} records for taxonomy terms.
|
||||
*/
|
||||
function metatag_update_7009() {
|
||||
if (module_exists('taxonomy')) {
|
||||
// Remove duplicates.
|
||||
_metatag_remove_dupes('taxonomy_term');
|
||||
}
|
||||
|
||||
// The taxonomy term entity doesn't support a 'language' option, so reset it
|
||||
// to LANGUAGE_NONE.
|
||||
$result = db_query("UPDATE {metatag} SET language = :language WHERE entity_type='taxonomy_term'", array(':language' => LANGUAGE_NONE));
|
||||
if ($result->rowCount() > 0) {
|
||||
drupal_set_message(t('Fixed language values for @count taxonomy terms.', array('@count' => $result->rowCount())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix {metatag} records for users.
|
||||
*/
|
||||
function metatag_update_7010() {
|
||||
// Remove duplicates.
|
||||
_metatag_remove_dupes('user');
|
||||
|
||||
// Update User values.
|
||||
$result = db_query("UPDATE {metatag} SET language = :language WHERE entity_type='user'", array(':language' => LANGUAGE_NONE));
|
||||
if ($result->rowCount() > 0) {
|
||||
drupal_set_message(t('Fixed language values for @count user records.', array('@count' => $result->rowCount())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix {metatag} records for nodes.
|
||||
*/
|
||||
function metatag_update_7011(&$sandbox) {
|
||||
// Only proceed if Entity_Translation is not enabled as it allows each node
|
||||
// record to have multiple languages available.
|
||||
if (module_exists('entity_translation')) {
|
||||
drupal_set_message(t("Entity Translation is enabled, so node meta tags will not be updated, to avoid accidental dataloss."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Process records by groups of 10 (arbitrary value).
|
||||
// When a group is processed, the batch update engine determines whether it
|
||||
// should continue processing in the same request or provide progress
|
||||
// feedback to the user and wait for the next request.
|
||||
$limit = 20;
|
||||
|
||||
// Use the sandbox at your convenience to store the information needed
|
||||
// to track progression between successive calls to the function.
|
||||
if (!isset($sandbox['progress'])) {
|
||||
// The count of records visited so far.
|
||||
$sandbox['progress'] = 0;
|
||||
|
||||
// Remove duplicates.
|
||||
_metatag_remove_dupes('node');
|
||||
|
||||
// Update Node values.
|
||||
$nodes = db_query("SELECT n.nid, n.language FROM {node} n INNER JOIN {metatag} m ON n.nid = m.entity_id WHERE m.entity_type = 'node' AND n.language != m.language ORDER BY nid");
|
||||
$sandbox['records'] = array();
|
||||
foreach ($nodes as $record) {
|
||||
$sandbox['records'][] = $record;
|
||||
}
|
||||
|
||||
// If there's no data, don't bother with the extra work.
|
||||
if (empty($sandbox['records'])) {
|
||||
watchdog('metatag', 'Update 7011: No nodes need the Metatag language values fixed.', array(), WATCHDOG_INFO);
|
||||
if (drupal_is_cli()) {
|
||||
drupal_set_message(t('Update 7011: No nodes need the Metatag language values fixed.'));
|
||||
}
|
||||
return t('No nodes need the Metatag language values fixed.');
|
||||
}
|
||||
|
||||
// Total records that must be visited.
|
||||
$sandbox['max'] = count($sandbox['records']);
|
||||
|
||||
// A place to store messages during the run.
|
||||
$sandbox['messages'] = array();
|
||||
|
||||
// An initial record of the number of records to be updated.
|
||||
watchdog('metatag', 'Update 7011: !count records to update.', array('!count' => $sandbox['max']), WATCHDOG_INFO);
|
||||
if (drupal_is_cli()) {
|
||||
drupal_set_message(t('Update 7011: !count records to update.', array('!count' => $sandbox['max'])));
|
||||
}
|
||||
|
||||
// Last record processed.
|
||||
$sandbox['current_record'] = -1;
|
||||
|
||||
// Because a lot of other processing happens on the first iteration, just do
|
||||
// one.
|
||||
$limit = 1;
|
||||
}
|
||||
|
||||
// The for loop will run as normal when ran via update.php, but when ran via
|
||||
// Drush it'll just run 'til it's finished.
|
||||
$increment = 1;
|
||||
if (drupal_is_cli()) {
|
||||
$increment = 0;
|
||||
}
|
||||
|
||||
// Set default values.
|
||||
for ($ctr = 0; $ctr < $limit; $ctr += $increment) {
|
||||
$sandbox['current_record']++;
|
||||
if (empty($sandbox['records'][$sandbox['current_record']])) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Shortcuts for later.
|
||||
$langcode = $sandbox['records'][$sandbox['current_record']]->language;
|
||||
$nid = $sandbox['records'][$sandbox['current_record']]->nid;
|
||||
|
||||
db_update('metatag')
|
||||
->fields(array('language' => $langcode))
|
||||
->condition('entity_type', 'node')
|
||||
->condition('entity_id', $nid)
|
||||
->execute();
|
||||
|
||||
// Update our progress information.
|
||||
$sandbox['progress']++;
|
||||
}
|
||||
|
||||
// Set the "finished" status, to tell batch engine whether this function
|
||||
// needs to run again. If you set a float, this will indicate the progress of
|
||||
// the batch so the progress bar will update.
|
||||
$sandbox['#finished'] = ($sandbox['progress'] >= $sandbox['max']) ? TRUE : ($sandbox['progress'] / $sandbox['max']);
|
||||
|
||||
if ($sandbox['#finished']) {
|
||||
// Clear all caches so the fixed data will be reloaded.
|
||||
cache_clear_all('*', 'cache_metatag', TRUE);
|
||||
|
||||
// A final log of the number of records that were converted.
|
||||
watchdog('metatag', 'Update 7011: !count records were updated in total.', array('!count' => $sandbox['progress']), WATCHDOG_INFO);
|
||||
if (drupal_is_cli()) {
|
||||
drupal_set_message(t('Update 7011: !count records were updated.', array('!count' => $sandbox['progress'])));
|
||||
}
|
||||
|
||||
// hook_update_N() may optionally return a string which will be displayed
|
||||
// to the user.
|
||||
return t('Fixed the Metatag language values for @count nodes.', array('!count' => $sandbox['progress']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove duplicate {metatag} records for non-core entities.
|
||||
*/
|
||||
function metatag_update_7012() {
|
||||
if (module_exists('entity_translation')) {
|
||||
drupal_set_message(t("Entity Translation is enabled, duplicate meta tags will not be removed for custom entities, to avoid accidental dataloss."));
|
||||
return;
|
||||
}
|
||||
|
||||
$records = db_select('metatag', 'm')
|
||||
->fields('m', array('entity_type'))
|
||||
->condition('m.entity_type', array('node', 'taxonomy_term', 'user'), 'NOT IN')
|
||||
->orderBy('m.entity_type', 'ASC')
|
||||
->orderBy('m.entity_id', 'ASC')
|
||||
->distinct()
|
||||
->execute();
|
||||
|
||||
$entity_types = array();
|
||||
foreach ($records as $record) {
|
||||
$entity_types[] = $record->entity_type;
|
||||
// Remove duplicates.
|
||||
_metatag_remove_dupes($record->entity_type);
|
||||
}
|
||||
|
||||
if (empty($entity_types)) {
|
||||
drupal_set_message(t('There were no other records to fix.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the {metatag} language value for all non-core entity records. This might
|
||||
* take a while, depending on how much data needs to be converted.
|
||||
*/
|
||||
function metatag_update_7013(&$sandbox) {
|
||||
if (module_exists('entity_translation')) {
|
||||
drupal_set_message(t("Entity Translation is enabled, meta tags will not be updated for custom entities, to avoid accidental dataloss."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the sandbox at your convenience to store the information needed
|
||||
// to track progression between successive calls to the function.
|
||||
if (!isset($sandbox['progress'])) {
|
||||
// The count of records visited so far.
|
||||
$sandbox['progress'] = 0;
|
||||
|
||||
// Because the {metatag} table uses multiple primary keys, there's no easy
|
||||
// way to do this, so we're going to cache all record keys and manually
|
||||
// step through them.
|
||||
$records = db_select('metatag', 'm')
|
||||
->fields('m', array('entity_type', 'entity_id'))
|
||||
->condition('m.entity_type', array('node', 'taxonomy_term', 'user'), 'NOT IN')
|
||||
->orderBy('m.entity_type', 'ASC')
|
||||
->orderBy('m.entity_id', 'ASC')
|
||||
->execute();
|
||||
$sandbox['records'] = array();
|
||||
foreach ($records as $record) {
|
||||
$sandbox['records'][] = $record;
|
||||
}
|
||||
|
||||
// If there's no data, don't bother with the extra work.
|
||||
if (empty($sandbox['records'])) {
|
||||
watchdog('metatag', 'Update 7013: No meta tag records need updating.', array(), WATCHDOG_INFO);
|
||||
if (drupal_is_cli()) {
|
||||
drupal_set_message(t('Update 7013: No meta tag records need updating.'));
|
||||
}
|
||||
return t('No meta tag records need updating.');
|
||||
}
|
||||
|
||||
// Total records that must be visited.
|
||||
$sandbox['max'] = count($sandbox['records']);
|
||||
|
||||
// A place to store messages during the run.
|
||||
$sandbox['messages'] = array();
|
||||
|
||||
// An initial record of the number of records to be updated.
|
||||
watchdog('metatag', 'Update 7013: !count records to update.', array('!count' => $sandbox['max']), WATCHDOG_INFO);
|
||||
if (drupal_is_cli()) {
|
||||
drupal_set_message(t('Update 7013: !count records to update.', array('!count' => $sandbox['max'])));
|
||||
}
|
||||
|
||||
// Last record processed.
|
||||
$sandbox['current_record'] = -1;
|
||||
}
|
||||
|
||||
// Process records by groups of 10 (arbitrary value).
|
||||
// When a group is processed, the batch update engine determines whether it
|
||||
// should continue processing in the same request or provide progress
|
||||
// feedback to the user and wait for the next request.
|
||||
$limit = 10;
|
||||
|
||||
// The for loop will run as normal when ran via update.php, but when ran via
|
||||
// Drush it'll just run 'til it's finished.
|
||||
$increment = 1;
|
||||
if (drupal_is_cli()) {
|
||||
$increment = 0;
|
||||
}
|
||||
|
||||
// Set default values.
|
||||
for ($ctr = 0; $ctr < $limit; $ctr += $increment) {
|
||||
$sandbox['current_record']++;
|
||||
if (empty($sandbox['records'][$sandbox['current_record']])) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Shortcuts for later.
|
||||
$entity_type = $sandbox['records'][$sandbox['current_record']]->entity_type;
|
||||
$entity_id = $sandbox['records'][$sandbox['current_record']]->entity_id;
|
||||
|
||||
// Load the entity.
|
||||
$entities = entity_load($entity_type, array($entity_id));
|
||||
if (!empty($entities)) {
|
||||
$entity = array_pop($entities);
|
||||
|
||||
// Make sure that the entity has a language set.
|
||||
if (!empty($entity)) {
|
||||
// If there's a (non-empty) language value, use it.
|
||||
$new_language = entity_language($entity_type, $entity);
|
||||
if (empty($new_language)) {
|
||||
$new_language = LANGUAGE_NONE;
|
||||
}
|
||||
// Update the 'language' value.
|
||||
db_update('metatag')
|
||||
->fields(array('language' => $new_language))
|
||||
->condition('entity_type', $entity_type)
|
||||
->condition('entity_id', $entity_id)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
||||
// Update our progress information.
|
||||
$sandbox['progress']++;
|
||||
}
|
||||
|
||||
// Set the "finished" status, to tell batch engine whether this function
|
||||
// needs to run again. If you set a float, this will indicate the progress of
|
||||
// the batch so the progress bar will update.
|
||||
$sandbox['#finished'] = ($sandbox['progress'] >= $sandbox['max']) ? TRUE : ($sandbox['progress'] / $sandbox['max']);
|
||||
|
||||
if ($sandbox['#finished']) {
|
||||
// Clear all caches so the fixed data will be reloaded.
|
||||
cache_clear_all('*', 'cache_metatag', TRUE);
|
||||
|
||||
// A final log of the number of records that were converted.
|
||||
watchdog('metatag', 'Update 7013: !count records were updated in total.', array('!count' => $sandbox['progress']), WATCHDOG_INFO);
|
||||
if (drupal_is_cli()) {
|
||||
drupal_set_message(t('Update 7013: !count records were updated.', array('!count' => $sandbox['progress'])));
|
||||
}
|
||||
|
||||
// hook_update_N() may optionally return a string which will be displayed
|
||||
// to the user.
|
||||
return t('!count records were updated in total.', array('!count' => $sandbox['progress']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove duplicate records for a given entity.
|
||||
*
|
||||
* It should be OK to run this without doing a separate batch process as there
|
||||
* shouldn't be many records that have this problem. Hopefully.
|
||||
*
|
||||
* @param $entity_type
|
||||
* The name of an entity type to check for.
|
||||
*/
|
||||
function _metatag_remove_dupes($entity_type) {
|
||||
$purge_count = 0;
|
||||
|
||||
// First step: fix the records. There should not be multiple records for the
|
||||
// same entity_id with different languages.
|
||||
$dupe_records = db_query("SELECT m.entity_id, count(m.language) AS the_count
|
||||
FROM {metatag} m
|
||||
WHERE
|
||||
m.entity_type = :type
|
||||
GROUP BY m.entity_id
|
||||
HAVING count(m.language) > 1", array(':type' => $entity_type));
|
||||
|
||||
if (!empty($dupe_records)) {
|
||||
foreach ($dupe_records as $record) {
|
||||
$entity_id = $record->entity_id;
|
||||
$langs = db_query("SELECT m.entity_id, m.language, m.data FROM {metatag} m WHERE m.entity_type = :type AND m.entity_id = :id", array(':type' => $entity_type, ':id' => $entity_id))->fetchAll();
|
||||
|
||||
// Work out which language record to remove. Will need to store this as
|
||||
// an array incase there are multiple records to purge.
|
||||
$langs_to_remove = array();
|
||||
|
||||
// Check for duplicate records.
|
||||
// Outer loop starts from the beginning.
|
||||
for ($outer = 0; $outer < count($langs); $outer++) {
|
||||
// This record may have been removed already.
|
||||
if (isset($langs[$outer])) {
|
||||
// Inner loop starts from the end.
|
||||
for ($inner = count($langs) - 1; $inner > 0; $inner--) {
|
||||
// Work out if the outer loop's data is the same as the inner
|
||||
// loop's.
|
||||
if (isset($langs[$inner]) && $langs[$outer]->data == $langs[$inner]->data) {
|
||||
// Remove the second record.
|
||||
$langs_to_remove[] = $langs[$inner]->language;
|
||||
unset($langs[$inner]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only one record left.
|
||||
if (count($langs) == 1) {
|
||||
// This is how it should be, this record is fine.
|
||||
}
|
||||
// More than one record, work out which one to keep.
|
||||
elseif (count($langs) > 1) {
|
||||
// Work out the entity's language.
|
||||
$entity = entity_load($entity_type, $entity_id);
|
||||
$entity_language = entity_language($entity_type, $entity);
|
||||
if (empty($language)) {
|
||||
$entity_language = LANGUAGE_NONE;
|
||||
}
|
||||
|
||||
// Work out if the entity's language record exists.
|
||||
$lang_pos = NULL;
|
||||
foreach ($langs as $key => $record) {
|
||||
if ($record->language == $entity_language) {
|
||||
$lang_pos = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If the language record exists, delete the others.
|
||||
if (isset($lang_pos)) {
|
||||
foreach ($langs as $key => $record) {
|
||||
if ($record->language != $entity_language) {
|
||||
$langs_to_remove[] = $record->language;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Otherwise look for a record for the site's default language.
|
||||
else {
|
||||
foreach ($langs as $key => $record) {
|
||||
if ($record->language == $GLOBALS['language']->language) {
|
||||
$lang_pos = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isset($lang_pos)) {
|
||||
foreach ($langs as $key => $record) {
|
||||
if ($record->language != $GLOBALS['language']->language) {
|
||||
$langs_to_remove[] = $record->language;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally check for LANGUAGE_NONE.
|
||||
else {
|
||||
foreach ($langs as $key => $record) {
|
||||
if ($record->language == LANGUAGE_NONE) {
|
||||
$lang_pos = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isset($lang_pos)) {
|
||||
foreach ($langs as $key => $record) {
|
||||
if ($record->language != LANGUAGE_NONE) {
|
||||
$langs_to_remove[] = $record->language;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Purge the redundant records.
|
||||
if (!empty($langs_to_remove)) {
|
||||
$purge_count += db_delete('metatag')
|
||||
->condition('entity_type', $entity_type)
|
||||
->condition('entity_id', $entity_id)
|
||||
->condition('language', $langs_to_remove)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($purge_count)) {
|
||||
drupal_set_message(t('No duplicate :entity_type records were found (this is a good thing).', array(':entity_type' => $entity_type)));
|
||||
watchdog('metatag', 'No duplicate :entity_type records were found (this is a good thing).', array(':entity_type' => $entity_type));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('Purged :count duplicate :entity_type record(s).', array(':count' => $purge_count, ':entity_type' => $entity_type)));
|
||||
watchdog('metatag', 'Purged :count duplicate :entity_type record(s).', array(':count' => $purge_count, ':entity_type' => $entity_type));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix {metatag} records that may have been corrupted by #1871020.
|
||||
*/
|
||||
function metatag_update_7014() {
|
||||
$records = db_query("SELECT *
|
||||
FROM {metatag} m
|
||||
WHERE
|
||||
m.data LIKE :nolang
|
||||
OR m.data LIKE :lang
|
||||
OR m.data LIKE :und",
|
||||
array(
|
||||
':nolang' => 'a:1:{s:0:"";a:%:{s:%;a:%:{%;}}}',
|
||||
':lang' => 'a:1:{s:2:"__";a:%:{s:%;a:%:{%;}}}',
|
||||
':und' => 'a:1:{s:3:"___";a:%:{s:%;a:%:{%;}}}',
|
||||
));
|
||||
|
||||
// Nothing to fix.
|
||||
if ($records->rowCount() == 0) {
|
||||
drupal_set_message(t('No corrupt records to fix, this is good news :-)'));
|
||||
}
|
||||
|
||||
// Fix the faulty records.
|
||||
else {
|
||||
foreach ($records as $record) {
|
||||
// Extract the data and get the first element of the array, this should be
|
||||
// valid data.
|
||||
$record->data = reset(unserialize($record->data));
|
||||
|
||||
// Update the record.
|
||||
drupal_write_record('metatag', $record, array('entity_type', 'entity_id', 'language'));
|
||||
}
|
||||
drupal_set_message(t('Fixed @count corrupt meta tag record(s).', array('@count' => $records->rowCount())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the revision_id from the entity into metatag schema, adjust the primary
|
||||
* keys accordingly.
|
||||
*/
|
||||
function metatag_update_7015() {
|
||||
// Add the new field.
|
||||
db_add_field('metatag', 'revision_id', array(
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => FALSE,
|
||||
'default' => 0,
|
||||
'description' => 'The revision_id for the entity object this data is attached to.',
|
||||
));
|
||||
|
||||
// Remove the existing primary key. This may take some work so it can be
|
||||
// database agnostic, i.e. some databases will not like it.
|
||||
db_drop_primary_key('metatag');
|
||||
|
||||
// Add the new primary key.
|
||||
db_add_primary_key('metatag', array('entity_type', 'entity_id', 'revision_id', 'language'));
|
||||
|
||||
drupal_set_message(t('Added the {metatag}.revision_id field.'));
|
||||
}
|
242
sites/all/modules/contrib/seo/metatag/metatag.metatag.inc
Normal file
242
sites/all/modules/contrib/seo/metatag/metatag.metatag.inc
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_default().
|
||||
*/
|
||||
function metatag_metatag_config_default() {
|
||||
$configs = array();
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'global';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'title' => array('value' => '[current-page:title] | [site:name]'),
|
||||
'generator' => array('value' => 'Drupal 7 (http://drupal.org)'),
|
||||
'canonical' => array('value' => '[current-page:url:absolute]'),
|
||||
'shortlink' => array('value' => '[current-page:url:unaliased]'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'global:frontpage';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'title' => array('value' => variable_get('site_slogan') ? '[site:name] | [site:slogan]' : '[site:name]'),
|
||||
'canonical' => array('value' => '[site:url]'),
|
||||
'shortlink' => array('value' => '[site:url]'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'node';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'title' => array('value' => '[node:title] | [site:name]'),
|
||||
'description' => array('value' => '[node:summary]'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
if (module_exists('taxonomy')) {
|
||||
$config = new stdClass();
|
||||
$config->instance = 'taxonomy_term';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'title' => array('value' => '[term:name] | [site:name]'),
|
||||
'description' => array('value' => '[term:description]'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
}
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'user';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'title' => array('value' => '[user:name] | [site:name]'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
return $configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_instance_info().
|
||||
*/
|
||||
function metatag_metatag_config_instance_info() {
|
||||
$info['global'] = array('label' => t('Global'));
|
||||
$info['global:frontpage'] = array('label' => t('Front page'));
|
||||
// @todo The 403 and 404 meta tag contexts are disabled until they can be properly implemented.
|
||||
//$info['global:403'] = array('label' => t('403 page not found'));
|
||||
//$info['global:404'] = array('label' => t('404 page not found'));
|
||||
|
||||
// Add instance information for entities.
|
||||
$entity_types = entity_get_info();
|
||||
foreach ($entity_types as $entity_type => $entity_info) {
|
||||
if (metatag_entity_supports_metatags($entity_type)) {
|
||||
$info[$entity_type] = array('label' => $entity_info['label']);
|
||||
foreach ($entity_info['bundles'] as $bundle => $bundle_info) {
|
||||
if (count($entity_info['bundles'] == 1) && $bundle == $entity_type) {
|
||||
// Skip default bundles (entities that do not really have bundles).
|
||||
continue;
|
||||
}
|
||||
if (metatag_entity_supports_metatags($entity_type, $bundle)) {
|
||||
$info[$entity_type . ':' . $bundle] = array('label' => $bundle_info['label']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_info().
|
||||
*/
|
||||
function metatag_metatag_info() {
|
||||
$info['groups']['advanced'] = array(
|
||||
'label' => t('Advanced'),
|
||||
'form' => array(
|
||||
'#weight' => 100,
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['title'] = array(
|
||||
'label' => t('Page title'),
|
||||
'description' => t("The text to display in the title bar of a visitor's web browser when they view this page. This meta tag may also be used as the title of the page when a visitor bookmarks or favorites this page."),
|
||||
'class' => 'DrupalTitleMetaTag',
|
||||
);
|
||||
|
||||
$info['tags']['description'] = array(
|
||||
'label' => t('Description'),
|
||||
'description' => t("A brief and concise summary of the page's content, preferably 150 characters or less. The description meta tag may be used by search engines to display a snippet about the page in search results."),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'form' => array(
|
||||
'#type' => 'textarea',
|
||||
'#rows' => 2,
|
||||
'#wysiwyg' => FALSE,
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['abstract'] = array(
|
||||
'label' => t('Abstract'),
|
||||
'description' => t("A brief and concise summary of the page's content, preferably 150 characters or less. The abstract meta tag may be used by search engines for archiving purposes."),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'form' => array(
|
||||
'#type' => 'textarea',
|
||||
'#rows' => 2,
|
||||
'#wysiwyg' => FALSE,
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['keywords'] = array(
|
||||
'label' => t('Keywords'),
|
||||
'description' => t("A comma-separated list of keywords about the page. This meta tag is <em>not</em> used by most search engines."),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
);
|
||||
|
||||
// More advanced meta tags.
|
||||
$info['tags']['robots'] = array(
|
||||
'label' => t('Robots'),
|
||||
'description' => t("Provides search engines with specific directions for what to do when this page is indexed."),
|
||||
'class' => 'DrupalListMetaTag',
|
||||
'form' => array(
|
||||
'#options' => array(
|
||||
'index' => t('Allow search engines to index this page (assumed).'),
|
||||
'follow' => t('Allow search engines to follow links on this page (assumed).'),
|
||||
'noindex' => t('Prevent search engines from indexing this page.'),
|
||||
'nofollow' => t('Prevent search engines from following links on this page.'),
|
||||
'noarchive' => t('Prevent a cached copy of this page from being available in the search results.'),
|
||||
'nosnippet' => t('Prevents a description from appearing below the page in the search results, as well as prevents caching of the page.'),
|
||||
'noodp' => t('Blocks the <a href="@odp-url">Open Directory Project</a> description of the page from being used in the description that appears below the page in the search results.', array('@odp-url' => 'http://www.dmoz.org/')),
|
||||
'noydir' => t('Prevents Yahoo! from listing this page in the <a href="@ydir">Yahoo! Directory</a>.', array('@ydir' => 'http://dir.yahoo.com/')),
|
||||
),
|
||||
),
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['news_keywords'] = array(
|
||||
'label' => t('Google News Keywords'),
|
||||
'description' => t('A comma-separated list of keywords about the page. This meta tag is used as an indicator in <a href="@google_news">Google News</a>.', array('@google_news' => 'http://support.google.com/news/publisher/bin/answer.py?hl=en&answer=68297')),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['standout'] = array(
|
||||
'label' => t('Google Standout'),
|
||||
'description' => t("Highlight standout journalism on the web, especially for breaking news; used as an indicator in <a href=\"@google_news\">Google News</a>. Warning: Don't abuse it, to be used a maximum of 7 times per calendar week!", array('@google_news' => 'https://support.google.com/news/publisher/answer/191283?hl=en&ref_topic=2484650')),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['generator'] = array(
|
||||
'label' => t('Generator'),
|
||||
'description' => t("Describes the name and version number of the software or publishing tool used to create the page."),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'header' => 'X-Generator',
|
||||
'context' => array('global'),
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['copyright'] = array(
|
||||
'label' => t('Copyright'),
|
||||
'description' => t("Details a copyright, trademark, patent, or other information that pertains to intellectual property about this page. Note that this will not automatically protect your site's content or your intellectual property."),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['image_src'] = array(
|
||||
'label' => t('Image'),
|
||||
'description' => t("An image associated with this page, for use as a thumbnail in social networks and other services."),
|
||||
'class' => 'DrupalLinkMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['canonical'] = array(
|
||||
'label' => t('Canonical URL'),
|
||||
'description' => t("Tells search engines where the preferred location or URL is for this page to help eliminate self-created duplicate content for search engines."),
|
||||
'class' => 'DrupalLinkMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['shortlink'] = array(
|
||||
'label' => t('Shortlink URL'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalLinkMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['publisher'] = array(
|
||||
'label' => t('Publisher URL'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalLinkMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['author'] = array(
|
||||
'label' => t('Author URL'),
|
||||
'description' => t("Used by some search engines to confirm authorship of the content on a page. Should be either the full URL for the author's Google+ profile page or a local page with information about the author."),
|
||||
'class' => 'DrupalLinkMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
$info['tags']['original-source'] = array(
|
||||
'label' => t('Original Source'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'advanced',
|
||||
'description' => t("Used to indicate the URL that broke the story, and can link to either an internal URL or an external source. If the full URL is not known it is acceptable to use a partial URL or just the domain name."),
|
||||
);
|
||||
|
||||
$info['tags']['revisit-after'] = array(
|
||||
'label' => t('Revisit After'),
|
||||
'description' => t('Tell search engines when to index the page again. Very few search engines support this tag, it is more useful to use an <a href="@xmlsitemap">XML Sitemap</a> file.', array('@xmlsitemap' => 'http://drupal.org/project/xmlsitemap')),
|
||||
'class' => 'DrupalDateIntervalMetaTag',
|
||||
'group' => 'advanced',
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
124
sites/all/modules/contrib/seo/metatag/metatag.migrate.inc
Normal file
124
sites/all/modules/contrib/seo/metatag/metatag.migrate.inc
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Metatag support for Migrate.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Basic usage of the Migrate integration.
|
||||
*
|
||||
* This example assumes the custom module's name is "example_migrate".
|
||||
*
|
||||
* example_migrate.inc:
|
||||
*
|
||||
* class MetatagTestMigration extends DynamicMigration {
|
||||
*
|
||||
* public function __construct() {
|
||||
* parent::__construct();
|
||||
*
|
||||
* $this->description = t('Migrate test.');
|
||||
*
|
||||
* $this->map = new MigrateSQLMap(
|
||||
* $this->machineName,
|
||||
* array(
|
||||
* 'id' => array(
|
||||
* 'type' => 'varchar',
|
||||
* 'not null' => TRUE,
|
||||
* 'length' => 254,
|
||||
* 'description' => 'ID of record.',
|
||||
* ),
|
||||
* ),
|
||||
* MigrateDestinationNode::getKeySchema()
|
||||
* );
|
||||
*
|
||||
* $this->source = new MigrateSourceCSV(
|
||||
* drupal_get_path('module', 'example_migrate') . '/sample.csv',
|
||||
* array(),
|
||||
* array('header_rows' => TRUE)
|
||||
* );
|
||||
*
|
||||
* $this->destination = new MigrateDestinationNode('article');
|
||||
*
|
||||
* $this->addFieldMapping('metatag_description', 'description');
|
||||
* $this->addFieldMapping('metatag_keywords', 'keywords');
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* example_migrate.migrate.inc:
|
||||
*
|
||||
* /**
|
||||
* * Implements hook_migrate_api().
|
||||
* * /
|
||||
* function example_migrate_migrate_api() {
|
||||
* $api = array(
|
||||
* 'api' => 2,
|
||||
* 'migrations' => array(
|
||||
* 'MetatagTest' => array('class_name' => 'MetatagTestMigration'),
|
||||
* ),
|
||||
* );
|
||||
*
|
||||
* return $api;
|
||||
* }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_migrate_api().
|
||||
*/
|
||||
function metatag_migrate_api() {
|
||||
$api = array(
|
||||
'api' => 2,
|
||||
'destination handlers' => array(
|
||||
'MigrateMetatagHandler',
|
||||
),
|
||||
);
|
||||
|
||||
return $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metatag destination handler.
|
||||
*/
|
||||
class MigrateMetatagHandler extends MigrateDestinationHandler {
|
||||
|
||||
public function __construct() {
|
||||
$types = array();
|
||||
foreach (entity_get_info() as $entity_type => $entity_info) {
|
||||
if (isset($entity_info['metatags']) && $entity_info['metatags']) {
|
||||
$types[] = $entity_type;
|
||||
}
|
||||
}
|
||||
|
||||
$this->registerTypes($types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MigrateDestinationHandler::fields().
|
||||
*/
|
||||
public function fields() {
|
||||
$fields = array();
|
||||
$elements = metatag_get_info();
|
||||
|
||||
foreach ($elements['tags'] as $value) {
|
||||
$metatag_field = 'metatag_' . $value['name'];
|
||||
$fields[$metatag_field] = $value['description'];
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements MigrateDestinationHandler::prepare().
|
||||
*/
|
||||
public function prepare($entity, stdClass $row) {
|
||||
$elements = metatag_get_info();
|
||||
|
||||
foreach ($elements['tags'] as $value) {
|
||||
$metatag_field = 'metatag_' . $value['name'];
|
||||
if (isset($entity->$metatag_field)) {
|
||||
$entity->metatags[$value['name']]['value'] = $entity->$metatag_field;
|
||||
unset($entity->$metatag_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1872
sites/all/modules/contrib/seo/metatag/metatag.module
Normal file
1872
sites/all/modules/contrib/seo/metatag/metatag.module
Normal file
File diff suppressed because it is too large
Load Diff
96
sites/all/modules/contrib/seo/metatag/metatag.test
Normal file
96
sites/all/modules/contrib/seo/metatag/metatag.test
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
class MetaTagsTestHelper extends DrupalWebTestCase {
|
||||
function setUp(array $modules = array()) {
|
||||
$modules[] = 'ctools';
|
||||
$modules[] = 'token';
|
||||
$modules[] = 'metatag';
|
||||
$modules[] = 'metatag_test';
|
||||
parent::setUp($modules);
|
||||
}
|
||||
}
|
||||
|
||||
class MetaTagsUnitTest extends MetaTagsTestHelper {
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Meta tag unit tests',
|
||||
'description' => 'Test basic meta tag functionality.',
|
||||
'group' => 'Meta tags',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the metatag_config_load_with_defaults() function.
|
||||
*/
|
||||
public function testConfigLoadDefaults() {
|
||||
$defaults = metatag_config_load_with_defaults('test:foo');
|
||||
$this->assertEqual($defaults, array(
|
||||
'description' => array('value' => 'Test foo description'),
|
||||
'abstract' => array('value' => 'Test foo abstract'),
|
||||
'title' => array('value' => 'Test altered title'),
|
||||
'test:foo' => array('value' => 'foobar'),
|
||||
'generator' => array('value' => 'Drupal 7 (http://drupal.org)'),
|
||||
'canonical' => array('value' => '[current-page:url:absolute]'),
|
||||
'shortlink' => array('value' => '[current-page:url:unaliased]'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testEntitySupport() {
|
||||
$test_cases[1] = array('type' => 'node', 'bundle' => 'article', 'expected' => TRUE);
|
||||
$test_cases[2] = array('type' => 'node', 'bundle' => 'page', 'expected' => TRUE);
|
||||
$test_cases[3] = array('type' => 'node', 'bundle' => 'invalid-bundle', 'expected' => FALSE);
|
||||
$test_cases[4] = array('type' => 'user', 'expected' => TRUE);
|
||||
foreach ($test_cases as $test_case) {
|
||||
$test_case += array('bundle' => NULL);
|
||||
$this->assertMetatagEntityHasMetatags($test_case['type'], $test_case['bundle'], $test_case['expected']);
|
||||
}
|
||||
|
||||
variable_set('metatag_test_entity_info_disable', TRUE);
|
||||
drupal_static_reset('metatag_entity_has_metatags');
|
||||
drupal_static_reset('metatag_entity_supports_metatags');
|
||||
entity_info_cache_clear();
|
||||
|
||||
$test_cases[2]['expected'] = FALSE;
|
||||
$test_cases[4]['expected'] = FALSE;
|
||||
foreach ($test_cases as $test_case) {
|
||||
$test_case += array('bundle' => NULL);
|
||||
$this->assertMetatagEntityHasMetatags($test_case['type'], $test_case['bundle'], $test_case['expected']);
|
||||
}
|
||||
}
|
||||
|
||||
function assertMetatagEntityHasMetatags($entity_type, $bundle, $expected) {
|
||||
$entity = entity_create_stub_entity($entity_type, array(0, NULL, $bundle));
|
||||
return $this->assertEqual(
|
||||
metatag_entity_has_metatags($entity_type, $entity),
|
||||
$expected,
|
||||
t("metatag_entity_has_metatags(:type, :entity) is :expected", array(
|
||||
':type' => var_export($entity_type, TRUE),
|
||||
':entity' => var_export($entity, TRUE),
|
||||
':expected' => var_export($expected, TRUE),
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the metatag_config_instance_label() function.
|
||||
*/
|
||||
public function testConfigLabels() {
|
||||
$test_cases = array(
|
||||
'node' => 'Node',
|
||||
'node:article' => 'Node: Article',
|
||||
'node:article:c' => 'Node: Article: Unknown (c)',
|
||||
'node:b' => 'Node: Unknown (b)',
|
||||
'node:b:c' => 'Node: Unknown (b): Unknown (c)',
|
||||
'a' => 'Unknown (a)',
|
||||
'a:b' => 'Unknown (a): Unknown (b)',
|
||||
'a:b:c' => 'Unknown (a): Unknown (b): Unknown (c)',
|
||||
'a:b:c:d' => 'Unknown (a): Unknown (b): Unknown (c): Unknown (d)',
|
||||
);
|
||||
|
||||
foreach ($test_cases as $input => $expected_output) {
|
||||
drupal_static_reset('metatag_config_instance_label');
|
||||
$actual_output = metatag_config_instance_label($input);
|
||||
$this->assertEqual($actual_output, $expected_output);
|
||||
}
|
||||
}
|
||||
}
|
58
sites/all/modules/contrib/seo/metatag/metatag.theme.inc
Normal file
58
sites/all/modules/contrib/seo/metatag/metatag.theme.inc
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Theme callbacks for the metatag module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Theme callback for a normal meta tag.
|
||||
*
|
||||
* The format is:
|
||||
* <meta name="[name]" content="[value]" />
|
||||
*/
|
||||
function theme_metatag($variables) {
|
||||
$element = &$variables['element'];
|
||||
element_set_attributes($element, array('name', '#value' => 'content'));
|
||||
unset($element['#value']);
|
||||
return theme('html_tag', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme callback for a normal meta tag.
|
||||
*
|
||||
* The format is:
|
||||
* <meta http-equiv="[name]" content="[value]" />
|
||||
*/
|
||||
function theme_metatag_http_equiv($variables) {
|
||||
$element = &$variables['element'];
|
||||
element_set_attributes($element, array('#name' => 'http-equiv', '#value' => 'content'));
|
||||
unset($element['#value']);
|
||||
return theme('html_tag', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme callback for a rel link tag.
|
||||
*
|
||||
* The format is:
|
||||
* <link rel="[name]" href="[value]" />
|
||||
*/
|
||||
function theme_metatag_link_rel($variables) {
|
||||
$element = &$variables['element'];
|
||||
element_set_attributes($element, array('#name' => 'rel', '#value' => 'href'));
|
||||
unset($element['#value']);
|
||||
return theme('html_tag', $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme callback for a rev link tag.
|
||||
*
|
||||
* The format is:
|
||||
* <link rev="[name]" href="[value]" />
|
||||
*/
|
||||
function theme_metatag_link_rev($variables) {
|
||||
$element = &$variables['element'];
|
||||
element_set_attributes($element, array('#name' => 'rev', '#value' => 'href'));
|
||||
unset($element['#value']);
|
||||
return theme('html_tag', $variables);
|
||||
}
|
173
sites/all/modules/contrib/seo/metatag/metatag.tokens.inc
Normal file
173
sites/all/modules/contrib/seo/metatag/metatag.tokens.inc
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Custom tokens for Metatag.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_token_info().
|
||||
*/
|
||||
function metatag_token_info() {
|
||||
$info = array();
|
||||
|
||||
$info['types']['metatag'] = array(
|
||||
'name' => t('Meta tags'),
|
||||
'description' => t('Generated by the Metatag module, may not be used to fill in other meta tags.'),
|
||||
);
|
||||
|
||||
$metatag_info = metatag_get_info();
|
||||
|
||||
foreach($metatag_info['tags'] as $value) {
|
||||
$info['tokens']['metatag'][$value['name']] = array(
|
||||
'name' => $value['label'],
|
||||
'description' => $value['description']
|
||||
);
|
||||
}
|
||||
|
||||
if (module_exists('taxonomy')) {
|
||||
$info['tokens']['term']['metatag'] = array(
|
||||
'name' => t('Metatag.'),
|
||||
'description' => t('Metatag.'),
|
||||
'type' => 'metatag'
|
||||
);
|
||||
}
|
||||
|
||||
if (module_exists('node')) {
|
||||
$info['tokens']['node']['metatag'] = array(
|
||||
'name' => t('Metatag.'),
|
||||
'description' => t('Metatag.'),
|
||||
'type' => 'metatag'
|
||||
);
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_tokens().
|
||||
*/
|
||||
function metatag_tokens($type, $tokens, array $data = array(), array $options = array()) {
|
||||
$replacements = array();
|
||||
|
||||
$sanitize = !empty($options['sanitize']);
|
||||
|
||||
// Metatag tokens.
|
||||
if ($type == 'metatag' && !empty($data['metatag'])) {
|
||||
$metatag = $data['metatag'];
|
||||
foreach ($tokens as $name => $original) {
|
||||
if(isset($metatag[$name])){
|
||||
$replacements[$original] = $sanitize ? filter_xss($metatag[$name]) : $metatag[$name];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Token tokens.
|
||||
if ($type == 'term' && !empty($data['term'])) {
|
||||
$term = $data['term'];
|
||||
|
||||
if ($metatag_tokens = token_find_with_prefix($tokens, 'metatag')) {
|
||||
$result = metatag_token_generate_array($term, 'taxonomy_term', $term->vocabulary_machine_name);
|
||||
$replacements += token_generate('metatag', $metatag_tokens, array('metatag' => $result), $options);
|
||||
}
|
||||
}
|
||||
|
||||
// Node tokens.
|
||||
if ($type == 'node' && !empty($data['node'])) {
|
||||
$node = $data['node'];
|
||||
|
||||
if ($metatag_tokens = token_find_with_prefix($tokens, 'metatag')) {
|
||||
$result = metatag_token_generate_array($node, 'node', $node->type);
|
||||
$replacements += token_generate('metatag', $metatag_tokens, array('metatag' => $result), $options);
|
||||
}
|
||||
}
|
||||
|
||||
return $replacements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_tokens_alter().
|
||||
*
|
||||
* Fix [node:summary] until http://drupal.org/node/1295524 is committed, this
|
||||
* code is retrofitted from the patches in that issue.
|
||||
*/
|
||||
function metatag_tokens_alter(array &$replacements, array $context) {
|
||||
// Only proceed if this is working on a node.
|
||||
if ($context['type'] == 'node' && !empty($context['data']['node'])) {
|
||||
// Loop through each of the tokens.
|
||||
foreach ($context['tokens'] as $name => $original) {
|
||||
// Only deal with the 'node:summary' token, that's the one being fixed.
|
||||
if ($name == 'summary') {
|
||||
// A shortcut to the node being processed.
|
||||
$node = $context['data']['node'];
|
||||
|
||||
// Work out the langcode being used.
|
||||
if (isset($context['options']['language'])) {
|
||||
$langcode = $context['options']['language']->language;
|
||||
}
|
||||
else {
|
||||
$langcode = NULL;
|
||||
}
|
||||
|
||||
// Decide whether the string needs to be sanitized.
|
||||
$sanitize = !empty($context['options']['sanitize']);
|
||||
|
||||
if ($items = field_get_items('node', $node, 'body', $langcode)) {
|
||||
$instance = field_info_instance('node', 'body', $node->type);
|
||||
$field_langcode = field_language('node', $node, 'body', $langcode);
|
||||
|
||||
// If the summary is not empty, use it.
|
||||
if (!empty($items[0]['summary'])) {
|
||||
$output = $sanitize ? _text_sanitize($instance, $field_langcode, $items[0], 'summary') : $items[0]['summary'];
|
||||
}
|
||||
|
||||
// Attempt to provide a suitable version of the 'body' field.
|
||||
else {
|
||||
$output = $sanitize ? _text_sanitize($instance, $field_langcode, $items[0], 'value') : $items[0]['value'];
|
||||
// A summary was requested.
|
||||
if ($name == 'summary') {
|
||||
if (isset($instance['display']['teaser']['settings']['trim_length'])) {
|
||||
$trim_length = $instance['display']['teaser']['settings']['trim_length'];
|
||||
}
|
||||
else {
|
||||
// Use default value.
|
||||
$trim_length = NULL;
|
||||
}
|
||||
// Generate an optionally trimmed summary of the body field.
|
||||
$output = text_summary($output, $instance['settings']['text_processing'] ? $items[0]['format'] : NULL, $trim_length);
|
||||
}
|
||||
}
|
||||
|
||||
// Override the original value.
|
||||
$replacements[$original] = $output;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an array of meta tags for a given entity.
|
||||
*/
|
||||
function metatag_token_generate_array($entity, $entity_type, $bundle) {
|
||||
if (metatag_entity_supports_metatags($entity_type, $bundle)) {
|
||||
$token_type = token_get_entity_mapping('entity', $entity_type);
|
||||
|
||||
$instance = "{$entity_type}:{$bundle}";
|
||||
$options = array();
|
||||
$options['token data'][$token_type] = $entity;
|
||||
$options['entity'] = $entity;
|
||||
|
||||
$metatags = isset($entity->metatags) ? $entity->metatags : array();
|
||||
$metatags += metatag_config_load_with_defaults($instance);
|
||||
|
||||
$result = array();
|
||||
foreach ($metatags as $metatag => $data) {
|
||||
if ($metatag_instance = metatag_get_instance($metatag, $data)) {
|
||||
$result[$metatag] = $metatag_instance->getValue($options);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
|
||||
(function ($) {
|
||||
|
||||
Drupal.behaviors.metatagFieldsetSummaries = {
|
||||
attach: function (context) {
|
||||
$('fieldset.metatags-form', context).drupalSetSummary(function (context) {
|
||||
var vals = [];
|
||||
$("input[type='text'], select, textarea", context).each(function() {
|
||||
var default_name = $(this).attr('name').replace(/\[value\]/, '[default]');
|
||||
var default_value = $("input[type='hidden'][name='" + default_name + "']", context);
|
||||
if (default_value.length && default_value.val() == $(this).val()) {
|
||||
// Meta tag has a default value and form value matches default value.
|
||||
return true;
|
||||
}
|
||||
else if (!default_value.length && !$(this).val().length) {
|
||||
// Meta tag has no default value and form value is empty.
|
||||
return true;
|
||||
}
|
||||
var label = $("label[for='" + $(this).attr('id') + "']").text();
|
||||
vals.push(Drupal.t('@label: @value', {
|
||||
'@label': $.trim(label),
|
||||
'@value': Drupal.truncate($(this).val(), 25) || Drupal.t('None')
|
||||
}));
|
||||
});
|
||||
if (vals.length === 0) {
|
||||
return Drupal.t('Using defaults');
|
||||
}
|
||||
else {
|
||||
return vals.join('<br />');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode special characters in a plain-text string for display as HTML.
|
||||
*/
|
||||
Drupal.truncate = function (str, limit) {
|
||||
if (str.length > limit) {
|
||||
return str.substr(0, limit) + '...';
|
||||
}
|
||||
else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
@@ -0,0 +1,31 @@
|
||||
Metatag Context
|
||||
---------------
|
||||
This module is provides a Metatag reaction for Context [1], thus allowing meta
|
||||
tags to be assigned to specific paths and other conditions.
|
||||
|
||||
Configuration can controlled via the normal Context UI module or the new admin
|
||||
page available at: admin/config/search/metatags/context
|
||||
|
||||
Included with the module are default Context configurations that may be enabled
|
||||
from the Context UI admin page and then customized as necessary. The included
|
||||
configurations are:
|
||||
* user_login - for anonymous users accessing the user and user/login pages.
|
||||
* user_register - for anonymous users accessing the user registration page.
|
||||
* forum - for the main forum page from the Forum module. Topic pages are
|
||||
handled as regular nodes, sub-forum pages are handled as regular term pages.
|
||||
* blog - for the main blog page. Note: it does not cover the per-user blog
|
||||
pages too.
|
||||
|
||||
|
||||
Credits
|
||||
------------------------------------------------------------------------------
|
||||
This module is based on the Context Metadata [2] module. The initial
|
||||
development was by Marcin Pajdzik [3] (sponsored by Dennis Publishing [4]).
|
||||
|
||||
|
||||
References
|
||||
------------------------------------------------------------------------------
|
||||
1: http://drupal.org/project/context
|
||||
2: http://drupal.org/project/context_metadata
|
||||
3: http://drupal.org/user/160555
|
||||
4: http://www.dennis.co.uk/
|
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Admin settings page for Metatag Context.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides administration overview page for metatags by path settings.
|
||||
*/
|
||||
function metatag_context_context_overview() {
|
||||
$contexts = context_enabled_contexts(TRUE);
|
||||
$header = array(t('Name'), t('Paths'), t('Operations'));
|
||||
$rows = array();
|
||||
|
||||
$caption = t('Values assigned here inherit from the <a href="@url" title="Edit the global default meta tags.">global defaults</a> and will override any other meta tags assigned elsewhere.', array('@url' => url('admin/config/search/metatags/config/global')));
|
||||
|
||||
foreach ($contexts as $name => $context) {
|
||||
// Only show context items that are specifically selected to be "Shown on
|
||||
// metatag admin page".
|
||||
if (isset($context->reactions['metatag_context_reaction']['metatag_admin']) && $context->reactions['metatag_context_reaction']['metatag_admin']) {
|
||||
$ops = array(
|
||||
l('Edit', 'admin/config/search/metatags/context/' . $context->name, array('query' => array('destination' => 'admin/config/search/metatags/context'))),
|
||||
l('Delete', 'admin/config/search/metatags/context/' . $context->name . '/delete', array('query' => array('destination' => 'admin/config/search/metatags/context'))),
|
||||
);
|
||||
$rows[] = array(
|
||||
$context->name,
|
||||
isset($context->conditions['path']) ? htmlspecialchars(implode(', ', $context->conditions['path']['values'])) : t('No path condition.'),
|
||||
implode(' | ', $ops),
|
||||
);
|
||||
}
|
||||
}
|
||||
return theme('table', array('header' => $header, 'rows' => $rows, 'caption' => $caption));
|
||||
}
|
||||
|
||||
/**
|
||||
* FormAPI callback to build the 'config_add' form.
|
||||
*/
|
||||
function metatag_context_config_add_form($form, &$form_state) {
|
||||
$form['name'] = array(
|
||||
'#title' => 'Name',
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => '',
|
||||
'#description' => 'The unique ID for this metatag path context rule. This must contain only lower case letters, numbers and underscores.',
|
||||
'#required' => 1,
|
||||
'#maxlength' => 255,
|
||||
'#element_validate' => array('metatag_context_edit_name_validate'),
|
||||
);
|
||||
|
||||
$form['actions']['#type'] = 'actions';
|
||||
$form['actions']['save'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Add and configure'),
|
||||
);
|
||||
$form['actions']['cancel'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Cancel'),
|
||||
'#href' => isset($_GET['destination']) ? $_GET['destination'] : 'admin/config/search/metatags/context',
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* FormAPI callback to validate the 'edit_name' field.
|
||||
*/
|
||||
function metatag_context_edit_name_validate($element, &$form_state) {
|
||||
// Check for string identifier sanity.
|
||||
if (!preg_match('!^[a-z0-9_-]+$!', $element['#value'])) {
|
||||
form_error($element, t('The name can only consist of lowercase letters, underscores, dashes, and numbers.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the CTools exportables system is loaded.
|
||||
ctools_include('export');
|
||||
|
||||
// Check for name collision.
|
||||
if ($exists = ctools_export_crud_load('context', $element['#value'])) {
|
||||
form_error($element, t('A context with this name already exists. Please choose another name or delete the existing item before creating a new one.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FormAPI callback to save the 'edit_name' form.
|
||||
*/
|
||||
function metatag_context_config_add_form_submit($form, &$form_state) {
|
||||
$context = metatag_context_load_default_context();
|
||||
$context->name = $form_state['values']['name'];
|
||||
context_save($context);
|
||||
$form_state['redirect'] = 'admin/config/search/metatags/context/' . $context->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* FormAPI callback to build the edit form.
|
||||
*/
|
||||
function metatag_context_config_edit_form($form, &$form_state, $context) {
|
||||
$form_state['metatag_context']['context'] = $context;
|
||||
|
||||
// Empty form to start with.
|
||||
$form = array();
|
||||
// Don't care about the instance name, the data is being managed by Context
|
||||
// and not Metatag.
|
||||
$instance = "";
|
||||
$options = array();
|
||||
|
||||
// Load the METATAG form.
|
||||
metatag_metatags_form($form, $instance, $context->reactions['metatag_context_reaction']['metatags'], $options);
|
||||
|
||||
$form['paths'] = array(
|
||||
'#title' => 'Path',
|
||||
'#description' => t('Set this metatag context when any of the paths above match the page path. Put each path on a separate line. You can use the <code>*</code> character (asterisk) as a wildcard and the <code>~</code> character (tilde) to exclude one or more paths. Use <code><front></code> for the site front page. Only local paths (e.g. "example/page") will work, do not use relative URLs ("/example/page") or absolute URLs ("http://example.com/example/page").'),
|
||||
'#type' => 'textarea',
|
||||
'#default_value' => isset($context->conditions['path']['values']) ? html_entity_decode(implode(' ', $context->conditions['path']['values'])) : '',
|
||||
'#required' => 1,
|
||||
'#weight' => -100,
|
||||
);
|
||||
|
||||
// If other conditions are assigned, mention it.
|
||||
$conditions = array_keys($context->conditions);
|
||||
foreach ($conditions as $key => $condition) {
|
||||
if ($condition == 'path') {
|
||||
unset($conditions[$key]);
|
||||
}
|
||||
}
|
||||
if (!empty($conditions)) {
|
||||
$form['other_conditions'] = array(
|
||||
'#prefix' => '<p><em>',
|
||||
'#markup' => t('Other conditions have been assigned that must be controlled through the main Context settings page.'),
|
||||
'#suffix' => '</em></p>',
|
||||
'#weight' => -99.9,
|
||||
);
|
||||
}
|
||||
|
||||
$form['help'] = array(
|
||||
'#prefix' => '<hr /><p><em>',
|
||||
'#markup' => t('Values assigned here inherit from the <a href="@url" title="Edit the global default meta tags.">global defaults</a> and will override any other meta tags assigned elsewhere.', array('@url' => url('admin/config/search/metatags/config/global'))),
|
||||
'#suffix' => '</em></p>',
|
||||
'#weight' => -99,
|
||||
);
|
||||
|
||||
// Show all tokens.
|
||||
$form['metatags']['tokens']['#token_types'] = 'all';
|
||||
|
||||
$form['metatags']['#type'] = 'container';
|
||||
unset($form['metatags']['#collapsed']);
|
||||
unset($form['metatags']['#collapsible']);
|
||||
|
||||
$form['actions']['#type'] = 'actions';
|
||||
$form['actions']['save'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
);
|
||||
$form['actions']['cancel'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Cancel'),
|
||||
'#href' => isset($_GET['destination']) ? $_GET['destination'] : 'admin/config/search/metatags/context',
|
||||
);
|
||||
$form['#submit'][] = 'metatag_context_config_edit_form_submit';
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* FormAPI callback for the final submission.
|
||||
*/
|
||||
function metatag_context_config_edit_form_submit($form, &$form_state) {
|
||||
$context = $form_state['metatag_context']['context'];
|
||||
$context->reactions['metatag_context_reaction']['metatags'] = $form_state['values']['metatags'];
|
||||
$paths = explode("\n", str_replace("\r", "", $form_state['values']['paths']));
|
||||
$paths = array_combine($paths, $paths);
|
||||
$context->conditions['path']['values'] = $paths;
|
||||
context_save($context);
|
||||
$form_state['redirect'] = 'admin/config/search/metatags/context';
|
||||
}
|
||||
|
||||
/**
|
||||
* FormAPI callback to build the 'delete' form.
|
||||
*/
|
||||
function metatag_context_delete_form($form, &$form_state, $context) {
|
||||
$form_state['metatag_context']['context'] = $context;
|
||||
|
||||
$form['delete'] = array(
|
||||
'#value' => 'This action will permanently remove this item from your database.'
|
||||
);
|
||||
|
||||
$form['actions']['#type'] = 'actions';
|
||||
$form['actions']['save'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Delete'),
|
||||
);
|
||||
$form['actions']['cancel'] = array(
|
||||
'#type' => 'link',
|
||||
'#title' => t('Cancel'),
|
||||
'#href' => isset($_GET['destination']) ? $_GET['destination'] : 'admin/config/search/metatags/context',
|
||||
);
|
||||
$form['#submit'][] = 'metatag_context_delete_form_submit';
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* FormAPI submission callback for the 'delete' form.
|
||||
*/
|
||||
function metatag_context_delete_form_submit($form, &$form_state) {
|
||||
context_delete($form_state['metatag_context']['context']);
|
||||
$form_state['redirect'] = 'admin/config/search/metatags/context';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default Metatag-focused context.
|
||||
*
|
||||
* @return object
|
||||
* A context structure in the form of a StdClass object.
|
||||
*/
|
||||
function metatag_context_load_default_context() {
|
||||
$context = new stdClass();
|
||||
$context->disabled = FALSE; /* Edit this to true to make a default context disabled initially */
|
||||
$context->api_version = 3;
|
||||
$context->name = 'default_metatag_context';
|
||||
$context->description = '';
|
||||
$context->tag = 'Metatag';
|
||||
$context->metatag = TRUE;
|
||||
$context->conditions = array(
|
||||
'path' => array(
|
||||
'values' => array(
|
||||
),
|
||||
),
|
||||
);
|
||||
$context->reactions = array(
|
||||
'metatag_context_reaction' => array(
|
||||
'metatags' => array(),
|
||||
'metatag_admin' => 1,
|
||||
),
|
||||
);
|
||||
$context->condition_mode = 0;
|
||||
$context->weight = 0;
|
||||
|
||||
// Translatables
|
||||
// Included for use with string extractors like potx.
|
||||
t('Metatag');
|
||||
return $context;
|
||||
}
|
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Context reaction for Metatag.
|
||||
*/
|
||||
|
||||
class metatag_context_reaction extends context_reaction {
|
||||
function options_form($context) {
|
||||
$form = array();
|
||||
|
||||
// Don't care about the instance name, the data is being managed by
|
||||
// Context and not Metatag.
|
||||
$instance = "";
|
||||
// Load the previously saved settings.
|
||||
$data = $this->fetch_from_context($context);
|
||||
if (!isset($data['metatags'])) {
|
||||
$data['metatags'] = array();
|
||||
}
|
||||
// No options currently available.
|
||||
$options = array();
|
||||
|
||||
$form['help'] = array(
|
||||
'#prefix' => '<p><em>',
|
||||
'#markup' => t('Values assigned here inherit from the <a href="@url" title="Edit the global default meta tags.">global defaults</a> and will override any other meta tags assigned elsewhere.', array('@url' => url('admin/config/search/metatags/config/global'))),
|
||||
'#suffix' => '</em></p>',
|
||||
);
|
||||
|
||||
$form['basic_header'] = array(
|
||||
'#prefix' => '<hr /><h3>',
|
||||
'#markup' => t('Basic tags'),
|
||||
'#suffix' => '</h3>',
|
||||
);
|
||||
|
||||
// Load the basic Metatag form.
|
||||
metatag_metatags_form($form, $instance, $data['metatags'], $options);
|
||||
|
||||
// Stop the meta tag fields appearing within a fieldset.
|
||||
$form['metatags']['#type'] = 'container';
|
||||
unset($form['metatags']['#collapsed']);
|
||||
unset($form['metatags']['#collapsible']);
|
||||
unset($form['#submit']);
|
||||
|
||||
// Flatten the fieldsets because otherwise the Context module will not save
|
||||
// them properly.
|
||||
// TODO: Perhaps it can be done in a better way with #tree and #parents?
|
||||
foreach (array('advanced', 'dublin-core', 'open-graph') as $fieldset) {
|
||||
if (isset($form['metatags'][$fieldset])) {
|
||||
$form['metatags'][$fieldset . '_heading'] = array(
|
||||
'#prefix' => '<hr /><h3>',
|
||||
'#markup' => $form['metatags'][$fieldset]['#title'],
|
||||
'#suffix' => '</h3>',
|
||||
);
|
||||
if (isset($form['metatags'][$fieldset]['#description'])) {
|
||||
$form['metatags'][$fieldset . '_description'] = array(
|
||||
'#prefix' => '<p>',
|
||||
'#markup' => $form['metatags'][$fieldset]['#description'],
|
||||
'#suffix' => '</p>',
|
||||
);
|
||||
}
|
||||
foreach ($form['metatags'][$fieldset] as $key => $value) {
|
||||
if (substr($key, 0, 1) == '#') {
|
||||
unset ($form['metatags'][$fieldset][$key]);
|
||||
continue;
|
||||
}
|
||||
$form['metatags'][$key] = $value;
|
||||
unset($form['metatags'][$key]['#parents']);
|
||||
unset($form['metatags'][$fieldset][$key]);
|
||||
}
|
||||
unset($form['metatags'][$fieldset]);
|
||||
}
|
||||
}
|
||||
|
||||
// Show all takens.
|
||||
$form['metatags']['tokens']['#token_types'] = 'all';
|
||||
|
||||
$form['metatag_admin'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Show on metatag admin page.'),
|
||||
'#weight' => -98,
|
||||
'#default_value' => isset($data['metatag_admin']) ? $data['metatag_admin'] : '',
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a list of active contexts.
|
||||
*/
|
||||
function execute() {
|
||||
$output = &drupal_static('metatag_context');
|
||||
|
||||
if (!isset($output)) {
|
||||
$metatags = array();
|
||||
$output = array();
|
||||
$contexts = context_active_contexts();
|
||||
$options = array();
|
||||
$instance_names = array();
|
||||
|
||||
foreach ($contexts as $context) {
|
||||
if (!empty($context->reactions['metatag_context_reaction']['metatags'])) {
|
||||
$metadata_array = $context->reactions['metatag_context_reaction']['metatags'];
|
||||
foreach ($metadata_array as $key => $data) {
|
||||
if (!empty($data['value'])) {
|
||||
$metatags[$key] = $data;//t(check_plain($data['value']));
|
||||
}
|
||||
}
|
||||
|
||||
// Add this context to the list of instances.
|
||||
$instance_names[] = $context->name;
|
||||
}
|
||||
}
|
||||
|
||||
// Only proceed if metatags were assigned.
|
||||
if (!empty($metatags)) {
|
||||
// Load the global defaults.
|
||||
$metatags += metatag_config_load_with_defaults('');
|
||||
|
||||
// Compile the identifier for this combination based on the context
|
||||
// names.
|
||||
asort($instance_names);
|
||||
$instance = 'context:' . implode(',', $instance_names);
|
||||
$options['instance'] = $instance;
|
||||
|
||||
foreach ($metatags as $metatag => $data) {
|
||||
if ($metatag_instance = metatag_get_instance($metatag, $data)) {
|
||||
$output[$metatag] = $metatag_instance->getElement($options);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the output meta tags to be modified using
|
||||
// hook_metatag_metatags_view_alter().
|
||||
drupal_alter('metatag_metatags_view', $output, $instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_context_default_contexts().
|
||||
*/
|
||||
function metatag_context_context_default_contexts() {
|
||||
$defaults = array();
|
||||
|
||||
$context = new stdClass();
|
||||
$context->disabled = TRUE; /* Edit this to true to make a default context disabled initially */
|
||||
$context->api_version = 3;
|
||||
$context->name = 'user_login';
|
||||
$context->description = 'A default Metatag:Context definition for the user login page. This needs to be enabled and then it can be customized as needed.';
|
||||
$context->tag = 'Metatag';
|
||||
$context->conditions = array(
|
||||
'path' => array(
|
||||
'values' => array(
|
||||
'user' => 'user',
|
||||
'user/login' => 'user/login',
|
||||
),
|
||||
),
|
||||
'user' => array(
|
||||
'values' => array(
|
||||
'anonymous user' => 'anonymous user',
|
||||
),
|
||||
),
|
||||
);
|
||||
$context->reactions = array(
|
||||
'metatag_context_reaction' => array(
|
||||
'metatags' => array(
|
||||
'title' => array(
|
||||
'value' => '[current-page:title] | [site:name]',
|
||||
'default' => '[current-page:title] | [site:name]',
|
||||
),
|
||||
),
|
||||
'metatag_admin' => 1,
|
||||
),
|
||||
);
|
||||
$context->condition_mode = 1;
|
||||
$defaults[$context->name] = $context;
|
||||
|
||||
$context = new stdClass();
|
||||
$context->disabled = TRUE; /* Edit this to true to make a default context disabled initially */
|
||||
$context->api_version = 3;
|
||||
$context->name = 'user_register';
|
||||
$context->description = 'A default Metatag:Context definition for the user registration page. This needs to be enabled and then it can be customized as needed.';
|
||||
$context->tag = 'Metatag';
|
||||
$context->conditions = array(
|
||||
'path' => array(
|
||||
'values' => array(
|
||||
'user/register' => 'user/register',
|
||||
),
|
||||
),
|
||||
'user' => array(
|
||||
'values' => array(
|
||||
'anonymous user' => 'anonymous user',
|
||||
),
|
||||
),
|
||||
);
|
||||
$context->reactions = array(
|
||||
'metatag_context_reaction' => array(
|
||||
'metatags' => array(
|
||||
'title' => array(
|
||||
'value' => '[current-page:title] | [site:name]',
|
||||
'default' => '[current-page:title] | [site:name]',
|
||||
),
|
||||
),
|
||||
'metatag_admin' => 1,
|
||||
),
|
||||
);
|
||||
$context->condition_mode = 1;
|
||||
$defaults[$context->name] = $context;
|
||||
|
||||
if (module_exists('forum')) {
|
||||
$context = new stdClass();
|
||||
$context->disabled = TRUE; /* Edit this to true to make a default context disabled initially */
|
||||
$context->api_version = 3;
|
||||
$context->name = 'forum';
|
||||
$context->description = 'A default Metatag:Context definition for the main forum page. This needs to be enabled and then it can be customized as needed.';
|
||||
$context->tag = 'Metatag';
|
||||
$context->conditions = array(
|
||||
'path' => array(
|
||||
'values' => array(
|
||||
'forum' => 'forum',
|
||||
),
|
||||
),
|
||||
);
|
||||
$context->reactions = array(
|
||||
'metatag_context_reaction' => array(
|
||||
'metatags' => array(
|
||||
'title' => array(
|
||||
'value' => '[current-page:title] | [site:name]',
|
||||
'default' => '[current-page:title] | [site:name]',
|
||||
),
|
||||
),
|
||||
'metatag_admin' => 1,
|
||||
),
|
||||
);
|
||||
$context->condition_mode = 1;
|
||||
$defaults[$context->name] = $context;
|
||||
}
|
||||
|
||||
if (module_exists('blog')) {
|
||||
$context = new stdClass();
|
||||
$context->disabled = TRUE; /* Edit this to true to make a default context disabled initially */
|
||||
$context->api_version = 3;
|
||||
$context->name = 'blog';
|
||||
$context->description = 'A default Metatag:Context definition for the main blog page. This needs to be enabled and then it can be customized as needed. Note: this does not cover the individual user blog pages, only the main blog page.';
|
||||
$context->tag = 'Metatag';
|
||||
$context->conditions = array(
|
||||
'path' => array(
|
||||
'values' => array(
|
||||
'blog' => 'blog',
|
||||
),
|
||||
),
|
||||
);
|
||||
$context->reactions = array(
|
||||
'metatag_context_reaction' => array(
|
||||
'metatags' => array(
|
||||
'title' => array(
|
||||
'value' => '[current-page:title] | [site:name]',
|
||||
'default' => '[current-page:title] | [site:name]',
|
||||
),
|
||||
),
|
||||
'metatag_admin' => 1,
|
||||
),
|
||||
);
|
||||
$context->condition_mode = 1;
|
||||
$defaults[$context->name] = $context;
|
||||
}
|
||||
|
||||
// Translatables
|
||||
// Included for use with string extractors like potx.
|
||||
t('Metatag');
|
||||
|
||||
return $defaults;
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
name = Metatag: Context
|
||||
description = "Assigned Metatag using Context definitions, allowing them to be assigned by path and other criteria."
|
||||
package = SEO
|
||||
core = 7.x
|
||||
dependencies[] = context
|
||||
dependencies[] = metatag
|
||||
files[] = metatag_context.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Installation and update hooks for Metatag:Context.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_enable().
|
||||
*/
|
||||
function metatag_context_enable() {
|
||||
// Clear the cache so Context and CTools know about this plugin.
|
||||
cache_clear_all('plugins:context:plugins', 'cache');
|
||||
}
|
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Primary hook implementations for Metatag Context.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function metatag_context_menu() {
|
||||
$items['admin/config/search/metatags/context'] = array(
|
||||
'title' => 'By path',
|
||||
'page callback' => 'metatag_context_context_overview',
|
||||
'access arguments' => array('administer meta tags'),
|
||||
'file' => 'metatag_context.admin.inc',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
$items['admin/config/search/metatags/context/add'] = array(
|
||||
'title' => 'Add a meta tag by path',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('metatag_context_config_add_form'),
|
||||
'access arguments' => array('administer meta tags'),
|
||||
'file' => 'metatag_context.admin.inc',
|
||||
'type' => MENU_LOCAL_ACTION,
|
||||
);
|
||||
$items['admin/config/search/metatags/context/%context'] = array(
|
||||
'title' => 'Configure metatags by path',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('metatag_context_config_edit_form', 5),
|
||||
'access arguments' => array('administer meta tags'),
|
||||
'file' => 'metatag_context.admin.inc',
|
||||
);
|
||||
$items['admin/config/search/metatags/context/%context/delete'] = array(
|
||||
'title' => 'Delete metatags by path',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('metatag_context_delete_form', 5),
|
||||
'access arguments' => array('administer meta tags'),
|
||||
'file' => 'metatag_context.admin.inc',
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_context_plugins().
|
||||
*/
|
||||
function metatag_context_context_plugins() {
|
||||
return array(
|
||||
'metatag_context_reaction' => array(
|
||||
'handler' => array(
|
||||
'path' => drupal_get_path('module', 'metatag_context'),
|
||||
'file' => 'metatag_context.context.inc',
|
||||
'class' => 'metatag_context_reaction',
|
||||
'parent' => 'context_reaction',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_context_registry().
|
||||
*/
|
||||
function metatag_context_context_registry() {
|
||||
return array(
|
||||
'reactions' => array(
|
||||
'metatag_context_reaction' => array(
|
||||
'title' => t('Meta Data'),
|
||||
'description' => t('Control page meta tags using the Metatag module.'),
|
||||
'plugin' => 'metatag_context_reaction',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_context_page_reaction().
|
||||
*/
|
||||
function metatag_context_context_page_reaction() {
|
||||
if ($plugin = context_get_plugin('reaction', 'metatag_context_reaction')) {
|
||||
$plugin->execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_page_build().
|
||||
*/
|
||||
function metatag_context_page_build(&$page) {
|
||||
// Load the meta tags that have been generated for this page.
|
||||
$metatags = drupal_static('metatag_context', array());
|
||||
|
||||
if (!empty($metatags)) {
|
||||
$page['content']['metatags']['global'] = $metatags;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_preprocess_html().
|
||||
*/
|
||||
function metatag_context_preprocess_html(&$variables) {
|
||||
$metadata = drupal_static('metatag_context');
|
||||
|
||||
if (isset($metadata['metadata_title'])) {
|
||||
$variables['head_title'] = token_replace($metadata['metadata_title']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_ctools_plugin_api().
|
||||
*/
|
||||
function metatag_context_ctools_plugin_api() {
|
||||
list($module, $api) = func_get_args();
|
||||
if ($module == "context" && $api == "context") {
|
||||
return array("version" => "3");
|
||||
}
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Functional tests for the Metatag:Context module.
|
||||
*/
|
||||
|
||||
class MetatagContextTestCase extends DrupalWebTestCase {
|
||||
/**
|
||||
* The getInfo() method provides information about the test.
|
||||
* In order for the test to be run, the getInfo() method needs
|
||||
* to be implemented.
|
||||
*/
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'Meta tag context tests',
|
||||
'description' => 'Test basic meta tag context functionality.',
|
||||
'group' => 'Meta tags',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the testing environment
|
||||
*/
|
||||
public function setUp(array $modules = array()) {
|
||||
$modules[] = 'metatag';
|
||||
$modules[] = 'metatag_context';
|
||||
parent::setUp($modules);
|
||||
// Create user.
|
||||
$this->privileged_user = $this->drupalCreateUser(array(
|
||||
'bypass node access',
|
||||
'administer content types',
|
||||
'administer meta tags',
|
||||
));
|
||||
$this->drupalLogin($this->privileged_user);
|
||||
// Create content type, with underscores.
|
||||
$type_name = strtolower($this->randomName(8)) . '_test';
|
||||
$type = $this->drupalCreateContentType(array('name' => $type_name, 'type' => $type_name));
|
||||
$this->type = $type->type;
|
||||
// Store a valid URL name, with hyphens instead of underscores.
|
||||
$this->hyphen_type = str_replace('_', '-', $this->type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the basic tests.
|
||||
*/
|
||||
public function testMetatagContextBasic() {
|
||||
// Create content type node.
|
||||
$this->drupalPost('node/add/' . $this->hyphen_type, array('title' => $this->randomName(8)), t('Save'));
|
||||
$this->context_name = drupal_strtolower($this->randomName(8));
|
||||
|
||||
// Generate metatags and check content.
|
||||
$this->metatag_pages['node'] = $this->createMetatagObject('node/1', 'node_metatags');
|
||||
$this->metatag_pages['page'] = $this->createMetatagObject('<front>', 'frontpage_metatags');
|
||||
foreach ($this->metatag_pages as $page) {
|
||||
$this->generateMetatag($page);
|
||||
$this->checkMetatags($page);
|
||||
}
|
||||
|
||||
// Edit metatag and check content.
|
||||
$this->metatag_pages['node']->title = 'New title';
|
||||
$this->metatag_pages['node']->description = '';
|
||||
$this->editMetatag($this->metatag_pages['node']);
|
||||
$this->checkMetatags($this->metatag_pages['node']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a metatag object which can be used for generate and check
|
||||
* the metatag_context module behavior.
|
||||
*
|
||||
* @param $path
|
||||
* Path where generate metatags.
|
||||
* @param $identifier
|
||||
* Custom test to identify metatags in source code.
|
||||
*
|
||||
* @return $metatag_object
|
||||
* Metatag mapping object.
|
||||
*/
|
||||
function createMetatagObject($path, $identifier) {
|
||||
$metatag_object = new stdClass();
|
||||
$metatag_object->name = drupal_strtolower($this->randomName(10));
|
||||
$metatag_object->path = $path;
|
||||
$metatag_object->title = "My $identifier title";
|
||||
$metatag_object->description = "My $identifier description";
|
||||
$metatag_object->abstract = "My $identifier abstract";
|
||||
$metatag_object->keywords = "My $identifier keywords";
|
||||
|
||||
return $metatag_object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates metatags by path from a metatag_object instance.
|
||||
*
|
||||
* @return $metatag_object
|
||||
* Metatag mapping object.
|
||||
*/
|
||||
function generateMetatag($metatag_object) {
|
||||
//Add new Metatag object by path.
|
||||
$edit = array(
|
||||
'name' => $metatag_object->name,
|
||||
);
|
||||
$this->drupalPost('admin/config/search/metatags/context/add', $edit, t('Add and configure'));
|
||||
$this->editMetatag($metatag_object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits metatags by path from a metatag_object instance.
|
||||
*
|
||||
* @return $metatag_object
|
||||
* Metatag mapping object.
|
||||
*/
|
||||
function editMetatag($metatag_object) {
|
||||
$edit_metatag = array(
|
||||
'paths' => $metatag_object->path,
|
||||
'metatags[title][value]' => $metatag_object->title,
|
||||
'metatags[description][value]' => $metatag_object->description,
|
||||
'metatags[abstract][value]' => $metatag_object->abstract,
|
||||
'metatags[keywords][value]' => $metatag_object->keywords,
|
||||
);
|
||||
$this->drupalPost('admin/config/search/metatags/context/' . $metatag_object->name, $edit_metatag, t('Save'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if metatags has been added correctly from a metatag_object instance.
|
||||
*
|
||||
* @return $metatag_object
|
||||
* Metatag mapping object.
|
||||
*/
|
||||
function checkMetatags($metatag_object) {
|
||||
$options = array('description', 'abstract', 'keywords');
|
||||
$this->drupalGet($metatag_object->path);
|
||||
|
||||
foreach ($options as $option) {
|
||||
if (!empty($metatag_object->{$option})) {
|
||||
$this->assertRaw($metatag_object->{$option}, $option . ' found in ' . $metatag_object->path);
|
||||
}
|
||||
else {
|
||||
$this->assertNoRaw('<meta name="' . $option, $option . ' not found in ' . $metatag_object->path);
|
||||
}
|
||||
}
|
||||
if (!empty($metatag_object->title)) {
|
||||
$this->assertRaw($metatag_object->title, 'Title found in ' . $metatag_object->path);
|
||||
}
|
||||
}
|
||||
}
|
36
sites/all/modules/contrib/seo/metatag/metatag_dc/README.txt
Normal file
36
sites/all/modules/contrib/seo/metatag/metatag_dc/README.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
Metatag: Dublin Core
|
||||
--------------------
|
||||
This module adds the fifteen Dublin Core Metadata Element Set [1] to the
|
||||
available meta tags, as defined by the Dublin Core Metadata Institute [2].
|
||||
|
||||
The following tags are provided:
|
||||
* dcterms.contributor
|
||||
* dcterms.coverage
|
||||
* dcterms.creator
|
||||
* dcterms.date
|
||||
* dcterms.description
|
||||
* dcterms.format
|
||||
* dcterms.identifier
|
||||
* dcterms.language
|
||||
* dcterms.publisher
|
||||
* dcterms.relation
|
||||
* dcterms.rights
|
||||
* dcterms.source
|
||||
* dcterms.subject
|
||||
* dcterms.title
|
||||
* dcterms.type
|
||||
|
||||
|
||||
Credits
|
||||
------------------------------------------------------------------------------
|
||||
The initial development was by Marty2081 [3] (sponsored by Gemeentemuseum Den
|
||||
Haag. [4]), with contributions by many in the community [5].
|
||||
|
||||
|
||||
References
|
||||
------------------------------------------------------------------------------
|
||||
1: http://dublincore.org/documents/dces/
|
||||
2: http://www.dublincore.org/
|
||||
3: http://drupal.org/user/960720
|
||||
4: http://www.gemeentemuseum.nl/
|
||||
5: http://drupal.org/node/1491616
|
@@ -0,0 +1,12 @@
|
||||
name = Metatag: Dublin Core
|
||||
description = Provides the fifteen <a href="http://dublincore.org/documents/dces/">Dublin Core Metadata Element Set 1.1</a> meta tags from the <a href="http://dublincore.org/">Dublin Core Metadata Institute</a>.
|
||||
package = SEO
|
||||
core = 7.x
|
||||
dependencies[] = metatag
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Metatag integration for the metatag_dc module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_default_alter().
|
||||
*/
|
||||
function metatag_dc_metatag_config_default_alter(array &$configs) {
|
||||
foreach ($configs as &$config) {
|
||||
switch ($config->instance) {
|
||||
case 'global':
|
||||
$config->config += array(
|
||||
'dcterms.title' => array('value' => '[current-page:title]'),
|
||||
'dcterms.type' => array('value' => 'Text'),
|
||||
'dcterms.format' => array('value' => 'text/html'),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'global:frontpage':
|
||||
$config->config += array(
|
||||
'dcterms.title' => array('value' => '[site:name]'),
|
||||
'dcterms.identifier' => array('value' => '[site:url]'),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'node':
|
||||
$config->config += array(
|
||||
'dcterms.title' => array('value' => '[node:title]'),
|
||||
'dcterms.date' => array('value' => '[node:created:custom:Y-m-d\TH:iP]'),
|
||||
'dcterms.identifier' => array('value' => '[current-page:url:absolute]'),
|
||||
'dcterms.language' => array('value' => '[node:language]'),
|
||||
'dcterms.creator' => array('value' => '[node:author]'),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'taxonomy_term':
|
||||
$config->config += array(
|
||||
'dcterms.title' => array('value' => '[term:name]'),
|
||||
'dcterms.identifier' => array('value' => '[current-page:url:absolute]'),
|
||||
'dcterms.description' => array('value' => '[term:description]'),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'user':
|
||||
$config->config += array(
|
||||
'dcterms.title' => array('value' => '[user:name]'),
|
||||
'dcterms.date' => array('value' => '[user:created:custom:Y-m-d\TH:iP]'),
|
||||
'dcterms.identifier' => array('value' => '[current-page:url:absolute]'),
|
||||
'dcterms.creator' => array('value' => '[user:name]'),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_info().
|
||||
* Dublin Core Elements taken from http://purl.org/dc/elements/1.1/.
|
||||
*/
|
||||
function metatag_dc_metatag_info() {
|
||||
$info['groups']['dublin-core'] = array(
|
||||
'label' => t('Dublin Core'),
|
||||
'description' => t('The Dublin Core Metadata Element Set, aka "Dublin Core meta tags", are a set of internationally standardized metadata tags used to describe content to make identification and classification of content easier; the standards are controlled by the <a href="http://dublincore.org/">Dublin Core Metadata Initiative (DCMI)</a>.'),
|
||||
'form' => array(
|
||||
'#weight' => 70,
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.title'] = array(
|
||||
'label' => t('Dublin Core Title'),
|
||||
'description' => t('The name given to the resource.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'dublin-core',
|
||||
'element' => array(
|
||||
'#type' => 'term',
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.creator'] = array(
|
||||
'label' => t('Dublin Core Creator'),
|
||||
'description' => t('An entity primarily responsible for making the resource. Examples of a Creator include a person, an organization, or a service. Typically, the name of a Creator should be used to indicate the entity.'),
|
||||
'group' => 'dublin-core',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.subject'] = array(
|
||||
'label' => t('Dublin Core Subject'),
|
||||
'description' => t('The topic of the resource. Typically, the subject will be represented using keywords, key phrases, or classification codes. Recommended best practice is to use a controlled vocabulary. To describe the spatial or temporal topic of the resource, use the Coverage element.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'dublin-core',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.description'] = array(
|
||||
'label' => t('Dublin Core Description'),
|
||||
'description' => t('An account of the resource. Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource.'),
|
||||
'group' => 'dublin-core',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.publisher'] = array(
|
||||
'label' => t('Dublin Core Publisher'),
|
||||
'description' => t('An entity responsible for making the resource available. Examples of a Publisher include a person, an organization, or a service. Typically, the name of a Publisher should be used to indicate the entity.'),
|
||||
'group' => 'dublin-core',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.contributor'] = array(
|
||||
'label' => t('Dublin Core Contributor'),
|
||||
'description' => t('An entity responsible for making contributions to the resource. Examples of a Contributor include a person, an organization, or a service. Typically, the name of a Contributor should be used to indicate the entity.'),
|
||||
'group' => 'dublin-core',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.date'] = array(
|
||||
'label' => t('Dublin Core Date'),
|
||||
'description' => t('A point or period of time associated with an event in the lifecycle of the resource. Date may be used to express temporal information at any level of granularity. Recommended best practice is to use an encoding scheme, such as the W3CDTF profile of ISO 8601 [W3CDTF].'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'dublin-core',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.type'] = array(
|
||||
'label' => t('Dublin Core Type'),
|
||||
'description' => t('The nature or genre of the resource. Recommended best practice is to use a controlled vocabulary such as the DCMI Type Vocabulary [DCMITYPE]. To describe the file format, physical medium, or dimensions of the resource, use the Format element.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'dublin-core',
|
||||
'form' => array(
|
||||
'#type' => 'select',
|
||||
'#options' => _metatag_dc_dcmi_type_vocabulary_options(),
|
||||
'#empty_option' => t('- None -'),
|
||||
),
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.format'] = array(
|
||||
'label' => t('Dublin Core Format'),
|
||||
'description' => t('The file format, physical medium, or dimensions of the resource. Examples of dimensions include size and duration. Recommended best practice is to use a controlled vocabulary such as the list of Internet Media Types [MIME].'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'dublin-core',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.identifier'] = array(
|
||||
'label' => t('Dublin Core Identifier'),
|
||||
'description' => t('An unambiguous reference to the resource within a given context. Recommended best practice is to identify the resource by means of a string conforming to a formal identification system.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'dublin-core',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.source'] = array(
|
||||
'label' => t('Dublin Core Source'),
|
||||
'description' => t('A related resource from which the described resource is derived. The described resource may be derived from the related resource in whole or in part. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system.'),
|
||||
'group' => 'dublin-core',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.language'] = array(
|
||||
'label' => t('Dublin Core Language'),
|
||||
'description' => t('A language of the resource. Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646].'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'dublin-core',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.relation'] = array(
|
||||
'label' => t('Dublin Core Relation'),
|
||||
'description' => t('A related resource. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system.'),
|
||||
'group' => 'dublin-core',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.coverage'] = array(
|
||||
'label' => t('Dublin Core Coverage'),
|
||||
'description' => t('The spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant. Spatial topic and spatial applicability may be a named place or a location specified by its geographic coordinates. Temporal topic may be a named period, date, or date range. A jurisdiction may be a named administrative entity or a geographic place to which the resource applies. Recommended best practice is to use a controlled vocabulary such as the Thesaurus of Geographic Names [TGN]. Where appropriate, named places or time periods can be used in preference to numeric identifiers such as sets of coordinates or date ranges.'),
|
||||
'group' => 'dublin-core',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
$info['tags']['dcterms.rights'] = array(
|
||||
'label' => t('Dublin Core Rights'),
|
||||
'description' => t('Information about rights held in and over the resource. Typically, rights information includes a statement about various property rights associated with the resource, including intellectual property rights.'),
|
||||
'group' => 'dublin-core',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_dc',
|
||||
),
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that returns the DCMI type options.
|
||||
* Types taken from http://dublincore.org/documents/dcmi-type-vocabulary/.
|
||||
*/
|
||||
function _metatag_dc_dcmi_type_vocabulary_options() {
|
||||
$options = array(
|
||||
'Collection',
|
||||
'Dataset',
|
||||
'Event',
|
||||
'Image',
|
||||
'InteractiveResource',
|
||||
'MovingImage',
|
||||
'PhysicalObject',
|
||||
'Service',
|
||||
'Software',
|
||||
'Sound',
|
||||
'StillImage',
|
||||
'Text',
|
||||
);
|
||||
return drupal_map_assoc($options);
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Metatag integration for the metatag_dc module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_ctools_plugin_api().
|
||||
*/
|
||||
function metatag_dc_ctools_plugin_api($owner, $api) {
|
||||
if ($owner == 'metatag' && $api == 'metatag') {
|
||||
return array('version' => 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function metatag_dc_theme() {
|
||||
$info['metatag_dc'] = array(
|
||||
'render element' => 'element',
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme callback for a Dublin Core meta tag.
|
||||
*/
|
||||
function theme_metatag_dc($variables) {
|
||||
$element = &$variables['element'];
|
||||
element_set_attributes($element, array(
|
||||
'#name' => 'name',
|
||||
'#schema' => 'schema',
|
||||
'#value' => 'content')
|
||||
);
|
||||
unset($element['#value']);
|
||||
return theme('html_tag', $variables);
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
name = Metatag: Open Graph
|
||||
description = Provides support for open graph meta tags.
|
||||
package = SEO
|
||||
core = 7.x
|
||||
dependencies[] = metatag
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Installation and update scripts for Metatag:OpenGraph.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function metatag_opengraph_requirements($phase) {
|
||||
$requirements = array();
|
||||
// Ensure translations don't break during installation.
|
||||
$t = get_t();
|
||||
|
||||
if ($phase == 'runtime') {
|
||||
if (module_exists('rdf')) {
|
||||
$requirements['metatag_og_rdf'] = array(
|
||||
'severity' => REQUIREMENT_WARNING,
|
||||
'title' => 'Metatag:OpenGraph',
|
||||
'value' => $t('Possible conflict with the RDF module'),
|
||||
'description' => $t("The core RDF module is known to cause validation problems for Open Graph meta tags. Unless it is actually needed for the site, it may be worthwhile to disable the RDF module to avoid any possible problems for the Open Graph integration."),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function metatag_opengraph_install() {
|
||||
// Display a warning about possible conflicts with the RDF module.
|
||||
if (module_exists('rdf')) {
|
||||
drupal_set_message(t('The core RDF module is known to cause validation problems for Open Graph meta tags. Unless it is actually needed for the site, it may be worthwhile to disable the RDF module to avoid any possible problems for the Open Graph integration.'));
|
||||
}
|
||||
}
|
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Metatag integration for the metatag_opengraph module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_default_alter().
|
||||
*/
|
||||
function metatag_opengraph_metatag_config_default_alter(array &$configs) {
|
||||
foreach ($configs as &$config) {
|
||||
switch ($config->instance) {
|
||||
case 'global':
|
||||
$config->config += array(
|
||||
'og:type' => array('value' => 'article'),
|
||||
'og:title' => array('value' => '[current-page:title]'),
|
||||
'og:site_name' => array('value' => '[site:name]'),
|
||||
'og:url' => array('value' => '[current-page:url:absolute]'),
|
||||
);
|
||||
break;
|
||||
case 'global:frontpage':
|
||||
$config->config += array(
|
||||
'og:type' => array('value' => 'website'),
|
||||
'og:title' => array('value' => '[site:name]'),
|
||||
'og:url' => array('value' => '[site:url]'),
|
||||
);
|
||||
break;
|
||||
case 'node':
|
||||
$config->config += array(
|
||||
'og:title' => array('value' => '[node:title]'),
|
||||
'og:description' => array('value' => '[node:summary]'),
|
||||
);
|
||||
break;
|
||||
case 'taxonomy_term':
|
||||
$config->config += array(
|
||||
'og:title' => array('value' => '[term:name]'),
|
||||
'og:description' => array('value' => '[term:description]'),
|
||||
);
|
||||
break;
|
||||
case 'user':
|
||||
$config->config += array(
|
||||
'og:type' => array('value' => 'profile'),
|
||||
'og:title' => array('value' => '[user:name]'),
|
||||
);
|
||||
if (variable_get('user_pictures')) {
|
||||
$config->config += array(
|
||||
'og:image' => array('value' => '[user:picture:url]'),
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_info().
|
||||
*/
|
||||
function metatag_opengraph_metatag_info() {
|
||||
$info['groups']['open-graph'] = array(
|
||||
'label' => t('Open Graph'),
|
||||
'form' => array(
|
||||
'#weight' => 50,
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['fb:admins'] = array(
|
||||
'label' => t('Facebook Admins'),
|
||||
'description' => t('A comma-separated list of Facebook user IDs of people who are considered administrators or moderators of this page. Most sites will only need to assign this on the global settings page.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['fb:app_id'] = array(
|
||||
'label' => t('Facebook Application ID'),
|
||||
'description' => t('A comma-separated list of Facebook Platform Application IDs applicable for this site. Most sites will only need to assign this on the global settings page.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
if (module_exists('fb_social')) {
|
||||
$info['tags']['fb:app_id']['form']['#disabled'] = TRUE;
|
||||
$info['tags']['fb:app_id']['form']['#description'] = t('The FB_Social module will automatically output this meta tag, go to the <a href="!fb_social">FB_Social settings page</a> to customize it.', array('!fb_social' => url('admin/config/user-interface/fb_social')));
|
||||
}
|
||||
|
||||
$info['tags']['og:site_name'] = array(
|
||||
'label' => t('Open Graph site name'),
|
||||
'description' => t('A human-readable name for your site, e.g., <em>IMDb</em>.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'context' => array('global'),
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['og:title'] = array(
|
||||
'label' => t('Open Graph title'),
|
||||
'description' => t('The title of your object as it should appear within the graph, e.g., <em>The Rock</em>.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['og:description'] = array(
|
||||
'label' => t('Open Graph description'),
|
||||
'description' => t('A one to two sentence description of your page.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['og:type'] = array(
|
||||
'label' => t('Open Graph type'),
|
||||
'description' => t('The type of your object, e.g., <em>movie</em>.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
'form' => array(
|
||||
'#type' => 'select',
|
||||
'#options' => _metatag_opengraph_type_options(),
|
||||
'#empty_option' => t('- None -'),
|
||||
),
|
||||
);
|
||||
|
||||
if (module_exists('select_or_other')) {
|
||||
// Enhance the og:type field to support custom types.
|
||||
$info['tags']['og:type']['form']['#type'] = 'select_or_other';
|
||||
$info['tags']['og:type']['form']['#other'] = t('Other (please type a value)');
|
||||
$info['tags']['og:type']['form']['#other_unknown_defaults'] = 'other';
|
||||
$info['tags']['og:type']['form']['#theme'] = 'select_or_other';
|
||||
$info['tags']['og:type']['form']['#element_validate'] = array('select_or_other_element_validate');
|
||||
}
|
||||
|
||||
$info['tags']['og:image'] = array(
|
||||
'label' => t('Open Graph image'),
|
||||
'description' => t('An image URL which should represent your object within the graph. The image must be at least 50px by 50px and have a maximum aspect ratio of 3:1. We support PNG, JPEG and GIF formats.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['og:url'] = array(
|
||||
'label' => t('Open Graph URL'),
|
||||
'description' => t('The canonical URL of your object that will be used as its permanent ID in the graph, e.g., <em>http://www.imdb.com/title/tt0117500/</em>.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['og:latitude'] = array(
|
||||
'label' => t('Open Graph Latitude'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:longitude'] = array(
|
||||
'label' => t('Open Graph Longitude'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['og:street-address'] = array(
|
||||
'label' => t('Open Graph Street Address'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:locality'] = array(
|
||||
'label' => t('Open Graph Locality'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:region'] = array(
|
||||
'label' => t('Open Graph Region'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:postal-code'] = array(
|
||||
'label' => t('Open Graph Postal Code'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:country-name'] = array(
|
||||
'label' => t('Open Graph Country Name'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['og:email'] = array(
|
||||
'label' => t('Open Graph Email'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:phone_number'] = array(
|
||||
'label' => t('Open Graph Phone Number'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:fax_number'] = array(
|
||||
'label' => t('Open Graph Fax Number'),
|
||||
'description' => '',
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['og:video'] = array(
|
||||
'label' => t('Open Graph Video (URL)'),
|
||||
'description' => t('A URL to a video file that complements this object.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:video:secure_url'] = array(
|
||||
'label' => t('Open Graph Video Secure'),
|
||||
'description' => t('A URL to a video file that complements this object using the HTTPS protocol.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:video:width'] = array(
|
||||
'label' => t('Open Graph Video Width'),
|
||||
'description' => t('The width of the video.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:video:height'] = array(
|
||||
'label' => t('Open Graph Video Height'),
|
||||
'description' => t('The height of the video.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
);
|
||||
$info['tags']['og:video:type'] = array(
|
||||
'label' => t('Open Graph Video Type'),
|
||||
'description' => t('The type of the video file.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'open-graph',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_opengraph',
|
||||
),
|
||||
'form' => array(
|
||||
'#type' => 'select',
|
||||
'#options' => array(
|
||||
'application/x-shockwave-flash' => 'Flash - playable directly from the feed',
|
||||
'text/html' => 'Separate HTML page',
|
||||
),
|
||||
'#empty_option' => t('- None -'),
|
||||
),
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
function _metatag_opengraph_type_options() {
|
||||
$options = array(
|
||||
t('Activities') => array(
|
||||
'activity' => t('Activity'),
|
||||
'sport' => t('Sport'),
|
||||
),
|
||||
t('Businesses') => array(
|
||||
'bar' => t('Bar'),
|
||||
'company' => t('Company'),
|
||||
'cafe' => t('Cafe'),
|
||||
'hotel' => t('Hotel'),
|
||||
'restaurant' => t('Restaurant'),
|
||||
),
|
||||
t('Groups') => array(
|
||||
'cause' => t('Cause'),
|
||||
'sports_league' => t('Sports league'),
|
||||
'sports_team' => t('Sports team'),
|
||||
),
|
||||
t('Organizations') => array(
|
||||
'band' => t('Band'),
|
||||
'government' => t('Government'),
|
||||
'non_profit' => t('Non-profit'),
|
||||
'school' => t('School'),
|
||||
'university' => t('University'),
|
||||
),
|
||||
t('People') => array(
|
||||
'actor' => t('Actor'),
|
||||
'athlete' => t('Athlete'),
|
||||
'author' => t('Author'),
|
||||
'director' => t('Director'),
|
||||
'musician' => t('Musician'),
|
||||
'politician' => t('Politician'),
|
||||
'profile' => t('Profile'),
|
||||
'public_figure' => t('Public figure'),
|
||||
),
|
||||
t('Places') => array(
|
||||
'city' => t('City'),
|
||||
'country' => t('Country'),
|
||||
'landmark' => t('Landmark'),
|
||||
'state_province' => t('State or province'),
|
||||
),
|
||||
t('Products and Entertainment') => array(
|
||||
'album' => t('Album'),
|
||||
'book' => t('Book'),
|
||||
'drink' => t('Drink'),
|
||||
'food' => t('Food'),
|
||||
'game' => t('Game'),
|
||||
'movie' => t('Movie'),
|
||||
'product' => t('Product'),
|
||||
'song' => t('Song'),
|
||||
'tv_show' => t('TV show'),
|
||||
),
|
||||
t('Websites') => array(
|
||||
'blog' => t('Blog'),
|
||||
'website' => t('Website'),
|
||||
'article' => t('Article'),
|
||||
),
|
||||
);
|
||||
|
||||
return $options;
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_preprocess_html().
|
||||
*/
|
||||
function metatag_opengraph_preprocess_html(&$variables) {
|
||||
// The RDF module adds the Open Graph namespace itself.
|
||||
// @see rdf_rdf_namespaces()
|
||||
if (!module_exists('rdf')) {
|
||||
$variables['rdf_namespaces'] .= "\n xmlns:og=\"http://ogp.me/ns#\"";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_ctools_plugin_api().
|
||||
*/
|
||||
function metatag_opengraph_ctools_plugin_api($owner, $api) {
|
||||
if ($owner == 'metatag' && $api == 'metatag') {
|
||||
return array('version' => 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function metatag_opengraph_theme() {
|
||||
$info['metatag_opengraph'] = array(
|
||||
'render element' => 'element',
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme callback for an OpenGraph meta tag.
|
||||
*/
|
||||
function theme_metatag_opengraph($variables) {
|
||||
$element = &$variables['element'];
|
||||
element_set_attributes($element, array('#name' => 'property', '#value' => 'content'));
|
||||
unset($element['#value']);
|
||||
return theme('html_tag', $variables);
|
||||
}
|
||||
|
||||
/*
|
||||
og:title = [node:title] / [user:name]
|
||||
og:type = article / profile
|
||||
og:image = ? / [user:picture:url]
|
||||
og:url = [node:url] / [user:url]
|
||||
og:description
|
||||
og:site_name = [site:name]
|
||||
|
||||
og:latitude
|
||||
og:longitude
|
||||
og:street-address
|
||||
og:locality
|
||||
og:region
|
||||
og:postal-code
|
||||
og:country-name
|
||||
|
||||
og:email
|
||||
og:phone_number
|
||||
og:fax_number
|
||||
|
||||
og:video
|
||||
og:video:height
|
||||
og:video:width
|
||||
og:video:type
|
||||
|
||||
og:audio
|
||||
og:audio:title
|
||||
og:audio:artist
|
||||
og:audio:album
|
||||
og:audio:type
|
||||
|
||||
og:upc
|
||||
og:isbn
|
||||
|
||||
fb:admins
|
||||
fb:app_id
|
||||
*/
|
@@ -0,0 +1,27 @@
|
||||
Metatag: Panels
|
||||
-----------------
|
||||
This module adds support for meta tag configuration for Panels pages.
|
||||
|
||||
Configuration is done within the "Metatag" tab existant in the Page Manager
|
||||
variant configuration page.
|
||||
|
||||
|
||||
Known Issues
|
||||
--------------------------------------------------------------------------------
|
||||
- Only contexts of a type that is supported by the Token API work.
|
||||
- Only one context for each type is currently supported. If you have two 'node'
|
||||
contexts, only the first node is elligible for replacement.
|
||||
|
||||
|
||||
Credits / Contact
|
||||
--------------------------------------------------------------------------------
|
||||
Originally developed by Diogo Correia [1] and sponsored by DRI — Discovery / Reinvention / Integration [2].
|
||||
|
||||
This module is based on Panels Breadcrumbs [3] and the Meta tag: Context module.
|
||||
|
||||
|
||||
References
|
||||
--------------------------------------------------------------------------------
|
||||
1: http://drupal.org/user/887060
|
||||
2: http://dri-global.com
|
||||
3: http://drupal.org/project/panels_breadcrumbs
|
@@ -0,0 +1,16 @@
|
||||
name = Metatag: Panels
|
||||
description = Provides Metatag integration within the Panels interface.
|
||||
package = SEO
|
||||
core = 7.x
|
||||
|
||||
dependencies[] = ctools
|
||||
dependencies[] = metatag
|
||||
dependencies[] = panels
|
||||
dependencies[] = token
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Main file for metatag_panels module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_page_manager_variant_operations_alter().
|
||||
*/
|
||||
function metatag_panels_page_manager_variant_operations_alter(&$operations, $handler) {
|
||||
// Use this obnoxious construct to safely insert our item.
|
||||
reset($operations['children']);
|
||||
$children_operations = array();
|
||||
while (list($key, $value) = each($operations['children'])) {
|
||||
$children_operations[$key] = $value;
|
||||
if ($key == 'context') {
|
||||
$children_operations['meta'] = array(
|
||||
'title' => t('Meta tags'),
|
||||
'description' => t('Edit variant level meta tags.'),
|
||||
'form' => 'metatag_panels_form',
|
||||
);
|
||||
}
|
||||
}
|
||||
$operations['children'] = $children_operations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metatag panels configuration form.
|
||||
*/
|
||||
function metatag_panels_form($form, $form_state) {
|
||||
$handler = $form_state['handler'];
|
||||
|
||||
// Load available contexts
|
||||
ctools_include('context-task-handler');
|
||||
$contexts = ctools_context_handler_get_all_contexts($form_state['task'], $form_state['subtask'], $handler);
|
||||
|
||||
// Convert contexts into keywords readable by the token engine.
|
||||
$token_types = array();
|
||||
|
||||
foreach ($contexts as $context) {
|
||||
if ($context->keyword == 'taxonomy_term') {
|
||||
$token_types[] = 'term';
|
||||
}
|
||||
else {
|
||||
$token_types[] = $context->keyword;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the user to enable/disable meta tags for this panel.
|
||||
$form['settings']['metatags_enabled'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Enable Metatag configuration.'),
|
||||
'#default_value' => isset($handler->conf['metatag_panels']['enabled']) ? $handler->conf['metatag_panels']['enabled'] : FALSE,
|
||||
);
|
||||
|
||||
// Don't set any metatag instance name as the configuration data is managed locally within panels.
|
||||
$instance = '';
|
||||
$options = array('token types' => $token_types);
|
||||
$conf = empty($handler->conf['metatag_panels']) ? array() : $handler->conf['metatag_panels']['metatags'];
|
||||
|
||||
// Load the metatag form (passed by reference).
|
||||
metatag_metatags_form($form, $instance, $conf, $options);
|
||||
|
||||
// Modify metatag form defaults.
|
||||
$form['metatags']['#collapsible'] = FALSE;
|
||||
$form['metatags']['#collapsed'] = FALSE;
|
||||
|
||||
// Don't show the Metatag options until it's enabled.
|
||||
$form['metatags']['#states'] = array(
|
||||
'visible' => array(
|
||||
':input[name="metatags_enabled"]' => array('checked' => TRUE),
|
||||
),
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submission handler for Metatag panels configuration form.
|
||||
*/
|
||||
function metatag_panels_form_submit($form, $form_state) {
|
||||
$conf = array(
|
||||
'enabled' => $form_state['values']['metatags_enabled'],
|
||||
'metatags' => $form_state['values']['metatags'],
|
||||
);
|
||||
|
||||
$form_state['handler']->conf['metatag_panels'] = $conf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_ctools_render_alter().
|
||||
*/
|
||||
function metatag_panels_ctools_render_alter($info, $page, $context) {
|
||||
$output = &drupal_static('metatag_panels');
|
||||
|
||||
$handler = $context['handler'];
|
||||
|
||||
if (empty($handler->conf['metatag_panels']) || !$handler->conf['metatag_panels']['enabled']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$metatags = $handler->conf['metatag_panels']['metatags'];
|
||||
$metatags += metatag_config_load_with_defaults('');
|
||||
|
||||
if (empty($metatags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the contexts that exist within this panel.
|
||||
ctools_include('context-task-handler');
|
||||
$task_object = ctools_context_handler_get_task_object($context['task'], $context['subtask'], $context['handler']);
|
||||
$task_contexts = ctools_context_load_contexts($task_object, TRUE, $context['contexts']);
|
||||
|
||||
// Build the tokens out of CTools contexts.
|
||||
$tokens = array();
|
||||
foreach ($task_contexts as $task_context) {
|
||||
$tokens[$task_context->keyword] = $task_context->data;
|
||||
}
|
||||
|
||||
// Build the Metatag.
|
||||
$options = array(
|
||||
'instance' => 'panels:' . $handler->name,
|
||||
'token data' => $tokens,
|
||||
);
|
||||
foreach ($metatags as $metatag => $data) {
|
||||
$metatag_instance = metatag_get_instance($metatag, $data);
|
||||
|
||||
if ($metatag_instance) {
|
||||
$output[$metatag] = $metatag_instance->getElement($options);
|
||||
}
|
||||
}
|
||||
|
||||
// Give third-parties the opportunity to alter the metatag for a given instance.
|
||||
drupal_alter('metatag_metatags_view', $output, $options['instance']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_page_build().
|
||||
*
|
||||
* @see metatag_panels_ctools_render_alter()
|
||||
*/
|
||||
function metatag_panels_page_build(&$page) {
|
||||
$metatags = drupal_static('metatag_panels');
|
||||
|
||||
if (!empty($metatags)) {
|
||||
$page['content']['metatags']['global'] = $metatags;
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
Metatag: Twitter Cards
|
||||
----------------------
|
||||
This module adds the fourteen basic Twitter Cards meta tags [1]. The following
|
||||
tags are provided:
|
||||
|
||||
* twitter:card
|
||||
* twitter:site
|
||||
* twitter:creator
|
||||
* twitter:url
|
||||
* twitter:title
|
||||
* twitter:description
|
||||
* twitter:image
|
||||
* twitter:image:width
|
||||
* twitter:image:height
|
||||
* twitter:player
|
||||
* twitter:player:width
|
||||
* twitter:player:height
|
||||
* twitter:player:stream
|
||||
* twitter:player:stream:content_type
|
||||
|
||||
|
||||
Usage
|
||||
------------------------------------------------------------------------------
|
||||
The Twitter Cards meta tags are configured along with all other meta tags;
|
||||
on-form help is provided to aid with configuring the meta tags.
|
||||
|
||||
After enabling and configuring the meta tags it is important to first test [2]
|
||||
the meta tags for compliance with Twitter's standards, and then apply [3] to
|
||||
have your site's usage approved.
|
||||
|
||||
|
||||
Credits
|
||||
------------------------------------------------------------------------------
|
||||
The initial development was by nico059 [4] with contributions by many in the
|
||||
community [5].
|
||||
|
||||
|
||||
References
|
||||
------------------------------------------------------------------------------
|
||||
1: https://dev.twitter.com/docs/cards
|
||||
2: https://dev.twitter.com/docs/cards/preview
|
||||
3: http://drupal.org/user/960720
|
||||
4: http://www.gemeentemuseum.nl/
|
||||
5: http://drupal.org/node/1664322
|
@@ -0,0 +1,11 @@
|
||||
name = Metatag: Twitter Cards
|
||||
description = "Provides support for Twitter's Card meta tags."
|
||||
package = SEO
|
||||
core = 7.x
|
||||
dependencies[] = metatag
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Metatag integration for the metatag Twitter Cards module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_default_alter().
|
||||
*/
|
||||
function metatag_twitter_cards_metatag_config_default_alter(array &$configs) {
|
||||
foreach ($configs as &$config) {
|
||||
switch ($config->instance) {
|
||||
case 'global':
|
||||
$config->config += array(
|
||||
'twitter:card' => array('value' => 'summary'),
|
||||
'twitter:description' => array('value' => '[site:slogan]'),
|
||||
'twitter:title' => array('value' => '[site:name]'),
|
||||
'twitter:url' => array('value' => '[current-page:url:absolute]'),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'global:frontpage':
|
||||
$config->config += array(
|
||||
'twitter:description' => array('value' => ''),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'node':
|
||||
$config->config += array(
|
||||
'twitter:card' => array('value' => 'summary'),
|
||||
'twitter:description' => array('value' => '[node:summary]'),
|
||||
'twitter:title' => array('value' => '[node:title]'),
|
||||
);
|
||||
break;
|
||||
|
||||
case 'taxonomy_term':
|
||||
$config->config += array(
|
||||
'twitter:card' => array('value' => 'summary'),
|
||||
'twitter:title'=> array('value' => '[term:name]'),
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_info().
|
||||
*/
|
||||
function metatag_twitter_cards_metatag_info() {
|
||||
$info['groups']['twitter-cards'] = array(
|
||||
'label' => t('Twitter card'),
|
||||
'description' => t('A set of meta tags specially for controlling the summaries displayed when content is shared on <a href="!url">Twitter</a>.', array('!url' => 'http://twitter.com/')),
|
||||
'form' => array(
|
||||
'#weight' => 60,
|
||||
),
|
||||
);
|
||||
|
||||
$info['tags']['twitter:card'] = array(
|
||||
'label' => t('Twitter card type'),
|
||||
'description' => t('Notes: no other fields are required for a <em>Summary</em> card, a <em>Photo</em> card requires the \'image\' field, while a <em>Media player</em> card requires the \'title\', \'description\', \'media player URL\', \'media player width\', \'media player height\' and \'image\' fields.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'form' => array(
|
||||
'#type' => 'select',
|
||||
'#options' => array(
|
||||
'summary' => t('Summary (default)'),
|
||||
'photo' => t('Photo'),
|
||||
'player' => t('Media player'),
|
||||
),
|
||||
'#empty_option' => t('- None -'),
|
||||
),
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:site'] = array(
|
||||
'label' => t('Site\'s Twitter account'),
|
||||
'description' => t('The @username for the website, which will be displayed in the Card\'s footer; must include the @ symbol.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'context' => array('global'),
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:site:id'] = array(
|
||||
'label' => t('Site\'s Twitter account ID'),
|
||||
'description' => t('The numerical Twitter account ID for the website, which will be displayed in the Card\'s footer.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'context' => array('global'),
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:creator'] = array(
|
||||
'label' => t('Creator\'s Twitter account'),
|
||||
'description' => t('The @username for the content creator / author for this page, including the @ symbol.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:creator:id'] = array(
|
||||
'label' => t('Creator\'s Twitter account ID'),
|
||||
'description' => t('The numerical Twitter account ID for the content creator / author for this page.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:url'] = array(
|
||||
'label' => t('Page URL'),
|
||||
'description' => t('The permalink / canonical URL of the current page.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:title'] = array(
|
||||
'label' => t('Title'),
|
||||
'description' => t('The page\'s title, which should be concise; it will be truncated at 70 characters by Twitter. This field is required unless this the \'type\' field is set to "photo".'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:description'] = array(
|
||||
'label' => t('Description'),
|
||||
'description' => t('A description that concisely summarizes the content of the page, as appropriate for presentation within a Tweet. Do not re-use the title text as the description, or use this field to describe the general services provided by the website. The string will be truncated, by Twitter, at the word to 200 characters.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:image'] = array(
|
||||
'label' => t('Image URL'),
|
||||
'description' => t('The URL to a unique image representing the content of the page. Do not use a generic image such as your website logo, author photo, or other image that spans multiple pages. Images larger than 120x120px will be resized and cropped square based on longest dimension. Images smaller than 60x60px will not be shown. If the \'type\' is set to <em>Photo</em> then the image must be at least 280x150px.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:image:width'] = array(
|
||||
'label' => t('Image width'),
|
||||
'description' => t('The width of the image being linked to, in pixels.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:image:height'] = array(
|
||||
'label' => t('Image height'),
|
||||
'description' => t('The height of the image being linked to, in pixels.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:player'] = array(
|
||||
'label' => t('Media player URL'),
|
||||
'description' => t('The full URL for loading a media player. Required when using a <em>Media player</em> card.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:player:width'] = array(
|
||||
'label' => t('Media player width'),
|
||||
'description' => t('The width of the media player iframe, in pixels. Required when using a <em>Media player</em> card.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:player:height'] = array(
|
||||
'label' => t('Media player height'),
|
||||
'description' => t('The height of the media player iframe, in pixels. Required when using a <em>Media player</em> card.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:player:stream'] = array(
|
||||
'label' => t('MP4 media stream URL'),
|
||||
'description' => t('The full URL for an MP4 video (h.264) or audio (AAC) stream, takes precidence over the other media player field.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
$info['tags']['twitter:player:stream:content_type'] = array(
|
||||
'label' => t('MP4 media stream MIME type'),
|
||||
'description' => t('The MIME type for the media contained in the stream URL, as defined by <a href="!url">RFC 4337</a>.', array('!url' => 'http://tools.ietf.org/rfc/rfc4337.txt')),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => 'twitter-cards',
|
||||
'element' => array(
|
||||
'#theme' => 'metatag_twitter_cards',
|
||||
),
|
||||
);
|
||||
return $info;
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Primary hook implementations for Metatag: Twitter Cards.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_ctools_plugin_api().
|
||||
*/
|
||||
function metatag_twitter_cards_ctools_plugin_api($owner, $api) {
|
||||
if ($owner == 'metatag' && $api == 'metatag') {
|
||||
return array('version' => 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function metatag_twitter_cards_theme() {
|
||||
$info['metatag_twitter_cards'] = array(
|
||||
'render element' => 'element',
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme callback for an twittercard meta tag.
|
||||
*/
|
||||
function theme_metatag_twitter_cards($variables) {
|
||||
$element = &$variables['element'];
|
||||
element_set_attributes($element, array('#name' => 'property', '#value' => 'content'));
|
||||
unset($element['#value']);
|
||||
return theme('html_tag', $variables);
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
name = Meta tag UI
|
||||
description = "DEPRECATED admin interface for the Meta tag API, this functionality has be merged into the main module."
|
||||
package = SEO
|
||||
core = 7.x
|
||||
dependencies[] = metatag
|
||||
dependencies[] = ctools
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Empty file for the deprecated Metatag UI module.
|
||||
*/
|
@@ -0,0 +1,16 @@
|
||||
Metatag: Views
|
||||
----------------
|
||||
This module adds support for meta tag configuration for Views pages.
|
||||
|
||||
Configuration is done within the "Metatag" section of the Page Settings in
|
||||
the Views UI configuration page.
|
||||
|
||||
|
||||
Credits / Contact
|
||||
--------------------------------------------------------------------------------
|
||||
Originally developed by Dave Reid [1].
|
||||
|
||||
|
||||
References
|
||||
--------------------------------------------------------------------------------
|
||||
1: http://drupal.org/user/53892
|
@@ -0,0 +1,16 @@
|
||||
name = Metatag: Views
|
||||
description = Provides Metatag integration within the Views interface.
|
||||
package = SEO
|
||||
core = 7.x
|
||||
|
||||
dependencies[] = metatag
|
||||
dependencies[] = views
|
||||
|
||||
files[] = metatag_views_plugin_display_extender_metatags.inc
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Meta tag integration for the metatag_views module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_instance_info().
|
||||
*/
|
||||
function metatag_views_metatag_config_instance_info() {
|
||||
$info['view'] = array('label' => t('Views'));
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_default().
|
||||
*/
|
||||
function metatag_views_metatag_config_default() {
|
||||
$configs = array();
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'view';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'title' => array('value' => '[view:title] | [site:name]'),
|
||||
'description' => array('value' => '[view:description]'),
|
||||
'canonical' => array('value' => '[view:url]'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
return $configs;
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Provides native meta tag integration with Views.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_views_api().
|
||||
*/
|
||||
function metatag_views_views_api() {
|
||||
return array('api' => 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_ctools_plugin_api().
|
||||
*/
|
||||
function metatag_views_ctools_plugin_api($owner, $api) {
|
||||
if ($owner == 'metatag' && $api == 'metatag') {
|
||||
return array('version' => 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_view_preview_info_alter().
|
||||
*/
|
||||
function metatag_views_views_preview_info_alter(&$rows, $view) {
|
||||
if (metatag_views_views_display_has_metatags($view->display_handler)) {
|
||||
$instance = 'view:' . $view->name;
|
||||
$metatags = $view->display_handler->get_option('metatags');
|
||||
$metatags = !empty($metatags) ? $metatags : array();
|
||||
|
||||
// Set the page title to be the previewed views title before fetching meta
|
||||
// tag values.
|
||||
$title = drupal_set_title();
|
||||
if ($view_title = $view->get_title()) {
|
||||
drupal_set_title($view_title);
|
||||
}
|
||||
|
||||
$options['token data']['view'] = $view;
|
||||
$values = metatag_metatags_values($instance, $metatags, $options);
|
||||
foreach ($values as $metatag => $value) {
|
||||
$metatag_info = metatag_get_info('tags', $metatag);
|
||||
$values[$metatag] = check_plain($metatag_info['label']) . ': ' . check_plain($value);
|
||||
}
|
||||
$rows['query'][] = array(
|
||||
'<strong>' . t('Meta tags') . '</strong>',
|
||||
implode('<br />', $values),
|
||||
);
|
||||
|
||||
// Restore the page title.
|
||||
drupal_set_title($title);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_page_alter().
|
||||
*/
|
||||
function metatag_views_page_alter(&$page) {
|
||||
if ($view = views_get_page_view()) {
|
||||
// The following is taken from views_get_page_view().
|
||||
// If a module is still putting in the display like we used to, catch that.
|
||||
if (is_subclass_of($view, 'views_plugin_display')) {
|
||||
$view = $view->view;
|
||||
}
|
||||
|
||||
// Load the
|
||||
if (metatag_views_views_display_has_metatags($view->display_handler)) {
|
||||
$saved_metatags = $view->display_handler->get_option('metatags');
|
||||
$metatags = array();
|
||||
if (!empty($saved_metatags)) {
|
||||
$metatags[LANGUAGE_NONE] = $saved_metatags;
|
||||
}
|
||||
|
||||
// Build options for meta tag rendering.
|
||||
$instance = 'view:' . $view->name;
|
||||
$options = array();
|
||||
$options['token data']['view'] = $view;
|
||||
|
||||
// Add the metatags.
|
||||
$page['content']['metatags'][$instance] = metatag_metatags_view($instance, $metatags, $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the requested view display has meta tags saved.
|
||||
*
|
||||
* @param $display views_plugin_display
|
||||
* The view display plugin that will be checked.
|
||||
*
|
||||
* @return
|
||||
* Simple boolean to indicate whether there are meta tags saved.
|
||||
*/
|
||||
function metatag_views_views_display_has_metatags(views_plugin_display $display) {
|
||||
if (method_exists($display, 'has_metatags')) {
|
||||
return $display->has_metatags();
|
||||
}
|
||||
else {
|
||||
return $display->has_path() && $display->uses_breadcrumb();
|
||||
}
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Token integration for the metatag_views module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_token_info().
|
||||
*/
|
||||
function metatag_views_token_info() {
|
||||
if (module_hook('views', 'token_info')) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$info['types']['view'] = array(
|
||||
'name' => t('View'),
|
||||
'description' => t('Tokens related to views.'),
|
||||
'needs-data' => 'view',
|
||||
);
|
||||
$info['tokens']['view']['name'] = array(
|
||||
'name' => t('Name'),
|
||||
'description' => t('The human-readable name of the view.'),
|
||||
);
|
||||
$info['tokens']['view']['description'] = array(
|
||||
'name' => t('Description'),
|
||||
'description' => t('The description of the view.'),
|
||||
);
|
||||
$info['tokens']['view']['machine-name'] = array(
|
||||
'name' => t('Machine name'),
|
||||
'description' => t('The machine-readable name of the view.'),
|
||||
);
|
||||
$info['tokens']['view']['title'] = array(
|
||||
'name' => t('Title'),
|
||||
'description' => t('The title of current display of the view.'),
|
||||
);
|
||||
$info['tokens']['view']['url'] = array(
|
||||
'name' => t('URL'),
|
||||
'description' => t('The URL of the view.'),
|
||||
'type' => 'url',
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_tokens().
|
||||
*/
|
||||
function metatag_views_tokens($type, $tokens, array $data = array(), array $options = array()) {
|
||||
if (module_hook('views', 'tokens')) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$url_options = array('absolute' => TRUE);
|
||||
if (isset($options['language'])) {
|
||||
$url_options['language'] = $options['language'];
|
||||
}
|
||||
$sanitize = !empty($options['sanitize']);
|
||||
$langcode = isset($options['language']) ? $options['language']->language : NULL;
|
||||
|
||||
$replacements = array();
|
||||
|
||||
if ($type == 'view' && !empty($data['view'])) {
|
||||
$view = $data['view'];
|
||||
|
||||
foreach ($tokens as $name => $original) {
|
||||
switch ($name) {
|
||||
case 'name':
|
||||
$replacements[$original] = $sanitize ? check_plain($view->human_name) : $view->human_name;
|
||||
break;
|
||||
|
||||
case 'description':
|
||||
$replacements[$original] = $sanitize ? check_plain($view->description) : $view->description;
|
||||
break;
|
||||
|
||||
case 'machine-name':
|
||||
$replacements[$original] = $view->name;
|
||||
break;
|
||||
|
||||
case 'title':
|
||||
$title = $view->get_title();
|
||||
$replacements[$original] = $sanitize ? check_plain($title) : $title;
|
||||
break;
|
||||
|
||||
case 'url':
|
||||
if ($path = $view->get_url()) {
|
||||
$replacements[$original] = url($path, $url_options);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// [view:url:*] nested tokens. This only works if Token module is installed.
|
||||
if ($url_tokens = token_find_with_prefix($tokens, 'url')) {
|
||||
if ($path = $view->get_url()) {
|
||||
$replacements += token_generate('url', $url_tokens, array('path' => $path), $options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $replacements;
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Views integration for the metatag module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_views_plugins().
|
||||
*/
|
||||
function metatag_views_views_plugins() {
|
||||
$plugins = array();
|
||||
$plugins['display_extender']['metatags'] = array(
|
||||
'title' => t('Meta tags'),
|
||||
'help' => t('Provides meta tags for views.'),
|
||||
'handler' => 'metatag_views_plugin_display_extender_metatags',
|
||||
'enabled' => TRUE,
|
||||
);
|
||||
|
||||
return $plugins;
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Custom display extender plugin for Views.
|
||||
*/
|
||||
|
||||
class metatag_views_plugin_display_extender_metatags extends views_plugin_display_extender {
|
||||
|
||||
protected function has_metatags() {
|
||||
return metatag_views_views_display_has_metatags($this->display);
|
||||
}
|
||||
|
||||
function options_definition_alter(&$options) {
|
||||
$options['metatags'] = array('default' => array());
|
||||
}
|
||||
|
||||
function options_summary(&$categories, &$options) {
|
||||
if ($this->has_metatags()) {
|
||||
$categories['metatags'] = array(
|
||||
'title' => t('Meta tags'),
|
||||
'column' => 'second',
|
||||
);
|
||||
$metatags = $this->display->get_option('metatags');
|
||||
$options['metatags'] = array(
|
||||
'category' => 'metatags',
|
||||
'title' => t('Meta tags'),
|
||||
'value' => !empty($metatags) ? t('Overridden') : t('Using defaults'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function options_form(&$form, &$form_state) {
|
||||
if ($form_state['section'] == 'metatags') {
|
||||
$form['#title'] .= t('The meta tags for this display');
|
||||
$instance = 'view:' . $form_state['view']->name;
|
||||
$metatags = $this->display->get_option('metatags');
|
||||
$metatags = !empty($metatags) ? $metatags : array();
|
||||
$options['token types'] = array('view');
|
||||
$options['context'] = 'view';
|
||||
metatag_metatags_form($form, $instance, $metatags, $options);
|
||||
$form['metatags']['#type'] = 'container';
|
||||
}
|
||||
}
|
||||
|
||||
function options_submit(&$form, &$form_state) {
|
||||
if ($form_state['section'] == 'metatags') {
|
||||
$metatags = $form_state['values']['metatags'];
|
||||
metatag_filter_values_from_defaults($metatags);
|
||||
$this->display->set_option('metatags', $metatags);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
name = Meta Tag Test
|
||||
description = Testing module for metatag.module
|
||||
core = 7.x
|
||||
dependencies[] = metatag
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-09-23
|
||||
version = "7.x-1.0-beta7+54-dev"
|
||||
core = "7.x"
|
||||
project = "metatag"
|
||||
datestamp = "1379942674"
|
||||
|
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_default().
|
||||
*/
|
||||
function metatag_test_metatag_config_default() {
|
||||
$configs = array();
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'test';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'description' => array('value' => 'Test description'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
$config = new stdClass();
|
||||
$config->instance = 'test:foo';
|
||||
$config->api_version = 1;
|
||||
$config->disabled = FALSE;
|
||||
$config->config = array(
|
||||
'description' => array('value' => 'Test foo description'),
|
||||
'abstract' => array('value' => 'Test foo abstract'),
|
||||
'title' => array('value' => 'Test title'),
|
||||
'test:foo' => array('value' => 'foobar'),
|
||||
);
|
||||
$configs[$config->instance] = $config;
|
||||
|
||||
return $configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_config_default_alter().
|
||||
*/
|
||||
function metatag_test_metatag_config_default_alter(array &$configs) {
|
||||
if (isset($configs['test:foo'])) {
|
||||
$configs['test:foo']->config['title']['value'] = 'Test altered title';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_metatag_info().
|
||||
*/
|
||||
function metatag_test_metatag_info() {
|
||||
$info['test:foo'] = array(
|
||||
'label' => t('Foo meta tag'),
|
||||
'description' => t('Testing metatag.'),
|
||||
'class' => 'DrupalTextMetaTag',
|
||||
'group' => t('Testing'),
|
||||
);
|
||||
|
||||
return $info;
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_ctools_plugin_api().
|
||||
*/
|
||||
function metatag_test_ctools_plugin_api($owner, $api) {
|
||||
if ($owner == 'metatag' && $api == 'metatag') {
|
||||
return array('version' => 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info_alter().
|
||||
*/
|
||||
function metatag_test_entity_info_alter(&$info) {
|
||||
if (variable_get('metatag_test_entity_info_disable')) {
|
||||
$info['node']['bundles']['page']['metatags'] = FALSE;
|
||||
$info['user']['metatags'] = FALSE;
|
||||
}
|
||||
}
|
339
sites/all/modules/contrib/seo/seo_checklist/LICENSE.txt
Normal file
339
sites/all/modules/contrib/seo/seo_checklist/LICENSE.txt
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
79
sites/all/modules/contrib/seo/seo_checklist/README.txt
Normal file
79
sites/all/modules/contrib/seo/seo_checklist/README.txt
Normal file
@@ -0,0 +1,79 @@
|
||||
|
||||
CONTENTS OF THIS FILE
|
||||
---------------------
|
||||
|
||||
* Description and Benefits
|
||||
* Installation and Usage
|
||||
* Upgrading from 3.x
|
||||
* More Information
|
||||
|
||||
|
||||
DESCRIPTION AND BENEFITS
|
||||
------------------------
|
||||
|
||||
The SEO Checklist module provides a list of good SEO actions that you should
|
||||
take to maximize the presence of your website in the major search engines. It
|
||||
provides little functionality itself but rather it helps you keep track of what
|
||||
needs to be done and what has been completed already.
|
||||
|
||||
Search Engines Drive 90% of the traffic on the web. The more "findable" you are,
|
||||
the easier it is for you to get customers. This module helps you with on-page
|
||||
SEO - a necessary component of a good online marketing campaign.
|
||||
|
||||
|
||||
INSTALLATION AND USAGE
|
||||
----------------------
|
||||
|
||||
SEO Checklist is installed in the usual way. See
|
||||
http://drupal.org/documentation/install/modules-themes/modules-7. To start using
|
||||
the module, go to admin/settings/seo-checklist. It will pre-check any completed
|
||||
items it is able to auto detect. Start working through the rest, and click
|
||||
"Save" to save your progress!
|
||||
|
||||
|
||||
UPGRADING FROM 3.x
|
||||
------------------
|
||||
|
||||
IMPORTANT: As with any other irreversible change, you should backup your
|
||||
database before attempting to upgrade the SEO Checklist!
|
||||
|
||||
With the 4.x branch the module machine name was changed to match the Drupal.org
|
||||
project name, so Drupal won't recognize it as the same module anymore. You'll
|
||||
need to re-enable it from the Modules page (admin/modules). When installed, it
|
||||
will remove the residue of the old module name itself.
|
||||
|
||||
Additionally, the module now depends on the Checklist API
|
||||
(http://drupal.org/project/checklistapi), which you'll need to install before
|
||||
you can enable the new version.
|
||||
|
||||
Your saved progress from the 3.x version of the module will be preserved when
|
||||
you update.
|
||||
|
||||
|
||||
MORE INFORMATION
|
||||
----------------
|
||||
|
||||
- A very handy companion for this module is the Drupal 6 Search Engine
|
||||
Optimization book by Ben Finklea. For more information and to purchase, go to
|
||||
http://www.drupalseobook.com/.
|
||||
|
||||
- To submit any bug reports or feature-or-support requests, see the module issue
|
||||
queue at http://drupal.org/project/issues/seo_checklist.
|
||||
|
||||
- This module is potentially controversial as many people have ideas about good
|
||||
and bad SEO. If you have an idea of a module or task that should be included,
|
||||
please file an issue at http://drupal.org/project/issues/seo_checklist.
|
||||
|
||||
- Volacci spent numerous hours in research and development on this module. We
|
||||
want to maintain it and keep good SEO advice available to the entire
|
||||
community. Instead of asking for donations or bounties for this module, we
|
||||
request that you include a simple link back to us somewhere on your website.
|
||||
When you're done (or before) go down to the "Link to Volacci" task and check
|
||||
it! That will automatically add a link to Volacci in your website's footer.
|
||||
If you want to link to us but not in your footer, uncheck the box and put
|
||||
the link to http://www.volacci.com/ wherever you want to. Thanks for the link!
|
||||
If you e-mail us (seochecklist [at] volacci.com) and tell us where your link
|
||||
is, we'll link back to you! As you may know, links help move your site up in
|
||||
the search engines. (See http://www.volacci.com/why-links-help-seo.)
|
||||
|
||||
- Enjoy using the module!
|
@@ -0,0 +1,11 @@
|
||||
|
||||
#seo-checklist-intro-volacci {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
#seo-checklist-intro-volacci strong {
|
||||
display: block;
|
||||
}
|
||||
#seo-checklist-volacci-link {
|
||||
text-align: center;
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
name = SEO Checklist
|
||||
description = A Search Engine Optimization checklist for Drupal.
|
||||
core = 7.x
|
||||
dependencies[] = checklistapi
|
||||
package = SEO
|
||||
configure = admin/config/search/seo-checklist
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-02-08
|
||||
version = "7.x-4.1"
|
||||
core = "7.x"
|
||||
project = "seo_checklist"
|
||||
datestamp = "1360294437"
|
||||
|
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Install, update and uninstall functions for the seo_checklist module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
function seo_checklist_install() {
|
||||
// Detect and update a pre- name change installation.
|
||||
$result = db_query("SELECT * FROM {system} WHERE name = 'seochecklist'");
|
||||
if ($result->rowCount()) {
|
||||
seo_checklist_update_7400();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_uninstall().
|
||||
*/
|
||||
function seo_checklist_uninstall() {
|
||||
variable_del('checklistapi_checklist_seo_checklist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename module machine name and convert saved progress data to new format.
|
||||
*
|
||||
* Note: Drupal won't detect and run this function in the usual way, because
|
||||
* the change of module machine name causes it to lose track of the current
|
||||
* schema version, so it's invoked manually by seo_checklist_install(), if
|
||||
* appropriate.
|
||||
*/
|
||||
function seo_checklist_update_7400() {
|
||||
// Convert saved progress data.
|
||||
if (db_table_exists('seo_checklist')) {
|
||||
$result = db_query('SELECT id, completed, uid FROM {seo_checklist}');
|
||||
$old_data = $result->fetchAllAssoc('id');
|
||||
$data_mapping = array(
|
||||
'install_page_title' => 1,
|
||||
'enable_clean_urls' => 2,
|
||||
'install_pathauto' => 5,
|
||||
'install_globalredirect' => 6,
|
||||
'get_google_account' => 7,
|
||||
'install_google_analytics' => 9,
|
||||
'create_google_analytics_analytics' => 11,
|
||||
'input_google_analytics_code' => 12,
|
||||
'authenticate_with_google_analytics' => 13,
|
||||
'install_metatags_quick' => 15,
|
||||
'install_scheduler' => 16,
|
||||
'install_htmlpurifier' => 17,
|
||||
'install_search404' => 18,
|
||||
'validate_html' => 19,
|
||||
'check_links' => 20,
|
||||
'install_xmlsitemap' => 21,
|
||||
'authenticate_with_google' => 23,
|
||||
'submit_xml_sitemap_to_google' => 24,
|
||||
'submit_xml_sitemap_to_bing' => 28,
|
||||
'add_to_google_places' => 29,
|
||||
'install_addthis' => 30,
|
||||
'install_service_links' => 31,
|
||||
'install_mollom' => 39,
|
||||
'sign_up_for_mollom_account' => 40,
|
||||
'authenticate_with_bing' => 43,
|
||||
'get_windows_live_id' => 44,
|
||||
'install_htmlpurifier' => 45,
|
||||
'install_site_map' => 46,
|
||||
'install_site_verify' => 47,
|
||||
'install_addtoany' => 49,
|
||||
'add_geo_meta_tags' => 51,
|
||||
'install_admin_menu' => 53,
|
||||
'enable_drupal_caching' => 54,
|
||||
'install_boost' => 55,
|
||||
'install_seo_checker' => 57,
|
||||
'install_fb_social' => 58,
|
||||
'install_follow' => 59,
|
||||
'install_elements' => 60,
|
||||
'install_security_review' => 61,
|
||||
'install_read_more' => 62,
|
||||
'install_ga_tokenizer' => 63,
|
||||
'install_contact_google_analytics' => 64,
|
||||
'install_context_keywords' => 65,
|
||||
);
|
||||
global $user;
|
||||
$new_data = array(
|
||||
'#changed' => $time = time(),
|
||||
'#changed_by' => $user->uid,
|
||||
'#completed_items' => 0,
|
||||
);
|
||||
$definitions = seo_checklist_checklistapi_checklist_info();
|
||||
$groups = $definitions['seo_checklist'];
|
||||
foreach (element_children($groups) as $group_key) {
|
||||
$group = &$groups[$group_key];
|
||||
foreach (element_children($group) as $item_key) {
|
||||
if (!empty($data_mapping[$item_key])) {
|
||||
$old_item = $old_data[$data_mapping[$item_key]];
|
||||
if (!empty($old_item->completed)) {
|
||||
$new_data[$item_key] = array(
|
||||
'#completed' => $old_item->completed,
|
||||
'#uid' => $old_item->uid,
|
||||
);
|
||||
$new_data['#completed_items']++;
|
||||
}
|
||||
}
|
||||
if (!isset($new_data[$item_key])) {
|
||||
$new_data[$item_key] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (variable_get('seo_checklist_link', 0)) {
|
||||
$new_data['link_to_volacci'] = array(
|
||||
'#completed' => $time,
|
||||
'#uid' => $user->uid,
|
||||
);
|
||||
}
|
||||
ksort($new_data);
|
||||
variable_set('checklistapi_checklist_seo_checklist', $new_data);
|
||||
}
|
||||
|
||||
// Remove old database tables.
|
||||
foreach (array('seo_group', 'seo_checklist') as $table) {
|
||||
if (db_table_exists($table)) {
|
||||
db_drop_table($table);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the old "seochecklist" row from the system table.
|
||||
db_delete('system')
|
||||
->condition('name', 'seochecklist')
|
||||
->execute();
|
||||
|
||||
// Remove now unused variables.
|
||||
variable_del('seo_checklist_book_references');
|
||||
variable_del('seo_checklist_link');
|
||||
variable_del('seo_checklist_podcast');
|
||||
variable_del('seo_checklist_thanks');
|
||||
}
|
23
sites/all/modules/contrib/seo/seo_checklist/seo_checklist.js
Normal file
23
sites/all/modules/contrib/seo/seo_checklist/seo_checklist.js
Normal file
@@ -0,0 +1,23 @@
|
||||
(function ($) {
|
||||
|
||||
"use strict";
|
||||
Drupal.behaviors.seo_checklist = {
|
||||
attach: function (context) {
|
||||
|
||||
// Open external links in a new window.
|
||||
$('#checklistapi-checklist-form fieldset a', context).filter(function () {
|
||||
// Ignore non-HTTP (e.g. mailto:) link.
|
||||
return this.href.indexOf('http') === 0;
|
||||
}).filter(function () {
|
||||
// Filter out links to the same domain.
|
||||
return this.hostname && this.hostname !== location.hostname;
|
||||
}).each(function () {
|
||||
// Send all links to drupal.org to the same window. Open others in their
|
||||
// own windows.
|
||||
$(this).attr('target', (this.hostname === 'drupal.org') ? 'drupal_org' : '_blank');
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
574
sites/all/modules/contrib/seo/seo_checklist/seo_checklist.module
Normal file
574
sites/all/modules/contrib/seo/seo_checklist/seo_checklist.module
Normal file
@@ -0,0 +1,574 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Track important SEO techniques on the website.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Checks whether the Volacci footer link is enabled.
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if the footer link is enabled or FALSE if not.
|
||||
*/
|
||||
function _seo_checklist_volacci_link_is_enabled() {
|
||||
$link_is_enabled = &drupal_static(__FUNCTION__);
|
||||
if (!isset($link_is_enabled)) {
|
||||
$saved_progress = variable_get('checklistapi_checklist_seo_checklist', array());
|
||||
$link_is_enabled = !empty($saved_progress['link_to_volacci']);
|
||||
}
|
||||
return $link_is_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*/
|
||||
function seo_checklist_form_checklistapi_checklist_form_alter(&$form, &$form_state, $form_id) {
|
||||
if ($form['#checklist']->id == 'seo_checklist') {
|
||||
$form['checklistapi']['#attached']['js'][] = drupal_get_path('module', 'seo_checklist') . '/seo_checklist.js';
|
||||
$form['checklistapi']['#attached']['css'][] = drupal_get_path('module', 'seo_checklist') . '/seo_checklist.css';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_checklistapi_checklist_info().
|
||||
*/
|
||||
function seo_checklist_checklistapi_checklist_info() {
|
||||
$modules_page = array('#text' => t('Enable'), '#path' => 'admin/modules');
|
||||
|
||||
$definitions = array();
|
||||
$definitions['seo_checklist'] = array(
|
||||
'#title' => t('SEO checklist'),
|
||||
'#description' => t('Keep track of your Drupal Search Engine Optimization tasks.'),
|
||||
'#path' => 'admin/config/search/seo-checklist',
|
||||
'#help' => t("<p>Check off each SEO-related task as you complete it. Don't forget to click the <em>Save</em> button!</p>"),
|
||||
|
||||
// Introduction.
|
||||
'introduction' => array(
|
||||
'#title' => t('Introduction'),
|
||||
'#description' => theme('seo_checklist_intro_tab', array(
|
||||
'volacci_logo' => theme('image', array(
|
||||
'path' => drupal_get_path('module', 'seo_checklist') . '/volacci-logo.png',
|
||||
'alt' => t('Volacci'),
|
||||
'title' => t('Volacci'),
|
||||
)),
|
||||
)),
|
||||
),
|
||||
|
||||
// Tools.
|
||||
'tools' => array(
|
||||
'#title' => t('Tools (optional)'),
|
||||
'#description' => t('<p>While not strictly necessary for SEO, these modules will accelerate your work.</p>'),
|
||||
'install_admin_menu' => array(
|
||||
'#title' => t('[Optional] Install Administration menu module.'),
|
||||
'#default_value' => module_exists('admin_menu'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/admin_menu',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'install_drush' => array(
|
||||
'#title' => t('[Optional] Install Drush.'),
|
||||
'#description' => t('Drush is a command line tool for Drupal that you can use, among other things, to <a href="http://vimeo.com/5207683">install modules faster</a>.'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download and install'),
|
||||
'#path' => 'http://drupal.org/project/drush',
|
||||
),
|
||||
),
|
||||
'install_module_filter' => array(
|
||||
'#title' => t('[Optional] Install Module Filter module.'),
|
||||
'#default_value' => module_exists('module_filter'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/module_filter',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
),
|
||||
|
||||
// Page titles and meta tags.
|
||||
'page_titles_meta_tags' => array(
|
||||
'#title' => t('Page titles and meta tags'),
|
||||
'#description' => t('<p>Search engines look at your <code>TITLE</code> tags and certain meta data to determine what your site is about. These modules give you control over this important information.</p>'),
|
||||
'install_metatag' => array(
|
||||
'#title' => t('Install Meta tags module.'),
|
||||
'#default_value' => module_exists('metatag'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/metatag',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'configure_metatag' => array(
|
||||
'#title' => t('Configure Meta tags module.'),
|
||||
'#description' => t('If local SEO is important to you, add geo meta tags.'),
|
||||
'config_page' => array(
|
||||
'#text' => t('Configure'),
|
||||
'#path' => 'admin/config/search/metatags',
|
||||
),
|
||||
),
|
||||
'install_metatags_quick' => array(
|
||||
'#title' => t('[Optional] Install Meta tags quick module.'),
|
||||
'#description' => t("If you want to add meta tags to non-node entities, you'll need this module for now."),
|
||||
'#default_value' => module_exists('metatags_quick'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/metatags_quick',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'configure_metatags_quick' => array(
|
||||
'#title' => t('[Optional] Configure Meta tags quick module.'),
|
||||
'config_page' => array(
|
||||
'#text' => t('Configure'),
|
||||
'#path' => 'admin/config/search/metatags_quick',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// URL paths.
|
||||
'url_paths' => array(
|
||||
'#title' => t('URL paths'),
|
||||
'#description' => t("<p>Search engines use your site's URLs to help determine structure, organization, and topical relevance.</p>"),
|
||||
'enable_clean_urls' => array(
|
||||
'#title' => t('Enable clean URLs.'),
|
||||
'#default_value' => variable_get('clean_url', 0),
|
||||
'config_page' => array(
|
||||
'#text' => t('Configure'),
|
||||
'#path' => 'admin/config/search/clean-urls',
|
||||
),
|
||||
'more_info' => array(
|
||||
'#text' => t('More info'),
|
||||
'#path' => 'http://drupal.org/getting-started/clean-urls',
|
||||
),
|
||||
),
|
||||
'install_pathauto' => array(
|
||||
'#title' => t('Install Pathauto module.'),
|
||||
'#default_value' => module_exists('pathauto'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/pathauto',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'configure_pathauto' => array(
|
||||
'#title' => t('Configure Pathauto module.'),
|
||||
'config_page' => array(
|
||||
'#text' => t('Configure'),
|
||||
'#path' => 'admin/config/search/path/patterns',
|
||||
),
|
||||
),
|
||||
'install_globalredirect' => array(
|
||||
'#title' => t('Install Global Redirect module.'),
|
||||
'#default_value' => module_exists('globalredirect'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/globalredirect',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'install_redirect' => array(
|
||||
'#title' => t('Install Redirect module.'),
|
||||
'#default_value' => module_exists('redirect'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/redirect',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
),
|
||||
|
||||
// Create search engine accounts.
|
||||
'search_engine_accounts' => array(
|
||||
'#title' => t('Create search engine accounts'),
|
||||
'#description' => t("<p>Set your site up with the search engines. You'll need these accounts for later steps in the SEO Checklist but also to help you communicate and evaluate your site on an ongoing basis.</p>"),
|
||||
'get_google_account' => array(
|
||||
'#title' => t('Get a Google account.'),
|
||||
'create_account' => array(
|
||||
'#text' => t('Create account'),
|
||||
'#path' => 'https://www.google.com/accounts/NewAccount',
|
||||
),
|
||||
),
|
||||
'get_windows_live_id' => array(
|
||||
'#title' => t('Get a Windows Live ID.'),
|
||||
'create_account' => array(
|
||||
'#text' => t('Create account'),
|
||||
'#path' => 'https://signup.live.com/',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Track your visitors.
|
||||
'track_visitors' => array(
|
||||
'#title' => t('Track your visitors'),
|
||||
'#description' => t('<p>See where your visitors are coming from and what they do while visiting your site.</p>'),
|
||||
'install_google_analytics' => array(
|
||||
'#title' => t('Install Google Analytics module.'),
|
||||
'#default_value' => module_exists('googleanalytics'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/google_analytics',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'create_google_analytics_analytics' => array(
|
||||
'#title' => t('Sign in to your Google Analytics account and create an Analytics for your website.'),
|
||||
'#default_value' => $googleanalytics_account = (bool) variable_get('googleanalytics_account', 0),
|
||||
'web_site' => array(
|
||||
'#text' => t('Google Analytics'),
|
||||
'#path' => 'http://www.google.com/analytics',
|
||||
),
|
||||
),
|
||||
'input_google_analytics_code' => array(
|
||||
'#title' => t('Copy and paste your new Google Analytics code into the Google Analytics module.'),
|
||||
'#default_value' => $googleanalytics_account = (bool) variable_get('googleanalytics_account', 0),
|
||||
'project_page' => array(
|
||||
'#text' => t('Module settings'),
|
||||
'#path' => 'admin/config/system/googleanalytics',
|
||||
),
|
||||
),
|
||||
'authenticate_with_google_analytics' => array(
|
||||
'#title' => t('Authenticate your site with Google Analytics.'),
|
||||
'web_site' => array(
|
||||
'#text' => t('Google Analytics'),
|
||||
'#path' => 'http://www.google.com/analytics',
|
||||
),
|
||||
),
|
||||
'install_ga_tokenizer' => array(
|
||||
'#title' => t('Install Google Analytics Tokenizer module.'),
|
||||
'#default_value' => module_exists('ga_tokenizer'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/ga_tokenizer',
|
||||
),
|
||||
),
|
||||
'install_contact_google_analytics' => array(
|
||||
'#title' => t('Install Google Analytics Contact Form, Webform, Rules Email module.'),
|
||||
'#default_value' => module_exists('contact_google_analytics'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/contact_google_analytics',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'configure_contact_google_analytics' => array(
|
||||
'#title' => t('Configure Google Analytics Contact Form, Webform, Rules Email module.'),
|
||||
'#default_value' => variable_get('contact_google_analytics_allowed_recipients', 'all') != 'all',
|
||||
'config_page' => array(
|
||||
'#text' => t('Configure'),
|
||||
'#path' => 'admin/config/contact-google-analytics',
|
||||
),
|
||||
),
|
||||
'install_context_keywords' => array(
|
||||
'#title' => t('Install Context Keywords module.'),
|
||||
'#default_value' => module_exists('context_keywords'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/context_keywords',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Content.
|
||||
'content' => array(
|
||||
'#title' => t('Content'),
|
||||
'#description' => t('<p>Well-written content is important to the search engines. These modules help.</p>'),
|
||||
'install_microdata' => array(
|
||||
'#title' => t('Install Microdata module.'),
|
||||
'#description' => t("Microdata enables you to share content with other sites and services, like Google's Recipe View, using inline metadata."),
|
||||
'#default_value' => module_exists('microdata'),
|
||||
'config_page' => array(
|
||||
'#text' => t('Download module'),
|
||||
'#path' => 'http://drupal.org/project/microdata',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'configure_microdata' => array(
|
||||
'#title' => t('Configure Microdata module.'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Configure'),
|
||||
'#path' => 'admin/config/services/microdata',
|
||||
),
|
||||
),
|
||||
'install_htmlpurifier' => array(
|
||||
'#title' => t('Install HTML Purifier module.'),
|
||||
'#description' => t('Follow the README!'),
|
||||
'#default_value' => module_exists('htmlpurifier'),
|
||||
'readme' => array(
|
||||
'#text' => t('README.txt'),
|
||||
'#path' => 'http://drupalcode.org/project/htmlpurifier.git/blob/refs/heads/7.x-1.x:/INSTALL.txt',
|
||||
),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download module'),
|
||||
'#path' => 'http://drupal.org/project/htmlpurifier',
|
||||
),
|
||||
'library_page' => array(
|
||||
'#text' => t('Download library'),
|
||||
'#path' => 'http://htmlpurifier.org/download',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'install_search404' => array(
|
||||
'#title' => t('Install Search 404 module.'),
|
||||
'#default_value' => module_exists('search404'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/search404',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'install_seo_checker' => array(
|
||||
'#title' => t('Install SEO Compliance Checker module.'),
|
||||
'#default_value' => module_exists('seo_checker'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/seo_checker',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'validate_html' => array(
|
||||
'#title' => t('Validate your markup.'),
|
||||
'w3c_validator' => array(
|
||||
'#text' => t('W3C Markup Validation Service'),
|
||||
'#path' => 'http://validator.w3.org/',
|
||||
),
|
||||
),
|
||||
'check_links' => array(
|
||||
'#title' => t('Check for broken links.'),
|
||||
'w3c_link_checker' => array(
|
||||
'#text' => t('W3C Link Checker'),
|
||||
'#path' => 'http://validator.w3.org/checklink',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Submit your site to the search engines.
|
||||
'submit_to_search_engines' => array(
|
||||
'#title' => t('Submit your site to the search engines'),
|
||||
'#description' => t("<p>Now that you've got your site ready for the search engines, use these tools to tell them you're ready for them to visit.</p>"),
|
||||
'install_site_verify' => array(
|
||||
'#title' => t('Install Site verification module.'),
|
||||
'#default_value' => module_exists('site_verify'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/site_verify',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'add_verifications' => array(
|
||||
'#title' => t('Add verifications.'),
|
||||
'config_page' => array(
|
||||
'#text' => t('Verifications'),
|
||||
'#path' => 'admin/config/search/verifications',
|
||||
),
|
||||
),
|
||||
'install_xmlsitemap' => array(
|
||||
'#title' => t('Install XML Sitemap module.'),
|
||||
'#default_value' => module_exists('xmlsitemap'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/xmlsitemap',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'install_site_map' => array(
|
||||
'#title' => t('Install Site map module.'),
|
||||
'#default_value' => module_exists('site_map'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/site_map',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'authenticate_with_google' => array(
|
||||
'#title' => t('Authenticate with Google.'),
|
||||
'webmaster_tools' => array(
|
||||
'#text' => t('Webmaster Tools'),
|
||||
'#path' => 'http://www.google.com/webmasters/tools',
|
||||
),
|
||||
),
|
||||
'submit_xml_sitemap_to_google' => array(
|
||||
'#title' => t('Submit your XML sitemap to Google.'),
|
||||
'webmaster_tools' => array(
|
||||
'#text' => t('Webmaster Tools'),
|
||||
'#path' => 'http://www.google.com/webmasters/tools',
|
||||
),
|
||||
'help_page' => array(
|
||||
'#text' => t('Help page'),
|
||||
'#path' => 'http://support.google.com/webmasters/bin/answer.py?hl=en&answer=183669&topic=8476&ctx=topic',
|
||||
),
|
||||
),
|
||||
'authenticate_with_bing' => array(
|
||||
'#title' => t('Authenticate with Bing.'),
|
||||
'webmaster_tools' => array(
|
||||
'#text' => t('Webmaster Tools'),
|
||||
'#path' => 'http://www.bing.com/webmaster/',
|
||||
),
|
||||
),
|
||||
'submit_xml_sitemap_to_bing' => array(
|
||||
'#title' => t('Submit your XML sitemap to Bing.'),
|
||||
'webmaster_tools' => array(
|
||||
'#text' => t('Submission page'),
|
||||
'#path' => 'http://www.bing.com/webmaster/submitsitepage.aspx',
|
||||
),
|
||||
),
|
||||
'add_to_google_places' => array(
|
||||
'#title' => t('[Optional] Add your business to Google Places, if appropriate.'),
|
||||
'google_places' => array(
|
||||
'#text' => t('Google Places'),
|
||||
'#path' => 'http://www.google.com/local/add/',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Other checklists.
|
||||
'other_checklists' => array(
|
||||
'#title' => t('Other checklists'),
|
||||
'#description' => t('<p>These checklists are essential for additional important Internet Marketing related tasks for your website.</p>'),
|
||||
'install_security_review' => array(
|
||||
'#title' => t('[Optional] Install Security Review module.'),
|
||||
'#description' => t('The more popular your website becomes, the more important good security will be.'),
|
||||
'#default_value' => module_exists('security_review'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/security_review',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
),
|
||||
|
||||
// Paid services.
|
||||
'paid_services' => array(
|
||||
'#title' => t('Paid services (optional)'),
|
||||
'#description' => t('<p>There are many paid tools available to help you with your SEO and website maintenance. Here are some suggestions typically used by top Internet Marketing firms. At Volacci, we have tested and use all of these tools.</p>'),
|
||||
'mollom_spam_prevention' => array(
|
||||
'#title' => t('[Optional] Mollom spam prevention'),
|
||||
'#description' => t('<p>If your site will get heavy use from visitors creating accounts, commenting and/or creating content then use Mollom.</p>'),
|
||||
'register_page' => array(
|
||||
'#text' => t('Mollom website'),
|
||||
'#path' => 'http://mollom.com/',
|
||||
),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/mollom',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
'config_page' => array(
|
||||
'#text' => t('Configure'),
|
||||
'#path' => 'admin/config/content/mollom',
|
||||
),
|
||||
),
|
||||
'volacci_automatr' => array(
|
||||
'#title' => t('[Optional] Volacci Automatr™ marketing automation'),
|
||||
'#description' => t('<p>If you need marketing automation, lead scoring, advanced email marketing, and more, along with SalesForce or SugarCRM integration, then use <a href="@automatr_url">Volacci Automatr™</a>. If, for some reason, Automatr™ does not work for you, consider <a href="@marketo_url">Marketo</a> or <a href="@eloqua_url">Eloqua</a>.</p>', array(
|
||||
'@automatr_url' => $automatr_url = 'http://automatr.volacci.com/?utm_source=seo_checklist&utm_medium=backend&utm_content=text&utm_campaign=volacci_automatr',
|
||||
'@marketo_url' => 'http://www.marketo.com/',
|
||||
'@eloqua_url' => 'http://www.eloqua.com/',
|
||||
)),
|
||||
'automatr_website' => array(
|
||||
'#text' => t('Automatr website'),
|
||||
'#path' => $automatr_url,
|
||||
),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/automatr',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
'config_page' => array(
|
||||
'#text' => t('Configure'),
|
||||
'#path' => 'admin/config/marketing/automatr',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Extras.
|
||||
'extras' => array(
|
||||
'#title' => t('Extras (optional)'),
|
||||
'install_scheduler' => array(
|
||||
'#title' => t('[Optional] Install Scheduler module.'),
|
||||
'#default_value' => module_exists('scheduler'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/scheduler',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'install_read_more' => array(
|
||||
'#title' => t('[Optional] Install Read More Link module.'),
|
||||
'#default_value' => module_exists('read_more'),
|
||||
'project_page' => array(
|
||||
'#text' => t('Download'),
|
||||
'#path' => 'http://drupal.org/project/read_more',
|
||||
),
|
||||
'modules_page' => $modules_page,
|
||||
),
|
||||
'download_internet_marketing_whitepapers' => array(
|
||||
'#title' => t('[Optional] Download <a href="http://www.volacci.com/resources/whitepapers">free internet marketing whitepapers</a> from Volacci.'),
|
||||
),
|
||||
'link_to_volacci' => array(
|
||||
'#title' => t('[Optional] Link to <a href="http://www.volacci.com/">Volacci</a> to thank them for this awesome module.'),
|
||||
'#description' => t('Checking this item will cause a small link to appear at the very bottom of your website. You can disable it at any time by un-checking this box. We really appreciate it!'),
|
||||
),
|
||||
'send_feedback' => array(
|
||||
'#title' => t("[Optional] Send feedback on the Drupal 7 SEO Checklist or just say <em>Thanks!</em>, and we'll link to your web site from volacci.com."),
|
||||
'#description' => t("Remember to include your link information in your email. If you don't know why you should link with other websites, read <a href=\"http://www.volacci.com/why-links-help-seo\">Why links help SEO</a>."),
|
||||
'email_link' => array(
|
||||
'#text' => t('seochecklist@volacci.com'),
|
||||
'#path' => 'mailto:seochecklist@volacci.com',
|
||||
),
|
||||
),
|
||||
'read_drupal_6_seo_book' => array(
|
||||
'#title' => t('[Optional] Read Drupal 6 Search Engine Optimization by Ben Finklea.'),
|
||||
'buy_from_amazon' => array(
|
||||
'#text' => t('Buy from Amazon'),
|
||||
'#path' => 'http://www.amazon.com/gp/product/1847198228?ie=UTF8&tag=dvdcentral02&linkCode=as2&camp=1789&creative=390957&creativeASIN=1847198228',
|
||||
),
|
||||
'buy_from_packt' => array(
|
||||
'#text' => t('Buy from Packt'),
|
||||
'#path' => 'https://www.packtpub.com/drupal-6-search-engine-optimization-seo/book?mid/170909568gh3',
|
||||
),
|
||||
),
|
||||
'watch_drupalize_me_video' => array(
|
||||
'#title' => t('[Optional] Watch the free <a href="http://drupalize.me/videos/introduction-drupal-seo">Introduction to Drupal SEO</a> video from Lullabot.'),
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
return $definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_init().
|
||||
*/
|
||||
function seo_checklist_init() {
|
||||
if (_seo_checklist_volacci_link_is_enabled()) {
|
||||
drupal_add_css(drupal_get_path('module', 'seo_checklist') . '/seo_checklist.css');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_page_alter().
|
||||
*/
|
||||
function seo_checklist_page_alter(&$page) {
|
||||
if (_seo_checklist_volacci_link_is_enabled()) {
|
||||
$page['page_bottom']['seo_checklist_volacci_link'] = array(
|
||||
'#type' => 'markup',
|
||||
'#markup' => '<div id="seo-checklist-volacci-link"><a href="http://www.volacci.com/contact?utm_source=seo_checklist&utm_medium=footer&utm_campaign=volacci_seo">Drupal SEO</a></div>',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_theme().
|
||||
*/
|
||||
function seo_checklist_theme($existing, $type, $theme, $path) {
|
||||
return array(
|
||||
'seo_checklist_intro_tab' => array(
|
||||
'template' => 'seo_checklist_intro_tab',
|
||||
'variables' => array(
|
||||
'volacci_logo' => t('Volacci'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Default theme implementation for the SEO Checklist "Intro" tab.
|
||||
*
|
||||
* Available variables:
|
||||
* - $volacci_logo: An HTML image tag for the Volacci logo.
|
||||
*
|
||||
* @see template_preprocess()
|
||||
* @see template_preprocess_seo_checklist_intro_tab()
|
||||
* @see template_process()
|
||||
*/
|
||||
?>
|
||||
<h3>How to use the Drupal SEO Checklist</h3>
|
||||
<p>Please read these instructions to get the most out of your Drupal Search Engine Optimization efforts.</p>
|
||||
|
||||
<h4>Important warning</h4>
|
||||
<p>This checklist will not search engine optimize your site. It was written as a guide for Drupal SEO experts. If you need help with Drupal SEO best practices, the search engines' latest changes, your brand's target audience, or strategic marketing objectives, consider using a Drupal-specific Internet Marketing consultant like <a href="http://www.volacci.com/contact?utm_source=seo_checklist&utm_medium=backend&utm_content=text&utm_campaign=volacci_seo">Volacci</a> or ask your Drupal developer for a recommendation.</p>
|
||||
|
||||
<h4>Getting started</h4>
|
||||
<p>Each time you open the SEO Checklist, it will look to see if any tasks have already been completed. For example, if you've already turned on clean URLs then that item will be checked. You still need to click "Save" to time and date stamp the automatically-checked items.</p>
|
||||
<p>The best way to proceed is to start at the top and work your way through each tab until you're done, clicking save after each completed item.</p>
|
||||
|
||||
<h4>How it's organized</h4>
|
||||
<p>The sections are listed from most important to least important. The tasks in each section are also ordered from most to least important. A notable exception to this is the Tools section.</p>
|
||||
<ul>
|
||||
<li><strong>Tools:</strong> The tools section contains items that will help you get things done faster. They are not necessary for good SEO, but they are highly recommended.</li>
|
||||
<li><strong>Save Button:</strong> Be sure to click the save button after you check off each item. This will create a time and date stamp so that you can easily see when each task was completed.</li>
|
||||
<li><strong>Links:</strong> Many tasks have links next to them. Some links are to drupal.org, outside websites, or to admin sections of your own site. Links to outside resources will open in a new window.</li>
|
||||
<li><strong>Help:</strong> Some items have "More info" links. These will take you to appropriate documentation pages where you can read more about a module or important concept.</li>
|
||||
</ul>
|
||||
|
||||
<h4>A note about pre-release modules</h4>
|
||||
<p><em>Some recommended modules may not be considered ready for production websites. These modules are usually marked with "beta" or "dev" or "alpha" on Drupal.org. Please be very careful when installing any module—even those that have been fully tested and released—but be especially careful with dev, alpha, or beta modules.</em></p>
|
||||
|
||||
<h4>Credits</h4>
|
||||
<p>The Drupal SEO Checklist was created by <a href="http://drupal.org/user/46676">Ben Finklea</a>, the CEO of <a href="http://www.volacci.com/?utm_source=seo_checklist&utm_medium=backend&utm_content=text&utm_campaign=volacci_seo">Volacci</a> and a long-time Drupal community member. Development was paid for exclusively by Volacci. Special thanks to <a href="http://drupal.org/user/236758">Travis Carden</a> who created the <a href="http://drupal.org/project/checklistapi">Checklist API</a> and ported the Drupal SEO Checklist module to use it. </p>
|
||||
<p id="seo-checklist-intro-volacci">
|
||||
<a href="http://www.volacci.com/?utm_source=seo_checklist&utm_medium=backend&utm_content=logo&utm_campaign=volacci_seo"><?php print $volacci_logo; ?></a>
|
||||
<strong>Marketing Intelligence.</strong>
|
||||
</p>
|
BIN
sites/all/modules/contrib/seo/seo_checklist/volacci-logo.png
Normal file
BIN
sites/all/modules/contrib/seo/seo_checklist/volacci-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
Reference in New Issue
Block a user