WindowsLiveWriter Archive

APR
17

WPCustomFieldsEditor更新

Published:2009-04-17 17:13:29 UTC

動かなくなったまま放置していたWPCustomFieldsEditor、修正したものと差し替えました。WPCustomFieldsEditorは、その名の通り、WordPressのカスタムフィールドを修正するためのWindows Live Writerのプラグインです。

Windows Live Writerがアップデートしたら動かなくなっていたのは、横着してWLWの内部的なアセンブリを直接参照した時点でまぁ予見出来た話ではあるのですが・・・。今回はちゃんとリフレクションで書き直しております。また、WordPressとのやり取りも、WP-XML-RPCLib2で行うように変更しました。

WPCustomFieldsEditor.zip

ソースコード:WPCustomFieldsEditor.sln.zip

OCT
4

セルクマプラグイン

Published:2008-10-04 13:08:04 UTC

これは何?

エントリの投稿時に、はてなブックマークに当該エントリを保存する機能を、Windows Live Writerに追加するプラグインです。

ダウンロード

SelkmaPluginSetup.zip

動作環境

  • Microsoft Windows XP SP2 以降または Windows Vista(Windows Live Writerに準拠)
  • Microsoft .NET Framework 2.0以上
  • Windows Live Writer Beta(Build14.0.5025.904)

※現在、Writer Zoneで配布されているTechnical Preview版では、おそらく動作しなくなっています。ご注意ください。

インストール方法

ダウンロードしたファイルを展開してsetup.exeを実行してください。

アンインストール方法

コントロールパネルのプログラムの追加と削除からSelkmaPluginを選択し削除してください。

操作説明

imageエントリの投稿を行うと、スプラッシュウィンドウに続いてブックマークコメントの編集画面が現れます。[OK]を押せばブックマークされ、[Cancel]を押せばエントリの投稿だけが行われます。


image また、初回実行時には、ブックマークする際に使うはてなのアカウントを尋ねるダイアログが表示されます。使いたいアカウントのユーザー名とパスワードを正しく入力してください。設定したはてなのアカウント情報を後で変更したい場合は、WLWのオプションのプラグインの項から編集することが出来ます。

謝辞

はてなブックマークに追加する処理の部分は、JZ5さんのはてブをプログラムから追加するというエントリのコードを参考にさせて頂きました。有難うございました。

ソースコード

SelkmaPluginSln.zip

更新履歴

  • 2008-10-04 イニシャルリリース
OCT
2

WPCustomFieldsEditor書き直し

Published:2008-10-02 01:18:04 UTC

先日WPCustomFieldsEditorが正常に動作しないというコメントがあり、良い機会なのでBugFixも兼ねてWordPressとXML-RPC APIを通じて遣り取りを行う部分を書き直してみました。これまでは文字列連結でリクエスト用のXMLを捻り出してなんとか凌いでいたのですが、WindowsLive.Writer.CoreServices.dllにXML-RPC Clientライブラリがあるのを見つけたので、今回はそのお世話になることに。WLWのプラグインを作る分には怒られないんじゃないかな・・・?

