Personal notes on Implementing autoPublishing mechanism to custom DB table within modx3.

A need.

  1. I have a custom database setup inside my modx3 install. Recently I started to think of adding a auto-publishing feature for this database, just as the modx3’s siteContent table is capable of doing.

Pre-requisite and assumptions.
1. MODX3 installation
2. Custom database table inside the MODX installation, which is created from modx database schema. I used migx’s package manager to create/modify one.
3. Let’s say that the class name of this dbtable is /MyDB/Model/Mydb
3. A custom table schema for modx to construct the table and associated code structure needs the following fields added to the schema. Note the data type for those date fields are all datetime. and not int(20) like original siteContent table fields for page resource. The difference will be dealt in the implementation code.

<field key="published" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
<field key="publishedon" dbtype="datetime" phptype="datetime" null="true" />
<field key="pub_date" dbtype="datetime" phptype="datetime" null="true" />
<field key="unpub_date" dbtype="datetime" phptype="datetime" null="true"/>

4. The auto-publish mechanism will mimic the existing code for modResource autopublishing mechanism. This reference code lives in core\src\revolution\modcachemanager.class.php. (for MODX2, the file is in core\model\modx\ folder)

5. The function I want is to toggle the record’s published flag based on records’ pub_date and un_pub date. It is still my implementation code (snippets) to filter records based on this flag to display data in the web site.

Two code segments have been written. The first is auto publishing functionality. The code heavily borrows from the aforementioned built-in autopublishing code, which is for page resources.

<?php
/**
 * @var $modx object
 * this code first check if auto_publish.cache.php returns the timestamp that is smaller than now timestamp.
 * if so, then there is at least one Mydb record that need to be acted on (either publish or unpublish))
 * and calls autopublish_mydb().
 */
/* first, check the cache value and compare it to current time */
$options = array(XPDO::OPT_CACHE_KEY => 'my_db'); 
//With this option, cache file is in /core/cache/my_db folder

$actionNeeded = $modx->cacheManager->get('auto_publish', $options);
$timeNow = time();
//No action is taken if cached timestamp is zero or bigger than today's timestamp, except when timestamp does not exist (null)
if (($actionNeeded>0 && $actionNeeded < $timeNow)  || $actionNeeded===null) autoPublish_mydb($modx, $options);

/** * @param $modx
 * @param array $options
 * @return void
 * this function check the Mydb table and alter record's published status.
 * if pub_date is less than current timestamp, and published is false then the record will be published and publishedon data
 * updated, and pub_date will be set to null
 * if unpub_date is less than current timestamp, and published is true then the record will be unpublished and publishedon date
 * and unpub_date will be set to null
 * record is scanned for new unpub/pub_date and cache file is refreshed.
 */
function autoPublish_mydb($modx, array $options): void
{

    $tblResource = $modx->getTableName('MyDB\Model\Mydb');

    $timeNow = time();  //get timestamp number of current date/time

    /* publish and unpublish resources using pub_date and unpub_date checks */
    $modx->exec("UPDATE $tblResource SET published=1, publishedon=pub_date, pub_date=NULL WHERE pub_date IS NOT NULL AND unix_timestamp(pub_date) < $timeNow");
    $modx->exec("UPDATE $tblResource SET published=0, publishedon=NULL,unpub_date=NULL WHERE unpub_date IS NOT NULL AND unix_timestamp(unpub_date) < $timeNow");

    /* update publish time file */
    $timesArr = array();
    $stmt = $modx->prepare("SELECT MIN(unix_timestamp(pub_date)) FROM $tblResource WHERE published = 0 AND unix_timestamp(pub_date) > 0");
    if ($stmt->execute()) {
        $value = $stmt->fetch(PDO::FETCH_NUM); // MIN operator query will return only one row. query is asking for only one column
        if ($value[0]) $timesArr[] = $value[0]; // that column is either empty or value. If value exists, push into array.

    }
    $stmt = $modx->prepare("SELECT MIN(UNIX_TIMESTAMP(unpub_date)) FROM $tblResource WHERE published = 1 AND UNIX_TIMESTAMP(unpub_date) > 0");
    if ($stmt->execute()) {
        $value = $stmt->fetch(PDO::FETCH_NUM);
        if ($value[0]) $timesArr[] = $value[0];

    }

    $nextEvent = (count($timesArr) > 0) ? min($timesArr) : 0;//select younger of timestamps if these exist. Otherwise, $nextEvent=0;
    /* cache the time of the next auto_publish event */
    $modx->cacheManager->set('auto_publish', $nextEvent, 0, $options);
}

