開発者向けのオーチャードCMS


現在ラスベガスで開催されているMIX11会議で、Orchard CMSの新しいバージョンが導入されました。MicrosoftのオープンソースCMSには、最先端といわれるMSFTテクノロジーの中で最も美味しくて健康的なものがすべて含まれています。 一見した後-私はCMSがかなり好きで(主にUmbracoと比較しています)-オーチャードの開発が実際にどのように進んでいるかを知りたいという要望がありました。 これであなたの願いが私のものと一致する場合-読んでください。

準備する


したがって、快適で便利で面白いものから素晴らしいカクテルを準備します-そして、Internet Explorer 9のサイトにグッズを追加できるようにするOrchard CMSのモジュールを作成します-すなわち、タスクバーでサイトを固定(ピン)し、そこにジャンプリストを追加します(ジャンプリスト)
職場の準備から始めましょう。 必要なツール:
1)Orchard CMS-orchard.codeplex.com
2)Internet Explorer 9-www.beautyoftheweb.com
3)Windows 7
4)Visual Studio 2010
オーチャードは、コンパイルされたパッケージの形式とソースコードの形式の両方で取得できます。 後者をお勧めします ドキュメントは非常に控えめであり、多くの場合、コードを読む必要があります。 Orchardにすばやく参加するには、 XaocCPS [1]から記事を読むだけで、ボーナスとして、公式サイト[2]から開発記事を読むことができます。 インターネットエクスプローラー9のピン留めサイトの詳細を確認するには、MSDN [3]または優れた記事[4]を参照してください。

モジュール作成