で、以下が書き直した後のOnPostPublishメソッドのソースコード。

        public override void OnPostPublish(IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
            Blog blog = new Blog(postEditorForm.CurrentBlogId);
            PropertyInfo propInfo = blog.GetType().GetProperty("BlogClient", BindingFlags.NonPublic | BindingFlags.Instance);
            IBlogClient blogClient = (IBlogClient)propInfo.GetValue(blog, null);

            WordPressClient xmlRpcClient = blogClient as WordPressClient;
            if (xmlRpcClient != null && !publishingContext.PostInfo.IsPage) {

                const string userAgent = "WPCustomFieldEditor";

                XmlRpcString postId = new XmlRpcString(publishingContext.PostInfo.Id);
                XmlRpcString userName = new XmlRpcString(xmlRpcClient.Username);
                XmlRpcString password = new XmlRpcString(xmlRpcClient.Password);

                HttpRequestFilter filter = delegate(System.Net.HttpWebRequest request) {
                };
                XmlRpcClient client = new XmlRpcClient(blog.PostApiUrl, userAgent, filter, xmlRpcClient.Options.CharacterSet);
                XmlRpcMethodResponse res = client.CallMethod("metaWeblog.getPost", postId, userName, password);
                if (res.FaultOccurred) {
                    showErrorMessage(dialogOwner, res.FaultString);
                    return;
                }

                XmlNodeList customFieldsNodes = res.Response.SelectNodes("//struct/member[name="custom_fields"]/value/array/data/value/struct");

                CustomField[] customFields = new CustomField[customFieldsNodes.Count];
                for (int i = 0; i < customFieldsNodes.Count; i++) {
                    XmlNode item = customFieldsNodes[i];
                    customFields[i] = new CustomField();
                    customFields[i].Id = item.SelectSingleNode("member[name="id"]/value/string").InnerText;
                    customFields[i].Key = item.SelectSingleNode("member[name="key"]/value/string").InnerText;
                    customFields[i].Value = item.SelectSingleNode("member[name="value"]/value/string").InnerText;
                }

                WPCustomFieldsEditor fieldEditor = new WPCustomFieldsEditor(customFields, this.Options);
                DialogResult result = fieldEditor.ShowDialog(dialogOwner);
                if (result == DialogResult.OK) {

                    Func getRpcMemberValue = delegate(string name) {
                        return res.Response.SelectSingleNode("//struct/member[name="" + name + ""]/value/*").InnerText;
                    };

                    XmlRpcStruct[] cv = new XmlRpcStruct[fieldEditor.CustomFields.Length];
                    for (int i = 0; i < cv.Length; i++) {
                        CustomField sourceItem = fieldEditor.CustomFields[i];
                        List<XmlRpcMember> structMember = new List<XmlRpcMember>();
                        if(!string.IsNullOrEmpty(sourceItem.Id)){
                            structMember.Add(new XmlRpcMember("id", sourceItem.Id));
                        }
                        if(!string.IsNullOrEmpty(sourceItem.Key)){
                            structMember.Add(new XmlRpcMember("key", sourceItem.Key));
                        }
                        structMember.Add(new XmlRpcMember("value", sourceItem.Value));
                        cv[i] = new XmlRpcStruct(structMember.ToArray());
                    }

                    XmlRpcStruct content = new XmlRpcStruct(new XmlRpcMember[]{
                        new XmlRpcMember("title",getRpcMemberValue("title")),
                        new XmlRpcMember("description",getRpcMemberValue("description")),
                        new XmlRpcMember("mt_text_more",getRpcMemberValue("mt_text_more")),
                        new XmlRpcMember("mt_allow_comments",getRpcMemberValue("mt_allow_comments")),
                        new XmlRpcMember("mt_allow_pings",getRpcMemberValue("mt_allow_pings")),
                        new XmlRpcMember("mt_keywords",getRpcMemberValue("mt_keywords")),
                        new XmlRpcMember("wp_slug",getRpcMemberValue("wp_slug")),
                        new XmlRpcMember("wp_password",getRpcMemberValue("wp_password")),
                        new XmlRpcMember("wp_author_id",getRpcMemberValue("wp_author_id")),
                        new XmlRpcMember("mt_excerpt",getRpcMemberValue("mt_excerpt")),
                        new XmlRpcMember("mt_keywords",getRpcMemberValue("mt_keywords")),
                        new XmlRpcMember("custom_fields",new XmlRpcArray(cv))
                        });
                    XmlRpcBoolean isPublish = new XmlRpcBoolean(publish);
                    
                    res = client.CallMethod("metaWeblog.editPost", postId, userName, password, content, isPublish);
                    if (res.FaultOccurred) {
                        showErrorMessage(dialogOwner, res.FaultString);
                        return;
                    }
                }


            }


        }