Some points to note.

  1. dbtype for these dates are datetime. In original code, they are integer(timestamp).   MySql function unix_timestamp() is used inside the query to  convert them as needed.
  2. The function return type is changed from array to void. I thus removed all return values construction as I could not think of any use case in my usage scenario.
  3. This code, when invoked will fetch the cache file /core/cache/my_db/auto_publish.cache.php. The file will return a timestamp value or 0 or null. The location of the cache file is defined in $options array and separate from the system’s auto publish cache file.
  4. if timestamp returned is less than current timestamp but not 0 or timestamp returned is null (meaning there is no cache file) then it proceeds to auto_publish function Otherwise it will return without doing anything.
    1. Auto publishing function will do the following. They are basically two pdo queries.
      1. Publish all record that’s pub_date is less than current time, unset pub_date, set publishedon to pub_date.
      2. Unpublish all record that’s unpub_date is less than current tme. unset unpub_date and unset publishedon date
      3. set new cache value to minimum of remaining unpub_date and pub_date sets.
    2. In the original code, Unpublishing query is resetting both unpub_date and pub_date. I can not see any side effects on not unsetting pub_date so I left it out.

Now, when to invoke this code? The original Resource auto_publishing code is invoked whenever resource is accessed.

I originally added the code as a snippet to my site’s landing page so that the code will execute whenever somebody visit my site. But I also wanted to tryout the plugin functionality, so I saved the code as a plugin and named the plugin refresh_pub_date

Then in the system’s settings, I created a custom event. myCustomeEvent and enabled the refresh_pub_date plugin to this event.

The following code will invoke this event. So my snippet in the landing page is just that.

$modx->invokeEvent('refresh_pub_date',array())

Second code is used to check for pub_date, unpub_date after record save/update

<?php
/**
 * afterSave snippet for Mydb (migxdb configurator setup  'snippethook')
 *  the snippet will update auto_publish timestamp for the custom table
 * if unpub or pub date is smaller than the value already cached.
 *
 * migx provides the following variables
 * @var $modx object modx runtime object
 * @var $object object  object of the class being handled
 * @var $postvalues  array of posted values
 * @var $scriptProperties  mixed parameters, Includes all of the above.
 */

$result = '{"error":"","result":"success"}';
$options = array(XPDO::OPT_CACHE_KEY => 'my_db'); //define folder name for cache file
$timesArray = [];
$pub_date_ts = strtotime($postvalues['pub_date']); //retrieve pub_date datestamp
// the value is also retrievable from $object.  ie., strtotime($object->get('pub_date'));
if ($pub_date_ts) {
    $timesArray[] = $pub_date_ts;
} //push pub_date to times array if exists. boolean evaluation of the variable returns
// false if $pub_data_ts is empty, null, 0 or false

$unpub_date_ts = strtotime($postvalues['unpub_date']);
if ($unpub_date_ts) {
    $timesArray[] = $unpub_date_ts;
} // push unpublish date timestamp to the times array if exists

$current_ts = $modx->cacheManager->get('auto_publish', $options);
if ($current_ts === null and count($timesArray) == 0) {//In case of no cache file, meaning  the file is manually deleted somehow.
    $current_ts = time(); //set the time so auto_publish logic will run once and will set correct time if pub/unpub already existed.
    $modx->cacheManager->add('auto_publish', $current_ts, 0, $options);
}

if (count($timesArray) > 0) { //rewrite timestamp only if new TS is younger or the  current one is 0. Don't write otherwise
    $new_candidate_ts = min($timesArray);
    if ($new_candidate_ts < $current_ts || $current_ts === 0) {
        $modx->cacheManager->replace('auto_publish', $new_candidate_ts, 0, $options);
    }
}
return $result;

This code will be invoked when Mydb record is added/updated. Since I use migxDB to create a CMP for this DB table in the manager, migxDB custom configurator allows the easy way to attach the snippet to after save action.