そのため、最初にモジュールブランクを作成します。 Web Platform Installer [5]またはソースコードからのアセンブリを介したCMSの迅速かつ便利なインストール後、cmd.exeを開き、<orchard_folder> \ binに移動してorchard.exeを実行します。 数秒の初期化の後、システムは親切に私たちを行動に誘います(「オーチャード」)。 コマンドラインの機能は非常に幅広く、モジュールと機能の管理、コンテンツ管理、コード生成と移行、パッケージ管理などが含まれます。 可能性を評価するには、招待状でヘルプコマンドを入力し、orchard.exeのパワーに驚嘆することができます。 しかし、喜びの議事録はすでに遅れています。骨の折れる仕事を始める時です。 モジュールの開発を開始するには、その構造を作成します。したがって、プロンプト行に次のように入力します。
orchard> codegen module Orchard.IE9Pins /IncludeInSolution:true.
これに応じて、CMSは新しいモジュール用に空のプロジェクトを作成し、CMS全体の一般的なソリューションであるModulesフォルダー(もちろん、ソースのバージョンを使用する場合)にそれを含めます(または含めません)。 一般的に、空のOrc​​hardモジュールのプロジェクトは、ASP.NET MVCプロジェクト(実際は)を恐ろしく連想させます。 最終的にVisual StudioにMVCで作業していることを納得させるために、Orchard.IE9pins.csprojファイルでそれを置き換えることができます
{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
に:
{E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}.
これにより、MVCの操作にスタジオの快適な機能を使用できるようになります-ビューの追加、ビューへ移動、コントローラーの追加などのコマンド [6]。

コンテンツタイプ


プロジェクトが作成され、準備完了です。ピン留めサイトモジュールのエンティティ構造を開発します。 既に(できれば)XaocCPSの記事から学んだように、Orchardの主な概念はコンテンツタイプとコンテンツアイテムです。 各アイテムには複数のパーツが含まれる場合があります。 部品に関するデータを保存するには、レコードが使用されるため、すべてが簡単です。 ジャンプリストのデータ構造を決めましょう。 このクイックジャンプリストとは何ですか? 実際には、これは名前-リンク-アイコンという形式のエントリのセットです。 したがって、必要なのは、情報を保存するための3つのフィールド、コンテンツパーツ、コンテンツタイプを含むDBのレコードです。 レコードはContenPartRecordから継承されたクラスであり、宣言されるすべてのプロパティは仮想でなければなりません。 そのため、プロジェクトのModelsフォルダーにJumpListItemRecord.csファイルを作成し、そこに書き込み用のクラスを配置します。
public class JumpListItemRecord : ContentPartRecord
{
public virtual string Name { get ; set ; }
public virtual string Url { get ; set ; }
public virtual string IconUrl { get ; set ; }
}


* This source code was highlighted with Source Code Highlighter .

レコードに基づいて、部品を決定できます。
public class JumpListItemPart : ContentPart<JumpListItemRecord>
{
[Required]
public string Name
{
get { return Record.Name; }
set { Record.Name = value ; }
}

[Required]
public string Url
{
get { return Record.Url; }
set { Record.Url = value ; }
}

public string IconUrl
{
get { return Record.IconUrl; }
set { Record.IconUrl = value ; }
}
}


* This source code was highlighted with Source Code Highlighter .

パーツを設計するために、データ検証(必須、StringLengthなど)を記述するために属性を使用できます。すでにお気付きのように、パーツの値は単に基礎となるレコードのデータです。 プロジェクトを収集し、モジュールがエラーなしでコンパイルされたことを確認します。 そして、CMSの利点に移りましょう。

移行


orchard.exeに戻り、コマンドを実行します。
orchard> codegen datamigration Orchard.IE9pins
はい、すでに騒々しい喜びと喜びを表現することができます-移行の概念が導入され、オーチャードで実装されています。 また、「RoRには長い間使用されている」と言ってはいけません。RoRには一般的に多くのニシュティアがありますが、話題を壊さないでください。 そのため、コマンドは次の内容のMigration.csファイルを生成します。
public class Migrations : DataMigrationImpl {

public int Create() {
// Creating table JumpListItemRecord
SchemaBuilder.CreateTable( "JumpListItemRecord" , table => table
.ContentPartRecord()
.Column( "Name" , DbType. String )
.Column( "Url" , DbType. String )
.Column( "IconUrl" , DbType. String )
);

return 1;
}
}

* This source code was highlighted with Source Code Highlighter .

ご覧のとおり、すべてが非常に簡単です-上記で定義したレコードの場合、データベースにテーブルが作成されます-これで移行が完了します。 最も注意深いのは、関数が1を返すことであり、これはエラーコードではありません。 これはバージョン番号です。 夢のような夢が実現します-Orchardはインストールされているバージョンを自動的に判断し、モジュールの更新を確認して、更新することができます。 これがどのように機能するか-もう少し詳しく見ていきますが、今度はジャンプリストのデータ構造の最後の部分であるコンテンツタイプについて考えます。 移行の段階(モジュールの作成または更新)で時間(および場所)を決定します。 1を返す前に次の行を追加して、タイプを作成してください。
ContentDefinitionManager.AlterTypeDefinition( "JumpListItem" ,
cfg => cfg
.WithPart( "JumpListItemPart" )
);


* This source code was highlighted with Source Code Highlighter .

すべてが非常に簡単に読み取られます-これは、JumpListItemPartパーツのみでJumpListItemコンテンツタイプを作成するシステムへのコマンドです。

ハンドラーとドライバー


部品を管理するためのインターフェイスに進む前に、2つの必要なスペア部品を「ボンネットの下」に追加する必要があります-ハンドラーとドライバー。 パートが発行、削除、バージョン管理などのコンテンツイベントに応答し、必要に応じて何らかのアクションを実行できるように、ハンドラーが必要です。 ハンドラーは(イデオロギー的に)モデルを操作する役割を果たし、プレゼンテーションには関係しません。 それまでの間、モデルを操作することで、パーツとレコードをリンクすることが必要になります。 これを行うには、ハンドラーのコンストラクターで、IRepository JumpListItemRecordがストレージとして使用されることをシステムに伝えます(これにより、システムはIoCコンテナーによりデータベースにバインドされますが、これには介入は不要です)。
public class JumpListPartHandler : ContentHandler
{
public JumpListPartHandler(IRepository<JumpListItemRecord> repo)
{
Filters.Add(StorageFilter.For(repo));
}
}


* This source code was highlighted with Source Code Highlighter .

ハンドラーとは対照的に、ドライバーはモデルではなく、ビュー、つまり パーツのレンダリングを制御します。 ContentPartDriverから継承したクラスでは、いくつかの関数を再定義できます。そのうちの2つに興味があります-Editor関数のオーバーロード(1つはGETリクエストの処理、つまり出力、POST、入力の処理) ) 実際、名前から明らかなように、メソッドはパーツを編集モードでレンダリングおよび処理するためのルールを決定します。
public class JumpListItemPartDriver : ContentPartDriver<Models.JumpListItemPart>
{
protected override DriverResult Editor(Models.JumpListItemPart part, dynamic shapeHelper)
{
return ContentShape( "Parts_JumpListItem_Edit" ,
() => shapeHelper.EditorTemplate(
TemplateName: "Parts/JumpListItem" ,
Model: part,
Prefix: Prefix));

}

protected override DriverResult Editor(Models.JumpListItemPart part, ContentManagement.IUpdateModel updater, dynamic shapeHelper)
{
updater.TryUpdateModel(part, Prefix, null , null );
return Editor(part, shapeHelper);
}
}


