12 سال کار، 12 درس
I’ve been at ThoughtWorks for 12 years. Who would have imagined? Instead of writing about my reflections from the past year, I thought I would do something different and post twelve key learnings and observations looking back over my career. I have chosen twelve, not because there are only twelve, but because it fits well with the theme of twelve years.
<div id="s4-ribbonrow">
<Sharepoint:SPSecurityTrimmedControl runat="server" Permissions="AddDelPrivateWebParts">
و تگ پایانی آن :
نکته مهم در استفاده از این تگ ، ویژگی Permissions آن است که باید با دقت و بسته به نیاز شما تعریف شود :
برخی از این موارد عبارتند از :
EmptyMask – Has no permissions on the Web site. Not available through the user interface.
ViewListItems – View items in lists, documents in document libraries, and view Web discussion comments.
AddListItems – Add items to lists, add documents to document libraries, and add Web discussion comments.
EditListItems – Edit items in lists, edit documents in document libraries, edit Web discussion comments in documents, and customize Web Part Pages in document libraries.
DeleteListItems – Delete items from a list, documents from a document library, and Web discussion comments in documents.
ApproveItems – Approve a minor version of a list item or document.
OpenItems – View the source of documents with server-side file handlers.
ViewVersions – View past versions of a list item or document.
DeleteVersions – Delete past versions of a list item or document.
CancelCheckout – Discard or check in a document which is checked out to another user.
ManagePersonalViews – Create, change, and delete personal views of lists.
ManageLists – Create and delete lists, add or remove columns in a list, and add or remove public views of a list.
ViewFormPages – View forms, views, and application pages, and enumerate lists.
Open – Allow users to open a Web site, list, or folder to access items inside that container.
ViewPages – View pages in a Web site.
AddAndCustomizePages – Add, change, or delete HTML pages or Web Part Pages, and edit the Web site using a SharePoint Foundation–compatible editor.
ApplyThemeAndBorder – Apply a theme or borders to the entire Web site.
ApplyStyleSheets – Apply a style sheet (.css file) to the Web site.
ViewUsageData – View reports on Web site usage.
CreateSSCSite – Create a Web site using Self-Service Site Creation.
ManageSubwebs – Create subsites such as team sites, Meeting Workspace sites, and Document Workspace sites.
CreateGroups – Create a group of users that can be used anywhere within the site collection.
ManagePermissions – Create and change permission levels on the Web site and assign permissions to users and groups.
BrowseDirectories – Enumerate files and folders in a Web site using Microsoft Office SharePoint Designer 2007 and WebDAV interfaces.
BrowseUserInfo – View information about users of the Web site.
AddDelPrivateWebParts – Add or remove personal Web Parts on a Web Part Page.
UpdatePersonalWebParts – Update Web Parts to display personalized information.
ManageWeb – Grant the ability to perform all administration tasks for the Web site as well as manage content. Activate, deactivate, or edit properties of Web site scoped Features through the object model or through the user interface (UI). When granted on the root Web site of a site collection, activate, deactivate, or edit properties of site collection scoped Features through the object model. To browse to the Site Collection Features page and activate or deactivate site collection scoped Features through the UI, you must be a site collection administrator.
UseClientIntegration – Use features that launch client applications; otherwise, users must work on documents locally and upload changes.
UseRemoteAPIs – Use SOAP, WebDAV, or Microsoft Office SharePoint Designer 2007 interfaces to access the Web site.
ManageAlerts – Manage alerts for all users of the Web site.
CreateAlerts – Create e-mail alerts.
EditMyUserInfo – Allows a user to change his or her user information, such as adding a picture.
EnumeratePermissions – Enumerate permissions on the Web site, list, folder, document, or list item.
FullMask – Has all permissions on the Web site. Not available through the user interface.
حال خارج از تگهای SPSecurityTrimmedControl در ابتدا یا انتها ، باید تگ login را مانند زیر به آن اضافه کرد .
و تمام :
کوئری در معماری CQRS
نحوه استفاده
نحوه استفاده از آن بسیار راحت است و در دموی html همراه آن به طور ساده در سه مثال توضیح داده شده است. ابتدا از این آدرس کتابخانه آن را دریافت کنید. این کتابخانه شامل یک فایل js که شامل کدهای پلاگین است، یک فایل css جهت تغییر استایل کدهایی است که پلاگین تولید میکند که اسامی آن دقیقا مشخص میکند که هر کلاس متعلق به چه بخشی است.
گام اول:
فایلهای مورد نظر را بعد از صدا زدن کتابخانهی جی کوئری صدا بزنید.
<link type="text/css" href="css/RowAdder.css" rel="stylesheet" /> <script src="js/RowAdder.js" type="text/javascript"></script>
گام دوم :
در تکه کدهای html، کدی را که قرار است در هر سطر تکرار شود، داخل یک div قرار داده و نامی مثل row-sample را برای آن قرار دهید (فعلا حتما این نام باشد)، بعدها پلاگین، کدهای داخل این تگ div را به عنوان هر سطر خواهد شناخت:
<div id="row-sample"> <form style="margin: 0; padding: 0;"> Name:<input type="text"/> <input type="radio" name="Gender" value="male" checked="checked">Male <input type="radio" name="Gender" value="female">Female </form> </div>
گام سوم:
سپس یک div دیگر ایجاد کنید و نامی مثل mypanel را به آن بدهید تا سطرهایی که ایجاد میشوند داخل این div قرار بگیرند.
<div id="mypanel"></div>
گام چهارم:
در بخش head یک تگ اسکریپت باز کرده و کدهای زیر را به آن اضافه میکنیم. این کد باعث میشود که پلاگین فعال شود.
<script> $(document).ready(function() { $("#mypanel").RowAdder(); }); </script>
یک دکمه جهت افزودن سطر به صفحه اضافه میکنیم
<button id="addanotherform">Add New Form</button>
و در قسمت تگ اسکریپت هم کد زیر را اضافه میکنیم:
$("#addanotherform").on('click', function() { $("#mypanel").RowAdder('add'); });
حال از صفحه تست میگیریم: با هر بار کلیک بر روی دکمهی Add New Form یک سطر جدید ایجاد میگردد.
در تصویر بالا دکمههای دیگر هم دیده میشوند که به دیگر متدهای آن اشاره دارد:
جهت مخفی سازی:
$("#mypanel").RowAdder('hide');
چهت نمایش:
$("#mypanel").RowAdder('show');
جهت افزودن سطر با کد:
$("#mypanel").RowAdder('add');
جهت دریافت تعداد سطرهای ایجاد شده:
$("#mypanel").RowAdder('count')
جهت دریافت کدهای یک سطر در اندیس x
$("#mypanel").RowAdder('content', 3)
جهت حذف یک سطر با اندیس x
$("#mypanel").RowAdder('remove', 3);
همانطور که با صدا زدن اولین متد پلاگین متوجه شدید و نتیجهی آن را در دمو دیدید، این پلاگین از پیش فرضهایی جهت راه اندازی اولیه استفاده میکند که این پیش فرضها عبارتند از تگ row-sample که بدون معرفی رسمی، آن را شناسایی کرد. همچنین ممکن است بخواهید عبارت Remove را با کلمهی فارسی «حذف» جایگزین نمایید. برای اینکار میتوانید پلاگین را به شکل زیر به کار ببرید:
$("#mypanel").RowAdder({ sample: '#my-custom-sample', type: 'text', value:'حذف' });
تغییر اولین پیش فرض، تغییر نام تگ row-sample به my-custom-sample بود و در مرحلهی بعد هم نام فارسی حذف را جایگزین remove کردیم. عبارت type به طور پیش فرض بر روی text قرار دارد که اجباری به ذکر آن در کد بالا نبود. ولی اگر دوست دارید که به جای نمایش عبارت حذف، از یک آیکن یا تصویر استفاده کنید، کد را به شکل زیر تغییر دهید:
$("#mypanel").RowAdder({ type: 'image', value: 'images/remove.png' });
فایل RowAdder.css
در بردارنده هر سطر .each-section { margin: 20px; padding: 5px; } جهت استایل بندی لینک چه تصویر و چه متن .remove-link { color:#999; text-decoration: none; } a:hover.remove-link { color:#802727; } جهت تغییر استایل بر روی خود تصویر .remove-image { }
آشنایی با کد پلاگین
(function ($) { var settings = null; $.fn.RowAdder = function (method) { // call methods if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === 'object' || !method) { return methods.init.apply(this, arguments); } else { $.error('Method ' + method + ' does not exist on jQuery.RowAdder'); } }; })(jQuery);
متدها
//methods var methods = { init: function (options) { //default-settings settings = $.extend({ 'sample': '#row-sample', 'type': 'text', 'value': 'Remove' }, options); this.attr('data-sample', settings.sample); this.attr('data-type', settings.type); this.attr('data-value', settings.value); Do(this); }, show: function () { this.css("display", "inline"); }, hide: function () { this.css("display", "none"); }, add: function () { Do(this); }, remove: function (index) { console.log(index); this.find(".each-section")[index].remove(); }, content: function (index) { return this.find(".each-section")[index]; }, count: function (index) { return this.find(".each-section").size(); } };
تابع Do
function Do(panelDiv) { settings.sample = panelDiv.data('sample'); settings.type = panelDiv.data('type'); settings.value = panelDiv.data('value'); //find sample code var rowsample = $(settings.sample); rowsample.css("display", "none"); var sample = rowsample.html(); var i = panelDiv.find(".each-section").size(); //add html details to create a correct template var sectionDiv = $('<div />', { "class": 'each-section', 'id': 'section'+i }); var image = $("<img />", { "src": settings.value,"class":"remove-image" }); var link = $("<a />", { "text": settings.value,"class":"remove-link" }); //remove event for remove selected form //create new form sectionDiv.html(sample); link.on('click', function (e) { e.preventDefault(); var $this = $(this); $this.closest(".each-section").remove(); }); if (i > 0) { if (settings.type == 'image') { link.text(''); link.append(image); } sectionDiv.append(link); } //add new created form on document panelDiv.append(sectionDiv); }
settings.sample = panelDiv.data('sample'); settings.type = panelDiv.data('type'); settings.value = panelDiv.data('value'); //find sample code var rowsample = $(settings.sample); rowsample.css("display", "none"); var sample = rowsample.html(); var i = panelDiv.find(".each-section").size();
//add html details to create a correct template var sectionDiv = $('<div />', { "class": 'each-section', 'id': 'section'+i }); var image = $("<img />", { "src": settings.value,"class":"remove-image" }); var link = $("<a />", { "text": settings.value,"class":"remove-link" });
در خط بعدی محتویات نمونه را داخل تگ sectiondiv قرار میدهیم:
//create new form sectionDiv.html(sample);
بعد از آن برای رویداد کلیک لینک حذف، کد زیر را وارد میکنیم:
link.on('click', function (e) { e.preventDefault(); var $this = $(this); $this.closest(".each-section").remove(); });
اولین شرط زیر بررسی میکند که آیا این سطری که ایجاد شده است سطر دوم به بعد است یا خیر؟ اگر آری پس باید دکمهی حذف را به همراه داشته باشد. در صورتیکه سطر دوم به بعد باشد، وارد آن میشود. حالا بررسی میکند که کاربر برای دکمهی حذف، درخواست لینک تصویری یا لینک متنی داده است و لینک مناسب را ساخته و آن را به انتهای sectionDiv اضافه میکند.
if (i > 0) { if (settings.type == 'image') { link.text(''); link.append(image); } sectionDiv.append(link); }
در انتها کل تگ sectionDiv را به تگ داده شده اضافه میکنیم تا به کاربر نمایش داده شود.
//add new created form on document panelDiv.append(sectionDiv);
Wikipedia و مهاجرت به HHVM
On over-engineering; finding the right balance
A big debate among developers is whether to write code for today’s problem or to build a general-purpose solution for future needs. Both approaches have their pros and cons. Specific-purpose code can quickly become messy. But overly general code can add unnecessary complexity. This post, obviously opinionated, argues for a middle ground. That’s the sweet spot, as always.