{"aftersave":"mySnippet"}

If called this way, migxDB provides $postvalues array variable to allow access to posted data field that is needed to be convert to timestamp like so.

strtotime($postvalues['unpub_date']);

It also provides $object variable for the class object (including record fields that are not posted) So the same value can be retrieved with usual get method.

strtotime($object->get('unpub_date'))

Note: If I don’t use migxDB CMP configurator and write my own class processors extended from MODX processors, retrieval of the same value in aftersave hook in the update processor would have been

strtotime($this->getProperty('unpub_date'))

There was a bonus take away from this project

  1. I learned how to use MODX Cache file system. The main purpose of using the cache files must be obviously to eliminate a need of re-running of various codes on server side. However I can also do things like the following to record values of variables into the cache file for debugging purpose.

$options=array(XPDO::OPT_CACHE_KEY=>'debugstore');
$myvalues=print_r($varToCheck,true);
$modx->cacheManager->set('myVarvalues',$myvalues,0,$options);

“Why did I not think of this?” moment in MODX 3 snippet development with PHPStorm

This is one of those ‘Aha!’ moments.

MODX is one of CMSs (content management system) that I have been using for a long time to maintain my shogi site. Market penetration of this CMS is said to be 0.1%. As of this writing, 43% of of Web sites uses WordPress and no other CMS reach even 10% of market share. (source, w3techs.com . I actually think MODX penetration is much greater than this number, MODX does not leave big footprint to show it’s identity in front of web crawlers. -Many sites I know powered by MODX, including mine – were identified as non-CMS site by w3tech’s tool.— Nevertheless, there is no doubt WordPress dominates the CMS market)

Although both uses same language (PHP) for powering the site, MODX gives much more flexibility in site design but you need to be proficient with HTML and CSS (and JavaScript). In another word, MODX is a tool while WordPress is a product.

What I liked about MODX over WordPress at the time was a separation of PHP code and HTML. This was a long time ago so the situation might have changed on WordPress, but I have been happy with MODX since.

At the time, I also looked at Drupal and Joomra . All of them forces you to follow their interpretation of what website should be. MODX has no opinion on how you want to create Web site. You have a total freedom.

On the other hand, if the only thing you want to do with your site is blogging, there is no better solution than using WordPress.

I digressed. Back to the subject!

With a wealth of plug-ins available, your rarely need to code in PHP. When you do though, MODX separates a PHP coding part from HTML with a thing called Snippets. A snippet is then inserted in to HTML with a use of tag.

[[aSnippet]]

You can edit a snippet within MODX backend’s editor. With a plugin like ‘ACE’ there is a nominal amount of syntax checking to the PHP code. Unfortunately, I am being spoiled with convenience of IDE such as PHPStorm,

MODX backend, Snippet editor with ACE plugin

So there is a desire to be able to write a snippet code using PHPStorm and get benefits of auto-completion and methods hinting, strict error checking and warning.

Unfortunately, there is no plugin in PHPStorm for MODX or MODX plugn for PHPStorm.

When I google “MODX with PHPStorm”, there are several hits, Although none of them gave me a direct answer on what I wanted to do, I was able to put enough facts together and came up with a solution. The solution that was just waiting for me to assemble few known facts, that I have used all of them separately in the past!


1. Fact that PHPstorm can create a project using existing remote site contents, so that PHPStorm can pull all file setup from MODX site.

PHPStorm->File->New Project from Existing Files


2. Fact that PHPstorm can then start syncing file contents of my local project files to server files.

File sync options available in PHPStorm

Ok, but Snippet is stored in Database. the code is not in the file, but then,

3. Fact, MODX snippet code can be from a static file, meaning I can create a PHP file and feed it as a snippet to MODX by turning on “is Static” option and point to the file location

Is Static option is turned on for Snippet. Snippet is now fed from “static file”



Result: When I combine those 3 factors, I can create a snippet with a comfort of PHPStorm IDE environment.

Snippet now editable in PHPStorm
Snippet output on browser page, powered through MODX

What do I gain? Full context support and code hinting, as PHPStorm analyzes whole MODX site and figures out all variables and object and its methods being used inside MODX. I have to give credit to MODX development team for fully documenting source files. Thank you!