WLWによるエントリの投稿が終わった後に呼び出され、サーバーからその投稿されたエントリのデータを取得し(20行目付近)、それに基づいてカスタムフィールドのデータを付加したエントリのデータを作成して投げ直すという流れ。

Windows Live WriterのプラグインをWLWに登録する場合、

HKEY_LOCAL_MACHINESOFTWAREWindows LiveWriterPluginAssemblies
HKEY_CURRENT_USERSOFTWAREWindows LiveWriterPluginAssemblies

以上の二つのレジストリのいずれかの下にアセンブリの場所を示す文字列値を追加すれば良い、とMSDNでは書かれているのですが、これは間違いで、

HKEY_LOCAL_MACHINESOFTWAREWindows Live WriterPluginAssemblies
HKEY_CURRENT_USERSOFTWAREWindows Live WriterPluginAssemblies

でなければならないようです。WPCustomFieldsEditorのバグフィックスの過程で気づきました。MSDN…。

SEP
23

InsertTegakiPlugin v1.1.0.0

Published:2008-09-23 19:58:45 UTC

InsertTegakiPlugin v1.1.0.0がリリースされています。これは個人的に気に入っているプラグインで、

          ____ /        / \   /\  キリッ / .     / (ー)  (ー)\ /     /   ⌒(__人__)⌒ \ なぜなら、AAを画像化して /     |      |r┬-|    | 環境によらず崩れないように出来るからです。 /      \     `ー'´   /  /     ノ            \    /  /    / ̄ ̄\ /  /   _ノ  \ /  |    ( ●)(●)  ぜったい / . |     (__人__)  使い方間違ってるだろ /   |     ` ⌒´ノ / .  |         }  ミ        ピコッ / .  ヽ        } ミ  /\  ,☆____ /    ヽ     ノ    \  \ /     \ /    /    く  \.  /\/ ─    ─ \  てへw /    |     `ー一⌒)  /   (●)  (●)  \ /     |    i´ ̄ ̄ ̄ \ |      (__人__)     | /                \_   ` ⌒´    / /                 /          \