* This source code was highlighted with Source Code Highlighter .

あなたの最初の反応-「OMG、これは何ですか?」 実際、すべてがそれほど怖いわけではありません。 ここで重要な概念はContentShapeです。


ContentShapeは、パーツのデータと、ユーザーへのプレゼンテーション(表示への主要な中間手段)との間のリンクです。 詳細を明確にするために、 XaocCPSの記事を参照することをお勧めします。 したがって、実際には、パーツはShapeを提供するプレゼンテーション層と交換されます。 この場合、PartsフォルダーのJumpListItem.cshtmlをテンプレートとして使用してエディターの形状を作成し(TemplateName:“ Parts / JumpListItem”)、モデルとしてJumpListItemPartパーツを転送します。 更新により、さらに簡単になりました。パラメーターとして渡されたIUpdateModelオブジェクトのみを使用し、パーツの更新方法を処理します。 これで、システムは、パーツを編集するときに表示するテンプレートと、その(パーツ)コンテンツを更新する方法を認識します。 JumpListItem.cshtmlテンプレート自体は、Views / EditorTemplates / Parts /フォルダーに配置する必要があります。 テンプレートの内容は非常に簡単です。
@model Orchard.IE9pins.Models.JumpListItemPart
< fieldset >
@Html.LabelFor(m = > m.Name)
@Html.TextBoxFor(m = > m.Name, T("Description"))
@Html.LabelFor(m = > m.Url)
@Html.TextBoxFor(m = > m.Url, T("Url"))
@Html.LabelFor(m = > m.IconUrl)
@Html.TextBoxFor(m = > m.IconUrl, T("IconUrl"))
</ fieldset >


* This source code was highlighted with Source Code Highlighter .

ご覧のとおり、これはJumpListItemPart型付きモデルを使用した通常のRazorマークアップファイルです。 まあ、それはすべて、まあ、何が起こったのかを見たいと思うでしょう! ほんの少しの忍耐-フォームごとに、表示する方法と場所を決定する必要があります。 これには、プロジェクトのルートにあるPlacement.infoファイルが使用されます。 私たちにとって、それは非常に簡単です:
< Placement >
< Place Parts_JumpListItem_Edit ="Content:1" />
</ Placement >

* This source code was highlighted with Source Code Highlighter .

パーツのドライバーメソッドで定義されたフォーム(O_o)については、コンテンツセクションの位置1に配置されることを決定します(ちなみに、ここのシリアル番号は整数ではないため、既存のパーツの間にパーツをアタッチできます)。 この場合、コンテンツタイプにまだ1つのパーツしか含まれていない場合、どこにでも出力できます。

メインメニュー


すべて、パーツが作成され、コンテンツのタイプが作成されます-すでに「歓声」のようですか? まだ、最後の噴出。 これは非現実的に長く複雑なプロセスのように思えますが、これまでのところほとんどの操作はStudioのプロジェクトテンプレートとしても実行できます。これは基本的にすべて日常的なものであり、完全に自動化されています- すべて、励ましは終わりました。スタジオに戻り、最後の拍車をかけます。 もちろん、管理パネルのメインメニューにモジュールを独立した項目として表示し、CMS内の通常のコンテンツのように編集するようにします。 メインメニューから何を継承するかをシステムに伝えるには、INavigationProviderインターフェイスの実装を追加するだけです。 最も重要なメソッドはGetNavigationです。実際には、メニュー内のアイテムの作成について説明します。 パラメーターの1つは関数(god bless関数型プログラミング!)です。メニュー項目のサブメニューを構築するBuildMenu-広範囲にわたる計画-ピン留めサイトの外観、そして実際にはジャンプリスト要素。 サブメニューのパント-item.Actionのホラーを作成するときに、微妙な点にすでに気づいたと思います。MVCのActionメソッドに似ています-特定のコントローラーのアクションへのリンクを生成します。 ですから、実際にはそうです-URLがあれば、ルーティングルートとコントローラーをシステムに提供することを意味します。

ルート


ルートは、IrouteProviderクラスを実装することで追加されます-Route.csで確認できます。 ルートは次のように説明されます。
Route = new Route(
"Admin/IE9JumpList/Create" ,
new RouteValueDictionary {
{ "area" , "Orchard.IE9pins" },
{ "controller" , "JumpLists" },
{ "action" , "Create" }
},
new RouteValueDictionary(),
new RouteValueDictionary {
{ "area" , "Orchard.IE9pins" }
},
new MvcRouteHandler())
}