PHPstorm explains what getOption method is
PHPStorm autocomplete support in action.

You can also open the corresponding file by pointing to method and do control-b to drill down on function.

I edit a file in PHPStorm, and you either 1) turn on auto-sync between your local files and server files or 2) manually upload changed file to server. Then I can run and test the snippet with MODX backend immediately.

So all of the sudden, I feel like invincible. It will be very hard for me to make coding error. (Ok, logic error still possible)

Once Snippet development is done, you may switch off the ‘is static’ option and keep the snippet inside database, remove the php file from the system.

One thing that is kind of annoying is that by default, PHPstorm thinks $modx variable is undefined. The default setting on PHPStorm’s inspections on undefined variable is somewhat on conservative side. It will not even acknowledge variables from included file!. To mitigate this, you need to put a check on “Search for variable’s definition outside the current file”

PHP settings->Editor->Inspection->PHP->Undefined symbols->Undefined variable

It hurts to think that I have been using both PHPstorm and MODX for more than 10 years and I am figuring this out just now 🙁

Creating a Blog page inside MODX version 3 web site

MODX comes clean slate so there is no ‘ready to use’ provisions for creating Blog style site. One has to set it up using tools available in the CMS.

I took an easy way out for my production site by creating blog site using free wordPress service and then feed content to MODX page. with this, the only extra you will need is Spiefeed to handle rss feed from WordPress.  But for purist approach it is certainly possible to setup blog section within MODX using few extras.

There are several articles available for creating Blog sites using MODX.  The one shown in the modx official site is somewhat dated, but the article actually have a link to the instruction/article of more recent implementation of MODX blog site.  Link is here.   Better yet, this instruction is accompanied with a package published in the github which has all chunks, a snippet and a template packaged up to duplicate the blog site that the article discusses.  A demo site is also available to check out the feel of using this template. The document states that the demo utilizes MODX 2.7.  So can I use this setup with MODX 3 site? Furthermore, the instruction assumes you want the Site to be a blogging site. Can I add ‘Blog page’ to already existing MODX site? Answer to both questions are ‘Yes’ but we need to modify some parts.

To start, I could have created each chunk and template manually following the instruction but to reduce my typing effort, I went ahead and downloaded the demo package. I also installed dependent extras (getResources, getPage, Collections, and Tagger).  Previously, I did not have any of those installed. – I am using pdoTools  to get resources and get page. – <edit> It was fairly easy to change references to getResources and getPage to equivalent pdo* snippets.

Again, the setup instruction is written for MODX version 2.7 and the site I am setting up this blog structure is version 3.0.3.  Setup also assumes the top page is a site home page. There are several area in chunks and template that refers to [[++site_start]] and this need to be changed to point to correct Resource.  I want to have a blog page as a subpage of the site.

Looking through the template and snippets that I setup with the downloaded package , I found some more modifications were needed.

I will list out those changes.

  1. My server uses Nginx and it needs additional html tag to specify base url in <head> section of blog template html. Without it, Friendly URL won’t work correctly.
    <base href="[[++site_url]]">
  2. In MODX 3, [[*class_key]] does not return “modResource”.  It returns “MODX\Revolution\modResource”.
    This means I get “MODX/Revolution\modDocument” or “MODX\Revolution\CollectionContainer” in [[*class_key]] field depending on resource selected. Two sections of “Blog Template” stops working due to this.

    1. Template tries to pull in “jumbotron_CollectionContainer” or “jumbotron chunk based on [[$jumbotron-[[]*class_key]]] tag. This tag doesn’t work in MODX 3 as it returns [[$jumbotron-MODX/Revolution/….]] which does not exist and forward slash within chunk name is probably invalid anyway.
    2. Template tries to insert [[$blog_listing]] or [[$blog_article]] based on conditional modifier [[*id:is`[[++site_start]]`:then….]] but the blog_listing page is not at [[+site_start]] resources in my use case.
      1. To mitigate both problems, I have created a system setting [[++blog_start]] in custom namespace/area and set it to id of a blog home page resource I created. Then rewrote tags as follows.
        For jumbotron section
        [[[[*id:is=`[[++blog_start]]`:then=`$jumbotron-CollectionContainer`:else`$jumbotron-modDocument`]]]]
        For container section
        [[[[*id:is=`[[++blog_start]]`:then=`$blog_listing`:else=`$blog_article`]]]]
      2. Note: It will be probably not that difficult to create snippets and replace conditional tags here.
  3. getResources and getSnippet tags are used to aggregate child resources and parents properties are set to site home page [[++site_start]].   These needed to be changed to aforementioned [[++blog_start]].  These changes had to be made on $blog_listing chunk and $jumbotron-CollectionContainer chunk.
  4. @groups properties are hardcoded in calls to TaggerGetTags snippet.  The snippet is called from $aside chunk is setting @groups to 1 and the snippet called from $headder chunk is setting @groups to 2.  Make sure this agrees with your tagger group settings. I have first created ‘Category’ group and then ‘Archives’ group so I needed to change them to 2 and 1 respectively.
  5. Last and least 🙂   as this is just a demo template, links to “subscribe”, “search”, “Sign up”, “GitHub”, “Twitter” and “Facebook” are all mocked and pointing to itself.  You either need to remove or put actual link to them when modifying to suit your site design.