daruyanagiさん、変な使い方してごめんなさい。
でもalt属性も別に編集できるようにしてくれるとありがたいです(コラ

SEP
23

BlogThisPluginよもやま話

Published:2008-09-23 18:52:11 UTC

image とりあえずWindows Live Photo Galleryのプラグインを作るぞー!ということでサクッと作ってみたBlogThisPlugin。書くことが無さ過ぎて、前のエントリは無駄に英語で書いてみたりしてみましたが、このエントリでは、このBlogThisPluginを作るにあたってWindows Live Photo Gallery Publishing Plug-in Platformを調べて分かったことを記したいと思います。ちなみに、Windows Live Photo Gallery Publishing Plug-in PlatformとはWindows Live Photo Galleryの拡張をホストする機能のことで、これを使えば「投稿」メニューに独自の項目を追加することが出来ます。

Windows Live Photo GalleryのPublishing Plug-in(以下Publishing Plug-in)の作成はIPublishPlugin Interfaceを実装したクラスを作成し、そのアセンブリのパスやIPublishPlugin Interfaceを実装したクラスの完全限定名などをPublishing Plug-in Registry Settingsに従ってレジストリに登録すれば出来上がり、という流れです。属性を活用していたWLWに比べると、ちょっとレガシーですね。IPublishPlugin Interfaceを実装するにあたってはPublishing Plug-in Architectureを参照し、どのメソッドがどのタイミングで呼び出されるかを確認するとよいでしょう。メソッドの呼び出しの合間に、Live Photo Galleryが進捗状況を表示するダイアログを挟みこんできたりするので…。また、Publishing Plug-in Platformは、IPublishPluginのメソッドを呼び出す際、IPublishPlugin Interfaceを実装したクラスのインスタンスを使いまわさず、インスタンスを生成し直してくる場合があるので、その点にも注意した方がよいでしょう。

折角なので、BlogThisPluginのソースコードを晒してみます。

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Microsoft.WindowsLive.PublishPlugins;
using WindowsLive.Writer.Api;

namespace SharpLab.BlogThisPlugin {
    public class PublishPlugin : IPublishPlugin{

        public bool HasPublishResults(System.Xml.XmlDocument sessionXml) {
            throw new NotImplementedException();
        }

        public bool HasSummaryInformation(System.Xml.XmlDocument sessionXml) {
            throw new NotImplementedException();
        }

        public void LaunchPublishResults(System.Xml.XmlDocument sessionXml) {
            throw new NotImplementedException();
        }

        public bool PublishItem(System.Windows.Forms.IWin32Window parentWindow, string mediaObjectId, System.IO.Stream stream, System.Xml.XmlDocument sessionXml, IPublishProperties publishProperties, IPublishProgressCallback callback, System.Threading.EventWaitHandle cancelEvent) {
            throw new NotImplementedException();
        }

        public void ShowSummaryInformation(System.Windows.Forms.IWin32Window parentWindow, System.Xml.XmlDocument sessionXml) {
            throw new NotImplementedException();
        }

        public bool ShowConfigurationSettings(System.Windows.Forms.IWin32Window parentWindow, System.Xml.XmlDocument sessionXml, System.Xml.XmlDocument persistXml, IPublishProperties publishProperties) {
            if(!WriterApplication.IsInstalled){
                System.Windows.Forms.MessageBox.Show(parentWindow, "Windows Live Writer is not Installed.", "BlogThis Plugin",
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
            else{
                blogThis(parentWindow, sessionXml);
            }
            return false;
        }

        private void blogThis(System.Windows.Forms.IWin32Window parentWindow, System.Xml.XmlDocument sessionXml) {
                XmlNodeList items = sessionXml.SelectNodes("/PhotoGalleryPublishSession/ItemSet/Item[PerceivedType="image"]/FullFilePath");
            if(items.Count==0){
                System.Windows.Forms.MessageBox.Show(parentWindow, "Please select at least one image.", "BlogThis Plugin",
                    System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
                return;
            }
            string[] fileNames = new string[items.Count];
                for (int i = 0; i < items.Count; i++) {
                    fileNames[i] = items[i].InnerText;
                }
                WriterApplication writer = new WriterApplication();
                writer.BlogThisImageFileList(null, fileNames, null);            

        }
    }
}

うわぁNotImplementedExceptionばっか。。。BlogThisPluginでは、最初に呼び出されるShowConfigurationSettingsメソッドの段階でfalseを返してしまうことにしました。これは、写真のアップロードを直接するわけではないため、Live Photo Galleryの挟みこんでくるダイアログが邪魔だったからです。まぁ、こういうのもありかもね、ということで。そのうちにPublishing Plug-inのアーキテクチャに沿ってWordPressにXMLRPC-APIを使って画像やらを投稿するプラグインも試作してみたいと思います。

ちなみにソリューション全体はこちらにアップしています。

http://depot.sharplab.net/CSharp/WLWPlugin/BlogThisPluginSln.zip

真っ当に実装されたMS謹製のFlickerのプラグインより簡単に弄れるたたき台としてどうぞ。

SEP
23

BlogThisPlugin

Published:2008-09-23 16:59:43 UTC

What’s this?

imageThis is a simple plugin that adds “BlogThis” menu to Windows Live Photo Gallery. You can click this menu and launch Windows Live Writer with a new BlogThis post that contains selected images.

Download

BlogThisPluginSetup.zip

System Requirements

  • Microsoft Windows XP SP2 or later, or Windows Vista
  • Minimum 512 MB of RAM (based on the profile of Windows Live Photo Gallery)
  • Microsoft .NET Framework 2.0 or higher
  • Latest version of Windows Live Photo Gallery
  • Latest version of Windows Live Writer

imageHow to install

Please unzip BlogThisPluginSetup.zip, and execute setup.exe.

How to uninstall

Please uninstall by “Add or Remove Programs” utility in the Control Panel.

Releases

2008-09-23 Initial version released.

SEP
18

imageWindows Live Wave3のBetaアプリ群がDL出来るようになった、ということなので、早速Windows Live Writerの新版を入れてみた。Wave 3: Windows Live Writer – A First Look – LiveSide – News blog – LiveSide – Windows Live news and interviewsというレビュー記事によれば、CTP版からの大きな機能追加はされていない模様。実際、プラグイン関係でも、オブジェクトブラウザでWindowsLive.Writer.Api以下を覗いて見ても特に違いは見つけられなかった。但し、WLWの動画の貼り付け機能の動画の投稿先/既存の動画の選択元のオプションとしてYouTubeが追加されたのは結構便利かも。

しかし画面のデザインはWave 3に合わせる形で、変更が加えられたようだ。CTP版からGUI要素の位置には変更がないようだが、色遣いや区切り線の入れ方が変わっている。正直なところを言うと、CTP版の頃の方が自分は良かった…。


image

これまでPublish Notification Hook プラグインで、投稿前にエントリの内容を書き換えられないか何度か試行錯誤してきましたが(publish notification hooksでpost内容を安全に書き換えるには – SharpLab.など)、

WLW 自体は書き換えられることを想定してないので、プラグインから書き換えても投稿後にエディタ中の表示は変化しません。

Publish Notification Hook プラグイン 値の書き換え-katamari.wankuma.com

という問題などに行き当たったりしてきました。そこで、今回はエントリのメタ情報を編集するためのGUIコントロールのインスタンスのプロパティを弄ることで画面の書き換えも行ってみました。適用できる部分は限られ、根本的な解とは言い難いですが、参考まで。

今回は例としてタグの設定を行ってみたいと思います。

Textboxのインスタンスの取得方法

さて、操作の対象としたいWLW下部のプロパティパネルにあるタグ設定用のTextBoxですが、これのインスタンスのNameプロパティの値が分かれば、

private static Control findControlByName(Control control, string controlName) {
    foreach (Control cChild in control.Controls) {
        if (cChild.Name == controlName) {
            return cChild;
        }
        if (cChild.HasChildren) {
            Control returned = findControlByName(cChild, controlName);
            if (returned != null) {
                return returned;
            }
        }
    }
    return null;
}

上のようなメソッドを用意することでトップレベルのコントロールから包含関係を伝ってインスタンスを取得することが出来ます。

ではそのNameプロパティの値ですが、今回はWLWのプラグインにアタッチさせたVisual Studioのローカル変数ウィンドウからコントロールのツリー構造を辿って調べる方法ではなく、Managed Spyというツールを使って調べる方法を紹介してみたいと思います。

Managed Spy

ManagedSpy は、別プロセス内のマネージドコントロールのプロパティおよびイベントの表示・編集を行えるツールで、MSDN Magazineの06年4月号の記事原文、但しツールへのリンク消滅)と共に配布されています。SPY++のマネージド版という説明がよくなされているようですが、自分はSPY++を触ったことがないのでよく分かりません><。

なお、別プロセス内のマネージドコントロールにアクセスする方法はmanaged C++で書かれたManagedSpyLibというライブラリが提供しているようです。ソースコードの提供もされているので、興味があれば覗いてみると良いのではないでしょうか。

話をManaged Spyを使ったWLWのコントロールの調査に戻します。WLWを起動後、Managed Spyを起動すると、 image図のようなウィンドウが開きます。左側のツリービューには起動中のマネージドアプリの一覧が表示され、ツリーを展開してゆくことでコントロールのツリー構造を調べてゆくことが出来ます。選択しているツリーのノードがどのコントロールと対応しているかを見たい場合は、メニューから「Show Window」というメニューを実行してやれば、FirefoxのDOM InspectorやFirebugのように、選択されたコントロールを囲む形で矩形を表示させることが出来ます。

imageさて、そうやって発見したのがこのtextBoxKeywordsという名前のTextBox。コントロールのインスタンスの名前をアタッチさせたVSから調べるのはなかなか骨の折れる作業ですが、Managed Spyを使えば大分楽に出来ました。

なお、右側のVisual Studioのプロパティウィンドウのようなビューは表示だけでなくプロパティの編集も可能なので、WLWに対して色々イタズラをすることも可能です。

例えばエディタ部分を非表示にしてみた例。…だからどうしたって感じですが(笑)


image

実際に書き換えてみる

後は簡単です。こんな感じのコードでタグの書き換えが出来ます。

public override bool OnPrePublish(System.Windows.Forms.IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

    PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
    TextBox textBoxKeywords = (TextBox)findControlByName(postEditorForm, "textBoxKeywords");
    textBoxKeywords.Text = "SampleTag";
    ((BlogPost)publishingContext.PostInfo).Keywords = textBoxKeywords.Text;
    return true;
}

3行目、6行目については、中まで見よう!Windows Live Writer – Sharplab.のエントリを参照してください。

なお、用意したテスト用コード全文は以下の通りです。

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Windows.Forms;
using WindowsLive.Writer.Api;
using WindowsLive.Writer.BlogClient;
using WindowsLive.Writer.BlogClient.Clients;
using WindowsLive.Writer.PostEditor;
using WindowsLive.Writer.Extensibility.BlogClient;

namespace PublishNotificationHooksTestbedPlugin {
    [WriterPlugin("95c3d56c-671a-46a0-8bef-3d064d85867e", "PNHTestbedPlugin", PublisherUrl = "http://www.sharplab.net/")]
    public class PublishNotificationHooksTestbedPlugin : PublishNotificationHook {
        public override bool OnPrePublish(System.Windows.Forms.IWin32Window dialogOwner, IProperties properties, IPublishingContext publishingContext, bool publish) {

            PostEditorForm postEditorForm = getPostEditorForm(dialogOwner);
            TextBox textBoxKeywords = (TextBox)findControlByName(postEditorForm, "textBoxKeywords");
            textBoxKeywords.Text = "SampleTag";
            ((BlogPost)publishingContext.PostInfo).Keywords = textBoxKeywords.Text;
            return true;
        }

        private static PostEditorForm getPostEditorForm(IWin32Window postProgressForm) {
            return (PostEditorForm)((Form)Form.FromHandle(postProgressForm.Handle)).Owner;
        }

        private static Control findControlByName(Control control, string controlName) {
            foreach (Control cChild in control.Controls) {
                if (cChild.Name == controlName) {
                    return cChild;
                }
                if (cChild.HasChildren) {
                    Control returned = findControlByName(cChild, controlName);
                    if (returned != null) {
                        return returned;
                    }
                }
            }
            return null;
        }
    }
}

image WindowsLiveWriterの編集画面にウェブサイトのテーマを適用する場合、テーマが崩れて困ることがあります。例えばこのサイトの新デザインもWLW対策を取らなければ右SSのように酷い状態になってしまいます。むしろ、崩れなければ僥倖で(打率一割ぐらいかなぁ…)、自分は崩れた時の対応を織り込んでサイトの製作期間を見積るようにしています。

崩れる原因

さて、WLWの編集画面ではなぜテーマが崩れてしまうのでしょうか?WLWの描画エンジンがアホの子だから?ノー。WLWのエンジンはTridentです。確かにTridentはアホの子ではありますが、少なくともデファクトスタンダードであるIEと同じ表示になるわけですから、ここでは問題になりません。

image答は「WLWが編集画面に読み込むページのソースでは記事に関係のない部分、つまりタイトルと本文以外の部分の要素を全て削除してしまうから」です。WLWが取得してきたテーマはC:Users<ユーザー名>AppDataRoamingWindows Live Writerblogtemplates<ブログのGUID?>のどこかに保存されているのですが、それをFirebugでツリー表示したのが左のSSです。 ん~、見事なまでのふたこぶラクダ。タイトルの要素と、本文の要素、そしてそれらを囲む要素だけしか残っていません。ヘッダーやフッター、サイドバーは情け容赦なく消されています。visibility:hiddenが適用されているのではなく、要素自体が残っていません。これにより、その消された要素にレイアウトが依存しているテーマは表示が崩れてしまうのです。このサイトの新デザインも、消された要素によってfloatをclearしていた個所があったので、本文部を囲っているfloat要素の高さがゼロになり、白い背景が伸びずその下の暗色の横ストライプが見えてしまっていました。

対策

では、こんな時どうするか。WLWは諦めてしまうにはあまりに便利で惜しいソフトです。何とか対策を考えてみましょう。

対策1:サイトのテーマを全面的に修正する

ページのHTMLの構造を書き換える、floatは必ずclearfixでクリアする、など八方手を尽くしてWLW上では消えてしまう要素への依存をなくし、WLW Compatibleなテーマに書き換えるという方策です。これはサイトの設計時点で取り組まないと難しいでしょう。確実ですが、サイトの表現力にも影響を与えますし、本末転倒な気がします。

対策2:WLWがテーマをDLする時だけサイトのデザインを差し替える

WLWがテーマをDLする時を見計らって、その時だけstyle属性などでガチガチに固めてWLW対策をしたテーマに差し替えるという方法です。どうせ回り込ませるはずだった要素が消えてしまうなら、その時はfloatも辞めてしまえ、とか対策をします。差し替えはマニュアル操作でもよいですが、WordPressのようにテーマがプログラマブルな場合は、WLWに設定するホームページのURLにwlwcompatiblemode=onなどの適当なgetパラメタを追加し、テーマの側でそのようなパラメタが付加された場合だけWLW対策用のCSSを追加で読み込ませる、といった方法を採ることもできます。(WLWはテーマをWLWの設定でサイトのホームページとして指定したURLの内容から生成するので。)ちなみに自分はこの方法を使っています。

対策3:ダウンロードされたテーマの書き換え

ダウンロードされたテーマはC:Users<ユーザー名>AppDataRoamingWindows Live Writerblogtemplates<BlogのGUID?>に保存されると述べましたが、これを編集することでも対処できるようです。ただ、WLWの想定していない操作なので、副作用もあるかもしてないので、注意して行った方が良いでしょう。また、自動でWLWがテーマをウェブサイトから再読み込みして上書きしてしまう場合もあるらしいので、その点にも注意してバックアップを取るなりの対策が必要でしょう。

テーマのDLに失敗する場合

エントリの本題からは少しずれますが、テーマのDLに失敗する場合の原因とその対策で自分が知っているものを一セット紹介してみます。

前述の通り、WLWはテーマをWLWの設定でサイトのホームページとして指定したURLの内容から生成するようです。このとき、ホームページとして設定されたURLに最新記事が表示されない場合は、WLWはどこがタイトルに置き換えるべきところで、どこが本文に置き換えるべきところか判断がつかず、テーマの生成に失敗してしまいます。例えば、WordPressでホームページに最新記事の代わりに固定ページを表示させるようにした場合などがこれにあたります。前述の対策2を行えばよいでしょう。

おわりに

以上、WLWでデザインが崩れた際の対応策をまとめてみましたが、いかがだったでしょうか?このエントリがWLWの快適な利用に繋がれば幸いです。

 

しかし…WLWが表示の必要のない要素の扱いを削除からvisibility:hiddenの適用に改めてくれれば多分全て解決するはずなんですけれどねぇ…レイアウトが崩れるリスクを取ってまで要素を削除する理由ってなんなんでしょうかね。