* This source code was highlighted with Source Code Highlighter .

説明なしですべてを読むのはかなり簡単です。モジュールのすべてのURLの一種の名前空間であるパラメーターarea = Orchard.IE9pinsをどこでも使用していることに注意してください。 JumpListsはコントローラーとして設定されています-それを実装する時が来ました。

コントローラー


MVCに比べて新しいものはありません。通常のコントローラーと、ActionResultを返すアクションメソッドのセットです。 特筆すべき点は、CMSコンポーネントとの通信がDependecy Injection方式でコントローラーに転送される方法のみです。必要なインターフェイスをデザイナーパラメーターとして指定すると、コントローラーがインスタンス化されると、登録されたCMSコンポーネントがパラメーターに到着します。 シンプルで美しい。 プレゼンテーションレイヤーで指定された転送方法に戻り、次の行にも注意を払います。
dynamic model = ContentManager.BuildEditor(item);

* This source code was highlighted with Source Code Highlighter .

これは、ビューに渡されるモデルを説明します。BuildEditorメソッドは、Shapeコンテンツの各部分に対してドライバーのEditorメソッドを使用して形成されます。これがモデルになります。 ビューに形状を表示するには、Displayメソッドで十分です。
@{ Layout.Title = T("Create jump list item").ToString(); }

@using (Html.BeginFormAntiForgeryPost()) {
@Html.ValidationSummary()
@Display(Model)
}

* This source code was highlighted with Source Code Highlighter .

実際のコンテンツを作成するとき、次のようなあいまいな行を観察できます。
var item = Services.ContentManager.New<Models.JumpListItemPart>( "JumpListItem" );

* This source code was highlighted with Source Code Highlighter .

実際、これは「JumpListItemコンテンツタイプの新しいアイテムを作成し、JumpListItemPartタイプのパーツを見つけて、結果として返す」と読む必要があります。 したがって、作成されたコンテンツでは、作成した部分のみを編集できます(正直なところ、他にはありません)。
最後のビルドが成功し、管理パネルに移動します。 そこでは、モジュール/機能を探しており、息を切らしてIE9Pinsに似たものを探しています。 さあ、ほら!

機能を有効化(有効化)し、...そう、はい-メインメニューにInternet Explorer 9パントが表示されます!

また、JumpListのリストを編集するための非常に素晴らしいインターフェースがあります。 さて、今私たちはそれをサイトに持ってくる必要があります...しかし、これはすでに次のシリーズにあります。 そのため、テキストが多すぎることが判明しました(すべてを明確にしようとすると、理論的には2分の1に減らすことができます)。

まとめ


要約すると:
1)管理パネルに新しいアイテムが追加され、クイックジャンプリストに必要なアイテムのリストが管理されます。
2)必要なすべてのデータ構造とコンテンツタイプが自動的に生成されます。

少し時間がかかりましたが、コードを見るだけでなく、CMS内でどのように機能するかを理解するために、すべてをできるだけ詳細に説明しようとしました。 次の部分(より小さくなります)では、レイアウト、ウィジェットの動作、サイトページでのコンテンツの表示方法、移行の実際の動作について説明します。
完全なソースコード(もちろん2番目の記事のコードを含む)は、 BitBucketにあります。 それはあまりきれいではありません、それは私の投げと検索の多くを反映しています、そして私はまだリファクタリングに気を取られていません-なぜなら 勉強するためにすべてをしました。

PS「それはなんて複雑なのか!」と結論付ける必要はありません。プロジェクト構造の作成は単純に十分に自動化されていませんが、将来はこれらすべてを迅速かつ簡単に行えることを願っていますが、内部を知ることは依然として有用です

参照資料


[1] Articles Architecture Orchard CMS。 セキュリティと開発の概念Orchard CMSアーキテクチャ。 レイアウトの概念オーチャードCMSアーキテクチャ。 基本的な概念
[2] 公式ウェブサイトの果樹園セクションの拡張
[3] MSDNのピン留めサイト
[4] kichikの 記事の ピン留めサイト
[5] Orchard CMSを使用してゼロからサイトを作成する方法。 パート1.オーチャードCMSの概要
[6] MVC 3「追加| 表示...”オーチャードコード生成モジュールプロジェクトへ


Source: https://habr.com/ru/post/J117373/


All Articles