So, in order to create a Blog section within Modx 3 hosted website, using this instruction and elements in the github repo, One needs to be aware of:

  1. Modx version 3’s breaking change of the model class caused decision logics inside Blog_Template to stop working.  Rework of the logic flow was needed.
  2. Friendly url.  Nginx needs base href reference in head section.
  3. Creating a blog section other than home page location. Needed to change references to [[++site_start]] system settings to [[++blog_start]], a user created system setting
  4. Adjust the template design to fit with other area of site design.

Some more miscellaneous items to note.

  1. $blog_listing_item chunk, content placeholder has a modifier :firstp. There is a firstp snippet that is installed with the package.  I opted to replace it with ellipsis=`500` modifier to limit the content output to first 500 chars followed by ellipsis to suit my preference.
  2. Also in $blog_listing, getPage snippet uses @blog properties set. This set does not exists so the default property set will be used instead. I think idea is to create a blog property set within getPage snippet to override the default property settings in easy way, if customization is needed.

Commenting on the posts are not possible.  This need to be setup by yourself and will require Quip extra. that part is not covered by this article. One has to go back to modx documentation’s tutorial section.

 

IIS のurls rewrite を䜿っおmodxのfriendly url を有効にする。

たずえIISサヌバヌを䜿っおいおもHelicon Ape ずいうツヌルをIISに組み蟌めば、modxに぀いおくる.htaccess をそのたた䜿っのfriendly url を掻甚するこずはできおいるわけだが、今回はIISのURL rewrite module (IIS 7 の堎合は別途ダりンロヌドで組み蟌む)を䜿っお同じこずをやっおみた。

IISのGUIでルヌルを䜜る䜜業になるが、.htaccess の蚘述を参考にしおやっおみたら動くようになった。

modx に付属する.htfile でfurl に関連するずころは 以䞋の郚分ず思われる

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

これを解釈するず
条件ずしお、芁求されおいるファむル名がファむルずしお存圚しない、か぀
フォルダヌずしおも存圚しない堎合、それは぀たり動的に生成されるHTMLペヌゞなので、
以䞋の曞き換えルヌルを適甚する。
曞き換えルヌル 枡された文字列を以䞋のパタヌンにしお加工する
“index.php?q=$1”
さらに 埌ろにク゚リヌが぀いおいる堎合はそのたた枡し、 䞋流の凊理を行わない。

IISのGUI䞊のRuleでは これを Inbound rule ずしお远加するが、その内容は以䞋のごずくなる。

Matches Pattern, “Regular expression”
“^(.*\.html)$” <= RewriteRule の最初の郚分*1 Conditions : "Matches All" {REQUEST_FILENAME} "file does not exist"  {REQUEST_FILENAME} "Directory does not exist" Action type "rewrite" index.php?q={R:1} <= RewriteRule index.php?q=$1 に匹敵 Append ques : yes <= [QSA] に匹敵 Stop Processing: yes <= [L] に匹敵 圓たり前ながら、同じ条件を蚘述しおいるので、それほど迷わずにできた。 はたりそうになったずころはRegular Expression の郚分で.htmlを明瀺しおいる郚分。これをやらないずloopしおしたう。 ほかのずころの条件付けでもっず綺麗に蚘述できるかもしれない。 ずりあえず、これでOK

subfolder がアクセスできない IIS

Modxで運甚するサむトであるサブフォルダヌだけアクセスできない。ManagerからはFile Treeで芋るこずができるのだが、フォルダヌの䞭のむメヌゞファむルの画像をレンダリングしない。 フロント゚ンドから芋るず、むメヌゞファむルの郚分でサヌバヌ゚ラヌになっおいるようだ。

web.configで゚ラヌ出力をONにしおみるず、゚ラヌで以䞋を衚瀺した。

Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level.  This error can be caused by a virtual directory not being configured as an application in IIS.

Source Error:

 

Line 36:             に、ASP.NET で䜿甚されるセキュリティ認蚌モヌドの構成
Line 37:             を有効にしたす。-->
Line 38: 		<authentication mode="Windows"/>
Line 39: 		<!--
Line 40:             <customErrors> セクションは、芁求の実行䞭にハンドル


さお、これをどう解釈すればよいのだろうずくよくよ考えるよりは、グヌぐる怜玢をするのが䞀番で、この蚘述に行き圓たった。

芁玄するずこういうこずだ。IISサヌバヌで

” It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level.” ずいう゚ラヌ衚瀺が出る理由には二぀ある。

ひず぀はアプリケヌションをちゃんずバヌチャルダむレクトリずしお蚭定しおいないこず。 これは蚭定を芋盎せばよい。

もうひず぀は、サブフォルダヌにweb.configがルヌトのweb.configずバッティングするための䞍具合、

で、今回の堎合、サブフォルダのファむルがアクセスできない、ずいうこずで、埌者だず考え探したらやはりsubfolderに入っおいたweb.configがルヌトのWebFoldeを発芋。 考えおみればあたりたえで、このサブフォルダヌ、以前のテストでスタティックなサむトをやはりIISで運営しおいたのをmodxでダむナミックなサむトにしようずそのたたコピヌしおいたのだ、から圓然web.configもコピヌしおしたっおいた、ずいうわけだった。

解決策ずしおは、このサブフォルダヌのweb.configをバッサリ削陀。

 

たくもう。
埌蚘サブフォルダヌにweb.configが存圚するこず自䜓、ありうる話フォルダヌごずに曞き換えのルヌルを倉えるなど。たずえばOutboundのurl情報からサブフォルダヌ情報を取り陀く なのでサむトの蚭定によっおは必芁なのだが、IISのGUIを䜿っおいれば、このマネヌゞメントはちゃんずなされお調和のずれたweb.configが䜜成される。
 

ModX cloud

Modx cloud ずいうのをMODXのサむトで盛んに宣䌝しおいたのは知っおいたのだが、前回フォヌラムにアクセスした際、「タダでアカりントをゲット」みたいなティッカヌが衚瀺され、それなら登録だけでも、ずMODXCloud.comに登録しおみれば、 Dev Siteを䞀本無料本無料で䜿えるこずが分かったので、早速sandbox サむトを䜜っおみた。

これは䟿利だ。サヌバヌの構築を気にせず、簡単にサむトをリセットしたり、バヌゞョンアップができるようだ。 スニペットやプラグむン、新しいアむデアを詊しおみたいずきに気軜にアクセスしおむロむロ無茶やれそうな堎所ができた。

MODXずいうのはコアを開発しおいる人が基本的に二人なので、開発が现い。 その分、コニュニティで協力しおやらなければならないのだろうが、MODXCLOUDのプロバヌゞョンは他のプロバむダヌよりも高めの料金蚭定なので、Financial なサポヌトをするのも 芚悟がいる。 バヌゞョンアップの節目節目にdonationをするのが今の自分にできるこずだ。

modx Snippet を改良したずきのメンテ法

昔に䜜ったmySnippet ずいうスニペットがあるずする。 そしおそれを既にサむトのい䜕か所にも䜿っおいるような堎合。

改良バヌゞョンでmySnippetずいうコヌドを䜜っお、眮き換えようずしたずきに、党おのリ゜ヌスのレファレンスを曞き換える手間を省くために、mySnippetを以䞋の2行に曞き換えお、mySnippetを呌んだずきには実はmySnippet2を実行するようにしおしたう。


runSnippet('mysnippet2',$scriptProperties);
return $output

きもmodX のrunSnippetずいうAPIを呌び出しお、パラメヌタヌアレむには$scriptProperties ずいうmodxのシステムアレむ倉数を䜿えばmySnippetのプロパティセット及びタグ内郚に䜿ったパラメヌタヌがすべお新しいスニペットで䜿える。

簡単、確実。

modx をコマンドラむンからアップグレヌドする。

珟圚 Official にリリヌスされおいるmodxのバヌゞョンは2.2.5-pl だが、結構バヌゞョンアップが煩雑に行われおいお、そのたび、バグが取れたり、䜿い勝手がよくなっおきおいお、たすたす気にいっおきたりするわけだけれども、ファむルサむズもだんだんず倧きくなっおきおおり、アップグレヌドするたびに、zipファむルをたずは自分のパ゜コンにおずしおきおから解凍し、倖郚のhost server にすべおをftp で転送するずなるず、やたらに時間がかかっおしたう。

しばらく前にhost 偎にsshでログむンし、コマンドラむンからファむル展開を盎接行う方法を説明しおいるサむトを芋぀け、この方法を䜿っお重宝しおいるので、ここに蚘しおおく。

オリゞナルの英文ペヌゞはこちら

䞊蚘ペヌゞはEvoluation 甚に蚘述しおあるが、revolution でも䜜業は同じ。

たずはホストサヌバヌのssh アクセスを有効にしおコマンドラむンを䜿えるようにしおおくのが第䞀歩。 自分の䜿っおいるホストはコン゜ヌルパネルからsshを有効にするだけで、コン゜ヌルパネル甚のナヌザヌネヌムずパスワヌドでアクセスできるようになった。パ゜コンがLinux であれば、タヌミナルから盎接sshを起動、 Windows の堎合はPuTTYずか、CygWinなどを実装しおおく必芁がある。

ssh username@server.com

First things firstで、たずは 既存のmodxファむルをサヌバヌのrootにバックアップしおおく。 sshでログむンするず最初はrootフォルダヌにいるのだが、そのrootの䞋にpublic-htmlずいうフォルダヌがあり、web アクセスができるのはこのpublic-html フォルダヌから䞋の階局のみずいう仕組みになっおいるのを利甚しおバックアップをweb からはアクセスできないrootフォルダヌにzipしお保存しおしたおうずいうわけ。(䞋のコマンドでは’~’ でroot指定しおいる

zip -r ~/my-modx-folder.bk.`date "+%Y.%m.%d.%H.%M.%S"`.zip my-modx-folder

これでrootフォルダヌ䞊に my-modx-folder.bk.date_of_backup.zip ずいうようなアヌカむブファむルができる。

次にmysqlのデヌタベヌスも念のためバックアップ。䜿っおいる環境によっお異なるず思うので説明省略

次にmodxの最新版をダりンロヌドしおくる。
これはmodxの最新版のダりンロヌドのペヌゞに行っお、ダりンロヌドのリンク先をコピヌし、これをタヌミナル画面䞊のwget コマンドに匵り付けるこずになる。

wget path-to-the-latest-modx.zip

これをサヌバヌ内郚で解凍

unzip modx-2.2.5-pl.zip

modx-2.2.5-pl ずいうフォルダが䜜成され䜕千ずいうファむルが展開される。

これをmy-modx-folder にコピヌするのは cp -r コマンドを䜿うわけだが自分の環境ではcp にAlias がかかっおいるらしく、f parameter を぀けおやらないずいちいち䞊曞きしたすか、ずきいおくるはめになる。
cp -rf modx-2.2.5-pl/* my-modx-folder
数分でファむルの展開が終了する。
次にmy-modx-folder/core/config/config.inc.phpのパヌミッションを倉曎しお曞き換え可胜にする

cd core/config
chmod 666 config.inc.php

あずはブラりザでsetupを実行するだけ。

my-domain.com/setup

 

78分で党䜜業が終了するはず

わかった぀もりになっおはいけない

地䞋宀においおあるPCのWEBServerはIISで動いおいる。 いや、Windwos7がはいっおいたので、気軜な気持ちでIISを導入し、うごかしおみたら、蚭定が簡単だったのず、PHPのサポヌトが意倖ず充実しおいたので、サヌバヌずしお䜿うこずにしたのだ。すでに2幎ほど支障なく動いおいる。

もっずも、アプリケヌションはPHPで動くModXだ。 asp、aspx ベヌスではない。Visual Studioもタダだし起動画面たでは芋おみたのだが、C#もVBも芚える぀もりがなく、 結局JavaScriptやCSSだけでWEBサむトを構築できるPHPベヌスのModXでうごかしおいる。

ひず぀だけ問題があるずしたら、IISベヌスではFriendly URLがサポヌトされおいないこず。 IIS自䜓はFURLはサポヌトしおいるのだが、別途蚭定しなければならない。これがApache ベヌスのサヌバヌではModXに付属しおくる.htaccess ファむルで簡単に察応できる。

䞖の䞭よくしたもので、IISでこの.htaccess をそのたた䜿えるツヌルが存圚する。 Helicon Ape ずいうナヌティリティなのだが、サヌバヌ本たでは無料バヌゞョンでサポヌトされおいる。 これを入れお、ModX偎のFriendly URLのシステム蚭定をOnにするだけで、FURLが有効になる。 するずそれたでは
http://mysite.org/index.php? id=36
などずいう味気ないURLが
http://mysite.org/this_pabe.html
ずいう”読みやすく芚えやすいFriendlyな”アドレスに曞き換わる。

この組み合わせで半幎ほど快適に䜿っおきたのだが、ある日突然うごかなくなっおしたった。 なぜか、最初はわからなかった。
で、いろいろ調べた結果わかったのが、IISの蚭定。このサむト、.net frameworkを぀かっおいないのだからいらないだろうず、.netのサポヌトをIISのメニュヌから前の日に倖しおいた。倖した途端に動かなくなったわけで、ホヌムペヌゞ自䜓はPHPがきちんず動いお衚瀺するが、リンクが党郚だめになったのは、芁するにApeが䜜動しおいなかったので、
http:/mysite.org/this.page.html
を Apeが以䞋に倉換、
http://mysite.org/index.php ?q=”this page.html”
さらにこれをModXが読み蟌んで
http://mysite.org/index.php ?id=36 に倉換
ずいう曞き換えができなくなっおいたわけ。 ぀たりApe 自䜓はIISの.net frameworkの䞊で動いおいたわけだ。

で、あらためおHeliconのペヌゞを読んでみれば

Helicon Ape is implemented as managed IIS 7 module and can be installed as .NET module on any ASP.NET-compatible IIS version. It works transparently for both server and client and can even be installed on a shared hosting account without administrative access.

.NET module だず、しっかり曞いおある。おい

わかった぀もりになっおいおはいけたせん。

ModX Revolution2.2 ずIIS の盞性

modXの2.2 がリリヌスされおからヶ月ほど経ったが、今回自宅のサヌバヌに導入しおみた。 ホストサヌビスのほうで運甚しおいるサヌバヌはApache なのだが、自宅はWindowsに実装したIISだ。

で、むンストヌルしおマネヌゞャ画面に行っおみたら、なんずリ゜ヌスツリヌがない。メニュヌずお知らせは衚瀺されるのだが メニュヌをクリックしおも空癜の画面が出おくるばかり。 ログアりトもできない。

むンストヌルを繰り替えしおみたり色々やっおみたが拉臎あかず

サポヌトフォヌラムに行っお2.2の゚ントリヌを眺めおみるず、結構類䌌の問題が発生しおいる暡様、 その䞭で

「どういう蚳か、IISではJS ずCSSを圧瞮するずうたく行かない」ずいう蚘述があり、察策ずしおはPHPMyadminなどで盎接mysqlデヌタにアクセスし、System settingの圓該項目を圧瞮ありからなしに倉曎すればよい、ずの曞き蟌みを芋぀けた。

もっずはやく蚀っおよ。

早速SQLBUDDYでデヌタ内容を曞き換えお解決。