<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Zorig on Medium]]></title>
        <description><![CDATA[Stories by Zorig on Medium]]></description>
        <link>https://medium.com/@Zorig?source=rss-b4aaa9ce2e86------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*VnJg1NAAVPixpYeY_sP_5Q.jpeg</url>
            <title>Stories by Zorig on Medium</title>
            <link>https://medium.com/@Zorig?source=rss-b4aaa9ce2e86------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 18 Jun 2026 18:27:41 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@Zorig/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Neovim хамгийн хялбар тохиргоо]]></title>
            <link>https://medium.com/@Zorig/neovim-%D1%85%D0%B0%D0%BC%D0%B3%D0%B8%D0%B9%D0%BD-%D1%85%D1%8F%D0%BB%D0%B1%D0%B0%D1%80-%D1%82%D0%BE%D1%85%D0%B8%D1%80%D0%B3%D0%BE%D0%BE-6508d6114c8d?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/6508d6114c8d</guid>
            <category><![CDATA[vim]]></category>
            <category><![CDATA[neovim]]></category>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[монгол]]></category>
            <category><![CDATA[програмчлал]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Thu, 30 Nov 2023 06:42:38 GMT</pubDate>
            <atom:updated>2023-11-30T06:42:38.891Z</atom:updated>
            <content:encoded><![CDATA[<p>Он цаг хугацааны туршид шалгарсан шилдэг код эдиторуудын нэг болох vim -ыг анх сурахад(learning curve) хүнд боловч нэг өөртөө зориулж тохируулж аваад, ашиглаад сурчихвал салахад тун бэрх зүйл билээ. Бараг 14 жил vim ашиглаад эргээд харахад, dotfiles тохиргоогоо байнга арчилж зүлгэж явна гэдэг нь зугаатай мэт боловч цаг хугацаа шаарддаг ажил байлаа.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HF4L3iicfIA5L3Psb75FuA.png" /><figcaption>Credits to Dall-E</figcaption></figure><blockquote>Сүүлийн 4 жил vim -ээс салбарлаж үүссэн neovim ашиглах болсон. Тиймээс энд neovim -ийн талаар бичигдэх болно. Neovim ийн тохиргоо lua хэл дээр бичигдэх боломжтой болсон нь нэмэлт(plugin) хөгжүүлэх эко систем нь асар хурдацтай хөгжиж байгаа билээ. Дахиад нэг програмчлалын хэл сурах нь гэж бодож байвал энэ нь харьцангуй амархан гэдгийг урьдчлаад хэлэе.</blockquote><p>Харин <a href="https://www.lazyvim.org">lazyVim</a> гарч ирсэнээр энэхүү ажил маш хялбар болж байгаа юм байна.</p><h4>Нэн түрүүнд шаардлагатай зүйлс нь:</h4><ul><li>Neovim &gt;= 0.9.0 (LuaJIT ашиглан build хийсэн хувилбар)</li><li>Git &gt;= 2.19.0 (мэдээж Git)</li><li>a <a href="https://www.nerdfonts.com/">Nerd Font</a>(v3.0 болон түүнээс дээш) <em>(заавал биш ч гэсэн зарим нэг icon -д шаардлагатай)</em></li><li><a href="https://github.com/jesseduffield/lazygit">lazygit</a> <em>(заавал биш)</em></li><li>C компайлэр, nvim-treesitter -д ашиглагдана</li><li><a href="https://github.com/nvim-telescope/telescope.nvim">telescope.nvim</a> <em>(заавал биш) <br>- </em>grep: <a href="https://github.com/BurntSushi/ripgrep">ripgrep</a><br>- Файлууд олох: <a href="https://github.com/sharkdp/fd">fd</a></li><li>true color болон <em>undercurl </em>дэмждэг терминал:<br>- <a href="https://github.com/kovidgoyal/kitty">kitty</a> <em>(Linux &amp; Macos)<br>- </em><a href="https://github.com/wez/wezterm">wezterm</a> <em>(Linux, Macos &amp; Windows)<br>- </em><a href="https://github.com/alacritty/alacritty">alacritty</a> <em>(Linux, Macos &amp; Windows)<br>- </em><a href="https://iterm2.com/">iterm2</a> <em>(Macos)</em></li></ul><h4>Суулгах:</h4><p>Юмыг яаж мэдэх вэ гээд, өмнө нь өөрт чинь nvim тохиргоо байсан бол backup хийгээд авсан дээр.</p><pre># заавал<br>mv ~/.config/nvim{,.bak}<br><br># заавал биш гэхдээ хийгээрэй<br>mv ~/.local/share/nvim{,.bak}<br>mv ~/.local/state/nvim{,.bak}<br>mv ~/.cache/nvim{,.bak}</pre><p>Дараа нь lazyVim ийн темплэйт тохиргоог clone хийж аваад:</p><pre>git clone https://github.com/LazyVim/starter ~/.config/nvim</pre><p>nvim ээ эхлүүлнэ.</p><pre>nvim</pre><p>nvim эхлэхдээ lazyVim ийн тохиргоог шууд ажиллуулж хэрэгцээтэй нэмэлтүүдийг өөрөө татаж авч суулгах учир тэвчээртэй хүлээгээрэй.</p><blockquote>Суулгаж дуусахаар нь <strong><em>:checkhealth </em></strong>командыг ажиллуулж ямар нэг асуудалгүй байгаа эсэхийг нягтлаарай.</blockquote><p>Амархан байгаа биз дээ. LazyVim ийн default тохиргоо ер нь л ихэнх хэрэгслүүдийг агуулсан учраас бараг л энэ чигээрээ ажиллана. Миний хувьд хэдэн customization хийсэн нь:</p><h4>Тохиргоо</h4><p>Neovim default -аараа json файлын “ quote ийг нуугаад байдаг үүнийг ил болгохдоо nvim/lua/config/autocmds.lua файлд доорхи өөрчлөлтийг оруулав.</p><pre>vim.api.nvim_create_autocmd(&quot;FileType&quot;, {<br>  pattern = { &quot;json&quot;, &quot;jsonc&quot; },<br>  callback = function()<br>    vim.wo.spell = false<br>    vim.wo.conceallevel = 0<br>  end,<br>})</pre><p>Мөн товчний хослолууд дээр доорхи тохиргоонуудыг хийсэн nvim/lua/config/keymaps.lua</p><pre>local keymap = vim.keymap<br>local opts = { noremap = true, silent = true }<br><br>-- KeyMap<br>--- Хуваасан цонхнуудруу шилжихдээ Ctrl + {h,j,k,l} ашиглах<br>keymap.set(&quot;n&quot;, &quot;&lt;C-h&gt;&quot;, &quot;&lt;C-w&gt;h&quot;, opts)<br>keymap.set(&quot;n&quot;, &quot;&lt;C-j&gt;&quot;, &quot;&lt;C-w&gt;j&quot;, opts)<br>keymap.set(&quot;n&quot;, &quot;&lt;C-k&gt;&quot;, &quot;&lt;C-w&gt;k&quot;, opts)<br>keymap.set(&quot;n&quot;, &quot;&lt;C-l&gt;&quot;, &quot;&lt;C-w&gt;l&quot;, opts)<br><br>--- идэвхижүүлсэн мөрийг дээш доош хөдөлгөх<br>keymap.set(&quot;v&quot;, &quot;J&quot;, &quot;:m &#39;&gt;+1&lt;CR&gt;gv=gv&quot;, opts)<br>keymap.set(&quot;v&quot;, &quot;K&quot;, &quot;:m &#39;&lt;-2&lt;CR&gt;gv=gv&quot;, opts)<br><br>--- buffer хооронд шилжих<br>keymap.set(&quot;n&quot;, &quot;&lt;leader&gt;]&quot;, &quot;:bn&lt;CR&gt;&quot;, opts)<br>keymap.set(&quot;n&quot;, &quot;&lt;leader&gt;[&quot;, &quot;:bp&lt;CR&gt;&quot;, opts)</pre><p>Мөн lazyVim ийн default тохиргоонд nvim/lua/config/lazy.lua дараах өөрчлөлтүүдийг оруулав.</p><pre>local lazypath = vim.fn.stdpath(&quot;data&quot;) .. &quot;/lazy/lazy.nvim&quot;<br>if not vim.loop.fs_stat(lazypath) then<br>  -- bootstrap lazy.nvim<br>  -- stylua: ignore<br>  vim.fn.system({ &quot;git&quot;, &quot;clone&quot;, &quot;--filter=blob:none&quot;, &quot;https://github.com/folke/lazy.nvim.git&quot;, &quot;--branch=stable&quot;, lazypath })<br>end<br>vim.opt.rtp:prepend(vim.env.LAZY or lazypath)<br><br>require(&quot;lazy&quot;).setup({<br>  spec = {<br>    -- add LazyVim and import its plugins<br>    { &quot;LazyVim/LazyVim&quot;, import = &quot;lazyvim.plugins&quot; },<br>    -- import any extras modules here<br>+    { import = &quot;lazyvim.plugins.extras.linting.eslint&quot; },<br>+    { import = &quot;lazyvim.plugins.extras.formatting.prettier&quot; },<br>+    { import = &quot;lazyvim.plugins.extras.formatting.black&quot; },<br>+    { import = &quot;lazyvim.plugins.extras.lang.typescript&quot; },<br>+    { import = &quot;lazyvim.plugins.extras.lang.tailwind&quot; },<br>+    { import = &quot;lazyvim.plugins.extras.lang.python&quot; },<br>+    { import = &quot;lazyvim.plugins.extras.lang.json&quot; }, <br>+    { import = &quot;lazyvim.plugins.extras.ui.mini-animate&quot; },<br>    -- import/override with your plugins<br>    { import = &quot;plugins&quot; },<br>  },<br>  defaults = {<br>    -- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup.<br>    -- If you know what you&#39;re doing, you can set this to `true` to have all your custom plugins lazy-loaded by default.<br>    lazy = false,<br>    -- It&#39;s recommended to leave version=false for now, since a lot the plugin that support versioning,<br>    -- have outdated releases, which may break your Neovim install.<br>    version = false, -- always use the latest git commit<br>    -- version = &quot;*&quot;, -- try installing the latest stable version for plugins that support semver<br>  },<br>  install = { colorscheme = { &quot;tokyonight&quot; } },<br>  checker = { enabled = true }, -- automatically check for plugin updates<br>  performance = {<br>    rtp = {<br>      -- disable some rtp plugins<br>      disabled_plugins = {<br>        &quot;gzip&quot;,<br> +      &quot;matchit&quot;,<br> +      &quot;matchparen&quot;,<br> +      &quot;netrwPlugin&quot;,<br>        &quot;tarPlugin&quot;,<br>        &quot;tohtml&quot;,<br>        &quot;tutor&quot;,<br>        &quot;zipPlugin&quot;,<br>      },<br>    },<br>  },<br>})</pre><blockquote>Энд анхаарах юм нь nvim/lua/config доторх файлуудад require дуудаж болохгүй. Учир нь lazyVim автоматаар доторх файлуудыг дууддаг. Зарим нэмэлтүүд тохиргооны заавар дээрээ require дуудсан байдаг!</blockquote><h4>Нэмэлтүүд(Plugins)</h4><p>file tree explorer ийн байршлыг сольсон. Ингэхдээ nvim/lua/plugins/neotree.lua файлыг үүсгээд доорхи хэсгийг бичиж өгөв.</p><pre>return {<br>  &quot;nvim-neo-tree/neo-tree.nvim&quot;,<br>  event = &quot;LazyFile&quot;,<br>  opts = function(_, opts)<br>    opts.window.position = &quot;right&quot;<br>  end,<br>}</pre><p>Default theme буюу colorscheme нь миний ашигладаг theme тул ердөө transparent болгох нэмэлт тохиргоо л бичив. nvim/lua/plugins/colorscheme.lua</p><pre>return {<br>  &quot;folke/tokyonight.nvim&quot;,<br>  lazy = true,<br>  opts = {<br>    style = &quot;storm&quot;,<br>    styles = {<br>      sidebars = &quot;transparent&quot;,<br>      floats = &quot;transparent&quot;,<br>    },<br>  },<br>}</pre><p>Ингээд л болоо. LazyVim өөрөө treesitter, syntax, нэмэлт суулгах, тухайн нээсэн файлын төрөлд тааруулж language-server асаах зэрэгээ хийдэг тул толгой өвтгөсөн асуудлууд байхгүй. Бас нэг зүйл нь lazyVim өөрийн нэмэлт plugin үүдээ үргэлж lazy буюу зөвхөн хэрэгцээтэй үед нь дууддаг. Харин хэрэглэгчийн нэмэлтээр суулгах plugin уудад та өөрөө нэмж тохируулах юм. Жишээ нь ts-autotag нэмэлтийг суулгах бол nvim/lua/plugins/autotag.lua гэж үүсгээд дотор нь:</p><pre>return {<br>  &quot;windwp/nvim-ts-autotag&quot;,<br>  lazy = true, --- хэрэгтэй үед нь л дуудна.<br>  opts = {<br>    ...<br>  },<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6508d6114c8d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Вэб хѳгжүүлэлтэй холбоотой миний сонсдог подкастууд]]></title>
            <link>https://medium.com/@Zorig/%D0%B2%D1%8D%D0%B1-%D1%85%D1%B3%D0%B3%D0%B6%D2%AF%D2%AF%D0%BB%D1%8D%D0%BB%D1%82%D1%8D%D0%B9-%D1%85%D0%BE%D0%BB%D0%B1%D0%BE%D0%BE%D1%82%D0%BE%D0%B9-%D0%BC%D0%B8%D0%BD%D0%B8%D0%B9-%D1%81%D0%BE%D0%BD%D1%81%D0%B4%D0%BE%D0%B3-%D0%BF%D0%BE%D0%B4%D0%BA%D0%B0%D1%81%D1%82%D1%83%D1%83%D0%B4-195b56395510?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/195b56395510</guid>
            <category><![CDATA[podcast]]></category>
            <category><![CDATA[вэб-хѳгжүүлэлт]]></category>
            <category><![CDATA[подкаст]]></category>
            <category><![CDATA[монгол]]></category>
            <category><![CDATA[mongolia]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Fri, 25 Jan 2019 15:48:55 GMT</pubDate>
            <atom:updated>2019-01-29T02:59:12.912Z</atom:updated>
            <content:encoded><![CDATA[<h3>Вэб хѳгжүүлэлттэй холбоотой миний сонсдог подкастууд</h3><p>Хѳгжүүлэгч хүн хэзээ ч суралцахаа зогсож болохгүй. Сүүлийн үеийн технологиудын талаар мэдээлэл, туршлага, номын дууг жолооны ард, гэрээ цэвэрлэж байхдаа г.м хаана ч сонсох боломжтой нэг зүйл нь подкаст билээ. Миний зүгээс доорх подкастуудыг санал болгож байна. Дараах подкастуудыг өөрсдийнх нь вэб болон <a href="https://itunes.apple.com/us/app/apple-podcasts/id525463029?mt=8">Apple Podcasts</a>, <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.podcasts">Google Podcasts</a> аппликешнүүдээр сонсох боломжтой</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CJUbGu1NxoTyqasAtJZm_w.jpeg" /><figcaption><a href="https://unsplash.com/photos/bXjqPckmLD8">https://unsplash.com/photos/bXjqPckmLD8</a></figcaption></figure><h4>1. <a href="http://www.fullstackradio.com/">Full Stack Radio</a></h4><p>Adam Wathan дизайнаас эхлээд тест хүртэлх маш өргөн олон зүйлсийг хамарсан сэдвээр зочин урин ярилцдаг.</p><h4><a href="https://syntax.fm/">2. Syntax</a></h4><p>Вэб хөгжүүлэлтийн талаарх tutorial, course, блогуудаар танил болсон Wes Bos, Scott Tolinski нар өөрсдийн туршлага, мэдлэг, entrepreneurship -ын талаар 2 долоо хоног тутам хуваалцдаг.</p><h4><a href="https://frontendhappyhour.com/">3. Front End Happy Hour</a></h4><p>Netflix, Evernote, Linkedin -ын инженерүүд цуглан frontend хөгжүүлэлтийн талаар нэмэлт зочинтой хөөрөлддөг. Сонирхолтой нь тэд ийнхүү хөөрөлдөх зуур түлхүүр үг дээр үндэслэн шар айраг, коктейл, виски, коняк уудаг. Нээрээ нээрээ :P</p><h4><a href="https://softwareengineeringdaily.com/">4. Sofware Engineering Daily</a></h4><p>Өдөр бүр програм хангамжийн инженертэй сонирхолтой яриа, асуудлын шийдэл зэргийг ярилцдаг. Database, Devops, React, Machine Learning, AR, VR г.м</p><h4><a href="https://shoptalkshow.com/">5. ShopTalk</a></h4><p>Codepen -ын co-founder Chris Coyier болон Dave Rupert нар вэб дизайн болон хөгжүүлэлт, сайжруулалт, UI, UX -ын талаар ярилцаж зөвлөгөө өгдөг.</p><h4><a href="https://devchat.tv/js-jabber/">6. Javascript Jabber</a></h4><p>7 хоног бүр зөвхөн javascript хэл дээр front-end болон back-end -ийг бүхэлд нь хамран tools, best practice, тест, deployment гэд бүгдийг нь 3–4 хүн ярилцдаг.</p><h4><a href="https://changelog.com/podcast">7. The Changelog</a></h4><p>Adam Stacoviak, Jerod Santo нарын нээлттэй эхийн хөгжүүлэлтийг хийж буй хүмүүстэй ярилцах санаа нь хэрэгжиж changelog болсон. Програм хангамжийн инженерүүд, хакерууд, бүтээлч хүмүүс зочид болж, програмчлалын хэл, үүсэл, ирээдүйн чиглэл, түүний community талаар ярилцдаг.</p><h4><a href="https://www.thisdot.co/modern-web">8. Modernweb</a></h4><p>Шинэ framework, стандарт, аргачлалууд, шинэчлэлтүүдийг яг тухайн framework -ын core хөгжүүлэгчтэй ярилцдаг.</p><h4><a href="https://reactpodcast.simplecast.fm/">9. React Podcast</a></h4><p>Вэб хөгжүүлэлтийн ертөнцөд хамгийн халуухан сэдвүүдийн нэг нь React гарцаагүй мөн билээ, Тэгэхээр зөвхөн react -д зориулагдсан podcast -ыг бол орхиж болохгүй. Мөн зочид нь ч бас дутахааргүй халуун сэдвүүдийг ярилцана. NPM -ын co-founder Laurie Voss хөтөлдөг.</p><p>Нийтлэл таалагдсан бол 👏 дарж энэ талаар сонирхдог хүмүүст share хийгээрэй.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=195b56395510" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Баяртай Bose буюу Sony WH-1000XM3 -ын талаар.]]></title>
            <link>https://medium.com/technote/%D0%B1%D0%B0%D1%8F%D1%80%D1%82%D0%B0%D0%B9-bose-%D0%B1%D1%83%D1%8E%D1%83-sony-wh-1000xm3-%D1%8B%D0%BD-%D1%82%D0%B0%D0%BB%D0%B0%D0%B0%D1%80-ab4bbc4d5951?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/ab4bbc4d5951</guid>
            <category><![CDATA[монгол]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[technology-news]]></category>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[sony]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Wed, 17 Oct 2018 06:11:01 GMT</pubDate>
            <atom:updated>2019-02-18T14:37:54.892Z</atom:updated>
            <content:encoded><![CDATA[<p>Энэ бол таны хүлээж байсан утасгүй, чимээ үл нэвтрүүлэх чихэвч юм.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rvwOtX_j4NoA066ejkhmCQ.jpeg" /><figcaption>Devindra Hardawar/Engadget</figcaption></figure><p>Гайхалтай дуугаралттай, маш эвтэйхэн санагдах <strong>Sony WH-1000XM3</strong> нь <strong>Sony</strong> -ын 2016 оноос эхлэн чимээ үл нэвтрүүлэх чихэвчний зах зээлд <strong>Bose</strong> -ын эсрэг зарласан дайны анхны 1000XM -ын үр хойч юм. Одоогоор <strong>Bose</strong> -ын хамгийн сайн буюу <strong>QuietComfort-35 </strong>аас илүү гарч чадсан энэхүү 3дахь хувилбар $350(одоогийн ханшаар 875к ₮ орчим) үнэтэй ба чимээ үл нэвтрүүлдэг, утасгүй чихэвч дотроо ерѳнхий role model болсон байна.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zKhM8UE1aApa4Qlzofa88Q.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TnVgcUItvZbjBNIArwWBhg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lc2t6pIUKL5wSVZO5g0LGQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bYs7NstOpiWsps5xedQUqw.jpeg" /></figure><p>Чимээ үл нэвтрүүлэх тал дээр энэ ангилалдаа 1-рт бичигдэж байгаа учир мэдээж дууны гаргалт чанарын хувьд ярих асуудалгүй биз. Ѳмнѳх хувилбаруудыг сайжруулах бус бүгдийг эхнээс нь дахин хийсэн нь чихэнд тааламжтай материал, том чихтэй хүмүүст зориулан доторх зайг арай том болгож ѳгсѳн нь дурьдахгүй ѳнгѳрч болохгүй зүйл юм. Мѳн ѳмнѳх хувилбарыг бодвол илүү хѳнгѳн бас толгой чихэвч 2ын хооронд гарах зай бага болж, эвхээд авч явахад хүртэл нилээд авсаархан болсон байна.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7N2W7AUzwBrDQCAaitpLxw.jpeg" /><figcaption>Зүүн талд 1000XM-3, баруун талд 1000XM-2</figcaption></figure><p>Энэ загварын хамгийн том дэвшил нь чимээ үл нэвтрүүлэх QN1 чип юм. Ѳмнѳх загварууын DAC(Digital to Analog Convertor) -д ѳѳрчлѳлт оруулж нэмэлт чимээг бууруулдаг байсан. Харин QN1 тусдаа чип болгосоноор орчны болон нэмэлт чимээг ѳмнѳх загваруудаас 4 дахин багасгадаг болж 32бит -ын аудио боловсруулах нэмэлт тѳхѳѳрѳмж багтах зай гаргаж ѳгсѳн байна. Ингэснээр энгийн шахагдсан дуунаас ялгаа мэдрэхгүй ч lossless дуу сонсоход жинхэнэ утгаараа ялгааг нь мэдэрч чадах нь.</p><p>Түүнчлэн <a href="https://www.sony.net/Products/LDAC/">Sony -ын LDAC</a> холболт дэмждэг болсон ч одоогоор зѳвхѳн бусад Sony тѳхѳѳрѳмжүүдтэй л хослон ажиллах нь</p><blockquote>LDAC нь Sony компаниас гаргасан утасгүй холболтоор аудио цацах боломжтой шинэ технологи юм. LDAC нь bluetooth -ээс 3 дахин ѳргѳн учраас энэ холболтоор илүү тѳгс дуугаралт мэдрэх боломжтой.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lr_LhoydpviXUeCVX1J_7Q.jpeg" /><figcaption>Devindra Hardawar/Engadget</figcaption></figure><p>Уг чихэвчээр юу ч тоглуулсан, бүр яг юу ч тоглуулсан(literally anything) Led Zeppelin — discography -ыг earpod оор сонсож байгаад Sony 1000XM3 дээр тоглуулж сонсоход тухайн тоглуулж буй дууг амилуулж байгаа нь үнэхээр гайхамшигтай санагдсан шүү.</p><p>Зарим чихэвч удаан зүүхэд толгой хэт хавчих, чих ѳвтгѳх зэрэг зовиур байдаг бол 1000XM3 ыг 8 цагын нислэгийн турш зүүхэд асуудалгүйн дээр, чихний хэсэг нь амьсгалдаг болохоор чих хѳлрѳх асуудалгүй болсон юм байна. Бас ѳмнѳх загвараас илүү хѳнгѳн болсон гэж хэлсэн бил үү?!</p><blockquote>Ѳѳ хэлсэн хүнд нэг л ѳѳ байна даа, хажуу талын touch хэсэгт дууны чанга сулыг тохируулах явцдаа санаандгүй дуу солигдоод байсан нь :(</blockquote><p>QN1 чипний тухайд сони үнэн хэлжээ, ѳмнѳх загваруудтай харьцуулахад мэдэгдэхүйц дуу чимээ үл нэвтрүүлж байна. Онгоцонд моторын хүнгэнэсэн дуу байхгүй болж кино үзэх, дуу сонсоход доторх чимээ тэр чигтээ байхгүй болж байсан. Чимээтэй metro хүртэл зүгээр л podcastны орчин болсон.</p><p>Sony -ын утасны апп-ыг ашиглан хэр их чимээ нэвтрүүлэхээ тохируулж хотийн гудамжын гоёмсог чимээг мэдэрч болно, хэрвээ байнга тохиргоо ѳѳрчлѳх хэцүү бол adaptive sound control-оор орчиндоо тааруулан ѳѳрчилж болдог.</p><p>Sony апп нь бас дуу чимээ үл нэвтрүүлэх тохиргоог зѳвхѳн таны сонсголд тохируулж ѳѳрчилж болдог, мѳн sony апп-ын тусламжтай google туслах холбох боломжтой.</p><p>30 цагын турш ажиллах чадамжтай 1000XM3 нь USB-C порттой нь хэрвээ та аль хэдийн C порт хэрэглээд сурчихсан бол илүү usb кабель авч явах шаардлагагүй болох нь, мѳн Sony -ын ѳѳрийх нь adapter 10мин дотор 5 цаг ашиглах цэнэг авдаг давуу талтай. Үнийн хувьд $350 нь нилээд санаа зовох асуудал болоод байгаа ч үнэхээр decent чихэвч бѳгѳѳд worth it байх нь ээ.</p><p>Орчуулга: engadget.com</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ab4bbc4d5951" width="1" height="1" alt=""><hr><p><a href="https://medium.com/technote/%D0%B1%D0%B0%D1%8F%D1%80%D1%82%D0%B0%D0%B9-bose-%D0%B1%D1%83%D1%8E%D1%83-sony-wh-1000xm3-%D1%8B%D0%BD-%D1%82%D0%B0%D0%BB%D0%B0%D0%B0%D1%80-ab4bbc4d5951">Баяртай Bose буюу Sony WH-1000XM3 -ын талаар.</a> was originally published in <a href="https://medium.com/technote">Technote</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Django 007: Зураг, файл админаас upload хийх нь]]></title>
            <link>https://medium.com/limitx/django-007-%D0%B7%D1%83%D1%80%D0%B0%D0%B3-%D1%84%D0%B0%D0%B9%D0%BB-%D0%B0%D0%B4%D0%BC%D0%B8%D0%BD%D0%B0%D0%B0%D1%81-upload-%D1%85%D0%B8%D0%B9%D1%85-%D0%BD%D1%8C-%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-763eb6d2359c?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/763eb6d2359c</guid>
            <category><![CDATA[вэб-хѳгжүүлэлт]]></category>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[монгол]]></category>
            <category><![CDATA[django]]></category>
            <category><![CDATA[хичээл]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Mon, 13 Aug 2018 10:03:37 GMT</pubDate>
            <atom:updated>2018-08-14T02:48:59.931Z</atom:updated>
            <content:encoded><![CDATA[<p>Ѳмнѳх царайлаг болгох алхам маань тийм ч царайлаг болоогүй ч одоо бага зэрэг визуал харагдацтай болгох үүднээс блог тус бүр ковер зурагтай болгоё.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J1RA_UuoNeMHeNeNBAOTNg.jpeg" /><figcaption><a href="https://www.facebook.com/kitophotography1/">https://www.facebook.com/kitophotography1/</a></figcaption></figure><p>Source код оо текст засварлагч дээрээ нээгээд blog/models.py файлыг нээж дотор нь дараах мѳрийг нэмнэ.</p><pre>cover = models.ImageField(upload_to=&quot;blog_cover&quot;)</pre><p>ингээд blog модэлийн харагдах байдал:</p><pre>from django.db import models<br>from django.utils.text import slugify</pre><pre>class Blog(models.Model):<br>    title = models.CharField(max_length=50, null=True)<br>    body = models.TextField()<br>    author = models.CharField(max_length=50, null=True)<br>    slug = models.SlugField(unique=True, blank=True)<br>    cover = models.ImageField(upload_to=&quot;blog_cover&quot;)</pre><pre>def __str__(self):<br>        return self.title + &#39;-&#39; + self.author</pre><pre>def get_absolute_url(self):<br>        return &quot;/%s&quot; % self.slug</pre><pre>def save(self, *args, **kwargs):<br>        self.slug = slugify(self.title, allow_unicode=True)<br>        super(Blog, self).save(*args, **kwargs)</pre><pre>def author_slug(self):<br>        return &quot;Publisher: %s - %s&quot; % (self.author, self.slug)</pre><p>Мэдээж models.py дээр ѳѳрчлѳлт оруулсан тул migration хийх шаардлагатай. Хэрвээ models.py дээр ямар нэг ѳѳрчлѳлт оруулсан л бол заавал migration хийх ёстойг байнга санаж хэрэгжүүлж сурах хэрэгтэй. Тэгэхээр одоо терминал дээр:</p><pre>python manage.py makemigrations</pre><p>Одоо demo_project/settings.py файлыг нээж хамгийн доод талын мѳрѳнд дараах 2 мѳрийг нэмнэ. Ингэснээр upload хийгдэх файлууд media хавтас дотор хуулагдахыг зааж ѳгнѳ. Мѳн файлруу хандахдаа domain.com/media/файлын_нэргэж хандахыг тохируулж ѳгч байгаа юм.</p><pre>MEDIA_URL = &#39;/media&#39;<br>MEDIA_ROOT = os.path.join(BASE_DIR, &#39;media&#39;)</pre><p>дээр тохируулсан url ээ demo_project/urls.py дээр тохируулж ѳгнѳ. Доорхи кодыг ѳмнѳх код дээр хуулж тавина.</p><pre>...<br>from django.conf import settings<br>from django.urls import re_path<br>from django.views.static import serve<br>...</pre><pre>] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)</pre><p>Ингэснээр demo_project/urls.py файл ингэж харагдана.</p><pre>&quot;&quot;&quot;demo_project URL Configuration</pre><pre>The `urlpatterns` list routes URLs to views. For more information please see:<br>    <a href="https://docs.djangoproject.com/en/1.11/topics/http/urls/">https://docs.djangoproject.com/en/1.11/topics/http/urls/</a><br>Examples:<br>Function views<br>    1. Add an import:  from my_app import views<br>    2. Add a URL to urlpatterns:  url(r&#39;^$&#39;, views.home, name=&#39;home&#39;)<br>Class-based views<br>    1. Add an import:  from other_app.views import Home<br>    2. Add a URL to urlpatterns:  url(r&#39;^$&#39;, Home.as_view(), name=&#39;home&#39;)<br>Including another URLconf<br>    1. Import the include() function: from django.conf.urls import url, include<br>    2. Add a URL to urlpatterns:  url(r&#39;^blog/&#39;, include(&#39;blog.urls&#39;))<br>&quot;&quot;&quot;<br>from django.conf.urls import url<br>from django.contrib import admin</pre><pre>from django.conf import settings<br>from django.urls import re_path<br>from django.views.static import serve</pre><pre>from blog.views import all_blog, single_blog</pre><pre>urlpatterns = [<br>    path(&#39;admin/&#39;, admin.site.urls),<br>    path(&#39;&#39;, all_blog, name=&quot;all_blog&quot;),<br>    path(&#39;&lt;slug&gt;&#39;, single_blog, name=&quot;single_blog&quot;),<br>] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)</pre><p>Одоо тэмплэйт дээрээ ѳѳрчлѳлт оруулж зураг харуулцгаая.</p><p>index.html нээгээд for loop дотор ингэж ѳѳрчлѳв.</p><pre>{% for blog in blogs %}<br>    &lt;div class=&quot;cell&quot;&gt;<br>      &lt;div class=&quot;media-object&quot;&gt;<br>        {%if blog.cover %} &lt;!--зураг байвал доорх img гарна--&gt;<br>         &lt;div class=&quot;thumbnail&quot;&gt;<br>           &lt;img src={{blog.cover.url}} alt=&quot;{{blog.title}}&quot; class=&quot;cover&quot;/&gt;<br>         &lt;/div&gt;<br>        {% endif %} &lt;!--нѳхцѳл шалгалт дуусна--&gt;<br>        &lt;div class=&quot;media-object-section&quot;&gt;<br>          &lt;h4&gt;&lt;a href=&quot;{{blog.get_absolute_url}}&quot;&gt;{{blog.title|capfirst}}&lt;/a&gt;&lt;/h4&gt;<br>          &lt;p&gt;{{blog.body|truncatechars:&#39;140&#39;}}&lt;/p&gt;<br>          &lt;a href=&quot;{{blog.get_absolute_url}}&quot;&gt;Үргэлжлэл...&lt;/a&gt;<br>        &lt;/div&gt;<br>      &lt;/div&gt;<br>    &lt;/div&gt;<br>  {% endfor %}</pre><p>Ингээд серверээ асааж эхлээд admin хэсгээс нэг блогруу cover зураг оруулая.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5ZzBr3IDwBKKKUmAitv1Mg.png" /><figcaption>localhost:8000/admin/blog/blog/3/change</figcaption></figure><p>Одоо нүүр хуудсаа харвал</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*A1Y-hsxWfoBX0lxaLqA0hw.png" /></figure><p>Зураг маань хэт том зураг байх нь үүнийг бага зэрэг css бичээд янзалж болно. Үүний тулд base.html -ын foundation.min.cssдоод талд доорхи мѳрийг нэмнэ.</p><pre>&lt;link rel=&quot;stylesheet&quot; href=&quot;{% static &#39;css/style.css&#39; %}&quot;&gt;</pre><p>Дараа нь static/css/style.css файл үүсгээд доорхи css ыг бичнэ.</p><pre>.cover {<br>  width: 10rem;<br>  height: auto;<br>}</pre><p>хадгалаад нүүр хуудсаа reload хийж харвал</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*s1z2BtYHbSnRWJ-LJTjDxw.png" /></figure><p>Ингээд cover зураг admin аас оруулдаг боллоо. Дээр бичсэн шиг detail хуудас буюу single.html дээр cover гаргаж болох нь.</p><p>Github дээрх тѳслийн эх код <a href="https://github.com/Zorig/django-demo_project/tree/007">update</a> хийгдсэн. Нийтлэл таалагдсан бол <strong><em>clap &amp; share </em></strong>хийж хэрэгтэй хүмүүст түгээгээрэй.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=763eb6d2359c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/limitx/django-007-%D0%B7%D1%83%D1%80%D0%B0%D0%B3-%D1%84%D0%B0%D0%B9%D0%BB-%D0%B0%D0%B4%D0%BC%D0%B8%D0%BD%D0%B0%D0%B0%D1%81-upload-%D1%85%D0%B8%D0%B9%D1%85-%D0%BD%D1%8C-%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-763eb6d2359c">Django 007: Зураг, файл админаас upload хийх нь</a> was originally published in <a href="https://medium.com/limitx">limitx</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Django 006: Django 1.x.x дээрх тѳслийг Django 2.x.x migrate хийх нь]]></title>
            <link>https://medium.com/limitx/django-006-django-1-x-x-%D0%B4%D1%8D%D1%8D%D1%80%D1%85-%D1%82%D1%B3%D1%81%D0%BB%D0%B8%D0%B9%D0%B3-django-2-x-x-migrate-%D1%85%D0%B8%D0%B9%D1%85-%D0%BD%D1%8C-bfe854924d28?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/bfe854924d28</guid>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[хичээл]]></category>
            <category><![CDATA[django]]></category>
            <category><![CDATA[вэб-хѳгжүүлэлт]]></category>
            <category><![CDATA[монгол]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Mon, 13 Aug 2018 04:44:30 GMT</pubDate>
            <atom:updated>2018-08-13T04:47:03.218Z</atom:updated>
            <content:encoded><![CDATA[<p>Зээ, ѳмнѳ нь амласан тул ингээд django 2.0 руу шилжүүлэх ажилруу оръё.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MLJ8kpVy5gvb7UbW-oZfpQ.jpeg" /><figcaption><a href="https://www.facebook.com/kitophotography1/photos/a.1391983497690713.1073741828.1391981541024242/1561897064032688/?type=3&amp;theater">https://www.facebook.com/kitophotography1</a></figcaption></figure><p>Django 2.x.x хувилбараас эхлээд python 3.xx л ашиглана гэсэн болохоор гол кодуудаа python 3 -т тааруулан ѳѳрчлѳх хэрэгтэй. Жишээ нь __unicode__ ашиглаж байгааг __str__ болгох хэрэгтэй г.м. Python 3 compatible болгох хэсэг нэг их ажил биш учир уншигч танд ѳѳрт тань энэхүү зугаатай ажлыг үлдээе. Энгийн google хайлтанд гараад ирэх илэрц шүү. Тиймээс Django 2.0 ын ѳѳрчлѳлтүүдыг шууд хийгээд явъя.</p><ol><li>ForeignKey ашиглахад on_delete заавал бичнэ.</li></ol><pre>class MyModel(models.Model):<br>    group = ForeignKey(<br>        &#39;MyGroup&#39;,<br>        on_delete=CASCADE,<br>    )</pre><p>2. Namspace ашиглаж байгаа route -ууд заавал app_name шаардана.</p><pre>urlpatterns = [<br>    path(&#39;myapp/&#39;, include(&#39;my_app.urls&#39;, namespace=&#39;my_app&#39;, app_name=&#39;my_app&#39;)),<br>]</pre><p>Тэгэхээр include хийгдэж буй url файл нь дараах ѳѳрчлѳлттэй байна.</p><pre>app_name=&#39;my_app&#39;<br>urlpatterns = [<br>    # ...<br>]</pre><p>Мѳн url гэж бичихгүй оронд нь path гэж бичнэ.</p><p>3. User object is_authenticated() болон is_anonymous() байхаа больсон</p><p>User ээс биш, моделын property болсон. Тэгэхээр дуудаж ашиглахдаа</p><pre>user.is_authenticated() → user.is_authenticated<br>user.is_anonymous() → user.is_anonymous</pre><p>4. urlresolver -оос reverse дуудахаа больсон</p><pre><strong>from</strong> django.core.urlresolvers <strong>import</strong> reverse</pre><p>ингэж ашигладаг байсан нь доорхи замаар дууддаг болсон.</p><pre><strong>from</strong> django.urls <strong>import</strong> reverse</pre><p>5. MIDDLEWARE_CLASSES -&gt; MIDDLEWARE болсон</p><p>settings.py дотор MIDDLEWARE_CLASSES ѳѳрчлѳгдѳн MIDDLEWARE болсон.</p><p>6. django.shortcut.render_to_response() байхаа больсон</p><p>render_to_response() хуучирч django.shortcuts.render() ашиглах нь</p><p>7. SessionAuthenticationMiddleware шаардлагагүй болсон.</p><p>Django 1.10 аас эхлээд энэ middleware цаанаасаа enabled болохоор</p><p>Дээрх ѳѳрчлѳлтүүдийг зѳвхѳн ѳѳрт байгаагаа ѳѳрчлѳѳрэй. Ѳмнѳх хувилбар ахиулах гэж ядаргаатай санагдаж байвал шууд django 2.0 дээр тѳслѳѳ эхлүүлээд доторхоо зѳѳсѳн ч болно.</p><p>Манай demo blog -ын хувьд аль болох хоцрогдох функцууд ашиглаагүй учраас, мѳн дээрх ѳѳрчлѳлтѳѳс ашиглаж байгаа зүйл бага болохоор одоохондоо ямар ч асуудалгүй шилжлээ.</p><p>Update хийгдсэн тѳслийн <a href="https://github.com/Zorig/django-demo_project/tree/006">эх код github дээр байршсан</a>.</p><p>Нийтлэл таалагдсан бол clap &amp; share хийж бусад хэрэгтэй хүмүүст нь хүргээрэй.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bfe854924d28" width="1" height="1" alt=""><hr><p><a href="https://medium.com/limitx/django-006-django-1-x-x-%D0%B4%D1%8D%D1%8D%D1%80%D1%85-%D1%82%D1%B3%D1%81%D0%BB%D0%B8%D0%B9%D0%B3-django-2-x-x-migrate-%D1%85%D0%B8%D0%B9%D1%85-%D0%BD%D1%8C-bfe854924d28">Django 006: Django 1.x.x дээрх тѳслийг Django 2.x.x migrate хийх нь</a> was originally published in <a href="https://medium.com/limitx">limitx</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[API аюулгүйн зѳвлѳмж]]></title>
            <link>https://medium.com/limitx/api-%D0%B3%D0%B0%D1%80%D0%B3%D0%B0%D1%85-%D0%B7%D0%B0%D0%B3%D0%B2%D0%B0%D1%80%D1%87%D0%BB%D0%B0%D1%85-%D1%82%D0%B5%D1%81%D1%82%D0%BB%D1%8D%D1%85%D1%8D%D0%B4-%D0%B0%D1%8E%D1%83%D0%BB%D0%B3%D2%AF%D0%B9%D0%BD-%D1%82%D0%B0%D0%BB%D0%B0%D0%B0%D1%81-%D0%B0%D0%B2%D0%B0%D1%85-%D1%81%D3%A9%D1%80%D3%A9%D0%B3-%D0%B0%D1%80%D0%B3%D0%B0-%D1%85%D1%8D%D0%BC%D0%B6%D1%8D%D1%8D%D0%BD%D0%B8%D0%B9-%D0%B6%D0%B0%D0%B3%D1%81%D0%B0%D0%B0%D0%BB%D1%82-28dbfda11613?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/28dbfda11613</guid>
            <category><![CDATA[api-security]]></category>
            <category><![CDATA[монгол]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[api]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Wed, 25 Jul 2018 02:36:33 GMT</pubDate>
            <atom:updated>2019-10-23T08:10:21.750Z</atom:updated>
            <content:encoded><![CDATA[<p>shieldfy.io -оос гаргасан <a href="https://github.com/shieldfy/API-Security-Checklist">https://github.com/shieldfy/API-Security-Checklist</a>-ыг Монгол хэлнээ буулгаснаа оруулав.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zv1SAvvGcbLr-3ye28Jw2Q.jpeg" /><figcaption>source: <a href="https://www.facebook.com/kitophotography1/photos/a.1391983497690713.1073741828.1391981541024242/1539633732925688/?type=3&amp;theater">https://www.facebook.com/kitophotography1</a></figcaption></figure><h3>API Аюулгүйн жагсаалт</h3><p>API гаргах, загварчлах, тестлэхэд аюулгүйн талаас авах сөрөг арга хэмжээний жагсаалт.</p><h3>Authentication</h3><ul><li>Basic Auth бүү ашигла, Стандарт authentication ашигла (Жнь. <a href="https://jwt.io/">JWT</a>, <a href="https://oauth.net/">OAuth</a>).</li><li>Authentication -ын token generation, password storage зэргийг бүү дахин шинээр хий, стандарт ашигла.</li><li>Нэвтрэх(Login) үед Max Retry ашиглан хорилт хий.</li><li>Чухал өгөгдлүүдийг encrupt хий.</li></ul><h3>JWT (JSON Web Token)</h3><ul><li>Санамсаргүй үүссэн түлхүүр (JWT Secret) ашиглаж token -ыг brute force -оос хамгаал.</li><li>Payload -аас алгоритмаа бүү задал. Backend дээрээ хий (HS256 or RS256).</li><li>Токен дуусах хугацаа (TTL, RTTL) аль болох бага болго.</li><li>Чухал өгөгдлийг JWT payload -д бүү хадгал, decode хийхэд <a href="https://jwt.io/#debugger-io">амархан</a>.</li></ul><h3>OAuth</h3><ul><li>redirect_uri -ыг үргэлж сервер талд шалган зөвшөөрөгдсөн URL эсэхийг шалга.</li><li>Аль болох токен биш код солилц (response_type=token -ыг зөвшөөрч болохгүй).</li><li>OAuth authentication -ын үед state параметрийг санамсаргүй үүссэн hash ашиглан CSRF ээс сэргийлнэ.</li><li>Хувьсагчид анхны утга заавал оноож өг, утгыг байнга шалга.</li></ul><h3>Access</h3><ul><li>Хүсэлтийн тоог хязгаарлаж (Throttling) DDoS / brute-force дайралтаас хамгаална.</li><li>HTTPS ашиглаж сервер талдаа MITM (Man In The Middle Attack) дайралтаас хамгаална.</li><li>HSTS header -ыг SSL дээр ашиглаж SSL Strip дайралтаас хамгаална.</li></ul><h3>Input</h3><ul><li>Яг зөв HTTP хүсэлтийг ашигла: GET (унших), POST (үүсгэх), PUT/PATCH (орлуулах/солих), мөн DELETE (устгах), бас 405 Method Not Allowed -ыг хүсэлтийн төрөл тодорхойгүй үед ашигла.</li><li>content-type -ыг хүсэлтийн header (Content Negotiation) дээр шалгаж зөвхөн дэмжигдсэн төрлийг зөвшөөр (Жнь. application/xml, application/json, гэх мэт) бас төрөл нь таарахгүй бол 406 Not Acceptable хариу буцаа.</li><li>content-type -ыг post хийх өгөгдөл дээр шалга (Жнь. application/x-www-form-urlencoded, multipart/form-data, application/json, г.м).</li><li>Хэрэглэгчээс гараас оруулсан утгыг шалгаж түгээмэл нүхнүүдээс сэргийлнэ. (Жнь. XSS, SQL-Injection, Remote Code Execution, г.м).</li><li>Чухал өгөгдлүүдийг (credentials, Passwords, security tokens, or API keys) URL ээр бүү явуул, оронд нь стандарт Authorization header ашигла.</li><li>API Gateway үйлчилгээ ашиглан Rate Limit Policies (Жнь. Quota, Spike Arrest, Concurrent Rate Limit) болон cache хийх, мөн API deploy хийхэд ашигла.</li></ul><h3>Processing</h3><ul><li>Нэвтрэх явцад алдаа гарахаас сэргийлж бүх endpoint -уудыг нэвтрэх шаардлагатай эсэхийг шалгах.</li><li>Хэрэглэгчийн ID ашиглахаас зайлсхийх. /user/654321/orders үүний оронд /me/orders ашиглах.</li><li>Автоматаар нэмэгдэх ID бүү ашигла. UUID ашигла.</li><li>XML файл parse хийх үед entity parse бүү хий ингэснээр XXE (XML external entity attack) -аас сэргийлнэ.</li><li>XML файл parse хийх үед entity expansion бүү хий ингэснэр Billion Laughs/XML bomb дайралтаас сэргийлнэ.</li><li>Файл upload хийхэд CDN ашигла.</li><li>Их хэмжээний өгөгдөлтэй ажиллах үед Workers болон Queue ашиглан үйлдлийг аль болох background -д ажиллуулж хариуг хурдан явуулах нь HTTP Blocking -оос сэргийлнэ.</li><li>DEBUG горимыг унтраах.</li></ul><h3>Output</h3><ul><li>X-Content-Type-Options: nosniff header дээр явуул.</li><li>X-Frame-Options: deny header дээр явуул.</li><li>Content-Security-Policy: default-src &#39;none&#39; header дээр явуул.</li><li>Ул мөр үлдээх X-Powered-By, Server, X-AspNet-Version header үүдыг устга.</li><li>content-type -ыг хүсэлтийн хариуд нь харгалзан буцаах, Хэрвээ application/json хүсэлт явсан бол хариуд нь content-type нь application/json байх.</li><li>Чухал өгөгдлүүд credentials, Passwords, security tokens бүү буцаа.</li><li>Тухайн ажилд тохирсон статус код илгээх. (Жнь. 200 OK, 400 Bad Request, 401 Unauthorized, 405 Method Not Allowed, г.м).</li></ul><h3>CI &amp; CD</h3><ul><li>unit/integration тест ашиглан системийн загварчлал, хэрэгжилтийг шалгах.</li><li>Код review ашигла, мөн өөрөө өөрийгөө ч шалга.</li><li>Бүх тусдаа хэсгүүд бүр vendor сан, бусад нэмэлт сангууд бүгдийг нь AV програмаар статикаар шалга.</li><li>Ямар ч үед deploy хийхэд амар шийдэл гаргах.</li></ul><h3>Мөн үзнэ үү:</h3><ul><li><a href="https://github.com/yosriady/api-development-tools">yosriady/api-development-tools</a> — RESTful HTTP+JSON API-г бүтээхэд хэрэгтэй нөөцүүдийн цуглуулга.</li></ul><h3>Оролцоо</h3><p>Энэ рэпод оролцох бол fork хийж өөрчлөлтөө оруулаад pull request үүсгэнэ үү. Асуулт байвал бидэнтэй холбогдоорой team@shieldfy.io.</p><h3>Нийтлэл таалагдсан бол clap &amp; share хийж ижил сонирхолтой хүмүүст хүргээрэй.</h3><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=28dbfda11613" width="1" height="1" alt=""><hr><p><a href="https://medium.com/limitx/api-%D0%B3%D0%B0%D1%80%D0%B3%D0%B0%D1%85-%D0%B7%D0%B0%D0%B3%D0%B2%D0%B0%D1%80%D1%87%D0%BB%D0%B0%D1%85-%D1%82%D0%B5%D1%81%D1%82%D0%BB%D1%8D%D1%85%D1%8D%D0%B4-%D0%B0%D1%8E%D1%83%D0%BB%D0%B3%D2%AF%D0%B9%D0%BD-%D1%82%D0%B0%D0%BB%D0%B0%D0%B0%D1%81-%D0%B0%D0%B2%D0%B0%D1%85-%D1%81%D3%A9%D1%80%D3%A9%D0%B3-%D0%B0%D1%80%D0%B3%D0%B0-%D1%85%D1%8D%D0%BC%D0%B6%D1%8D%D1%8D%D0%BD%D0%B8%D0%B9-%D0%B6%D0%B0%D0%B3%D1%81%D0%B0%D0%B0%D0%BB%D1%82-28dbfda11613">API аюулгүйн зѳвлѳмж</a> was originally published in <a href="https://medium.com/limitx">limitx</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Django 005: Хуудаслалт хэрхэн хийх вэ?]]></title>
            <link>https://medium.com/limitx/django-005-%D1%85%D1%83%D1%83%D0%B4%D0%B0%D1%81%D0%BB%D0%B0%D0%BB%D1%82-%D1%85%D1%8D%D1%80%D1%85%D1%8D%D0%BD-%D1%85%D0%B8%D0%B9%D1%85-%D0%B2%D1%8D-c2c895966b21?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/c2c895966b21</guid>
            <category><![CDATA[django]]></category>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[хичээл]]></category>
            <category><![CDATA[монгол]]></category>
            <category><![CDATA[вэб-хѳгжүүлэлт]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Wed, 16 May 2018 09:11:17 GMT</pubDate>
            <atom:updated>2018-05-16T09:17:31.004Z</atom:updated>
            <content:encoded><![CDATA[<p>Бүх блогоо нүүр хуудсан дээр гаргах нь бага зэргийн …, үгүй ээ нилээд утгагүй хэрэг болно. Тэгэхээр хуудаслалт хийцгээе.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mrStRYriL28SL3EQ7jIEgQ.jpeg" /><figcaption>source: <a href="https://www.facebook.com/pg/kitophotography1/photos/?ref=page_internal">https://www.facebook.com/pg/kitophotography1</a></figcaption></figure><p>Ѳмнѳх бичлэгээ дагаад хийсэн бол одоо үргэлжлүүлээд views.py файлыг нээгээд дээд хэсэгт доорхи импорт кодыг хуулж тавина.</p><pre>from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator</pre><p>дараа нь all_blog функц дотор доорхи ѳѳрчлѳлтийг оруулна.</p><pre>def all_blog(request):<br>    blog_list = Blog.objects.all()<br>    paginator = Paginator(blog_list, 3)<br>    page = request.GET.get(&#39;page&#39;)<br>    blogs = paginator.get_page(page)<br>    return render(request, &#39;index.html&#39;, {&#39;blogs&#39;: blogs})</pre><p>Харин одоо тэмплэйт дээр ѳѳрчлѳлт оруулна. <a href="https://foundation.zurb.com/sites/docs/pagination.html">Foundation -ын documentation </a>-ээс хуудаслалтын маркапыг хуулж бага зэрэг ѳѳрчлѳѳд,templates/index.html файлыг нээж дараах ѳѳрчлѳлтийг оруулна.</p><pre>{% extends &#39;base.html&#39; %}<br>{% block content %}<br>  &lt;div class=&quot;grid-x&quot;&gt;<br>  {% for blog in blogs %}<br>    &lt;div class=&quot;cell&quot;&gt;<br>      &lt;div class=&quot;media-object&quot;&gt;<br>        &lt;div class=&quot;media-object-section&quot;&gt;<br>          &lt;h4&gt;&lt;a href=&quot;{{blog.get_absolute_url}}&quot;&gt;{{blog.title|capfirst}}&lt;/a&gt;&lt;/h4&gt;<br>          &lt;p&gt;{{blog.body|truncatechars:&#39;140&#39;}}&lt;/p&gt;<br>          &lt;a href=&quot;{{blog.get_absolute_url}}&quot;&gt;Үргэлжлэл...&lt;/a&gt;<br>        &lt;/div&gt;<br>      &lt;/div&gt;<br>    &lt;/div&gt;<br>  {% endfor %}<br>  &lt;nav aria-label=&quot;Pagination&quot;&gt;<br>    &lt;ul class=&quot;pagination&quot;&gt;<br>      {% if blogs.has_previous %}<br>      &lt;li class=&quot;pagination-next&quot;&gt;&lt;a href=&quot;?page={{ blogs.previous_page_number }}&quot; aria-label=&quot;Next page&quot;&gt;Ѳмнѳх&lt;/a&gt;&lt;/li&gt;<br>      {% endif %}<br>      {% if blogs.has_next %}<br>      &lt;li class=&quot;pagination-next&quot;&gt;&lt;a href=&quot;?page={{ blogs.next_page_number }}&quot; aria-label=&quot;Next page&quot;&gt;Дараах&lt;/a&gt;&lt;/li&gt;<br>      {% endif %}<br>    &lt;/ul&gt;<br>  &lt;/nav&gt;<br>  &lt;/div&gt;<br>{% endblock content %}</pre><p>Ингээд render хийгээд харвал дараах үр дүнг үзүүлэх нь.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/853/1*_p8DkquwDDZBUIq1lrGkGQ.png" /></figure><p>Дараах товчийг дараад:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*wsrfRhzsJn-H6iCMdBPZJg.png" /></figure><p>Ингээд маш хялбар аргаар хуудаслалт хийчихлээ.</p><p>Тѳслийн код <a href="https://github.com/Zorig/django-demo_project/tree/005">github</a> дээр update хийгдсэн.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c2c895966b21" width="1" height="1" alt=""><hr><p><a href="https://medium.com/limitx/django-005-%D1%85%D1%83%D1%83%D0%B4%D0%B0%D1%81%D0%BB%D0%B0%D0%BB%D1%82-%D1%85%D1%8D%D1%80%D1%85%D1%8D%D0%BD-%D1%85%D0%B8%D0%B9%D1%85-%D0%B2%D1%8D-c2c895966b21">Django 005: Хуудаслалт хэрхэн хийх вэ?</a> was originally published in <a href="https://medium.com/limitx">limitx</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Django 004: Хѳгжүүлэлтийн орчны тохиргоо хэрэгжүүлэлт]]></title>
            <link>https://medium.com/limitx/django-004-%D1%85%D1%B3%D0%B3%D0%B6%D2%AF%D2%AF%D0%BB%D1%8D%D0%BB%D1%82%D0%B8%D0%B9%D0%BD-%D0%BE%D1%80%D1%87%D0%BD%D1%8B-%D1%82%D0%BE%D1%85%D0%B8%D1%80%D0%B3%D0%BE%D0%BE-4c50eea916c2?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/4c50eea916c2</guid>
            <category><![CDATA[монгол]]></category>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[вэб-хөгжүүлэлт]]></category>
            <category><![CDATA[django]]></category>
            <category><![CDATA[хичээл]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Thu, 29 Mar 2018 07:39:55 GMT</pubDate>
            <atom:updated>2018-03-29T07:43:37.924Z</atom:updated>
            <content:encoded><![CDATA[<p>Урьд нь бичсэн “<a href="https://medium.com/limitx/django-%D1%85%D3%A9%D0%B3%D0%B6%D2%AF%D2%AF%D0%BB%D1%8D%D0%BB%D1%82%D0%B8%D0%B9%D0%BD-%D0%B7%D3%A9%D0%B2-%D0%BE%D1%80%D1%87%D0%B8%D0%BD-%D0%B1%D1%8D%D0%BB%D0%B4%D1%8D%D1%85-f03d23444e72">Django хөгжүүлэлтийн ЗӨВ орчин бэлдэх</a>” нийтлэлийн дагуу project оо ѳѳрчлѳе.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HpfdC96mr4q1TpIXUY7rTw.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/JAHdPHMoaEA?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Spencer Imbrock</a> on <a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Эхлээд virtual environment үүсгэх хэрэгтэй. Миний хувьд virtualenvwrapper ашигладаг, гэхдээ энэ удаа virtualenv ашиглая. Тѳслийн хавтасруу ороод terminal нээгээд доорхи командыг бичиж ажиллуулна.</p><blockquote>Virtualenvwrapper ашиглах бол энэ <a href="https://virtualenvwrapper.readthedocs.io/en/latest/">заавраар тохируулна</a>. Заавал virtualenvwrapper суулгах шаардлагагүй.</blockquote><pre>virtualenv -p python3 venv</pre><p>Дээрхи команд ажиллаж дуусаад тѳслийн хавтсанд venv хавтас үүсэх ба үүсгэхдээ python3 ашиглана гэх нэмэлт тохиргоо ѳгч байна. -p python3 бичээгүй тохиолдолд default -аар python2 ашиглах юм. Дараа нь доорхи командаар virtualenvironment -оо идэвхижүүлнэ.</p><pre>source venv/bin/activate</pre><p>Одоо яг зѳв үүссэн эсэхийг шалгаж үзвэл:</p><pre>which python</pre><p>үр дүн нь сая үүсгэсэн venv/bin/python ашиглаж байгааг харуулж байна.</p><pre>(venv) zorig$ which python</pre><pre>/Users/zorig/projects/django-demo_project/venv/bin/python</pre><p>Одоо шинээр үүсгэсэн virtual environment дотроо Django суулгах шаардлагатай. Доорхи командаар django хамгийн сүүлийн хувилбар татаж авна. Гэхдээ … 😧</p><pre>pip install django</pre><p>Анх django тѳслѳѳ үүсгэхдээ Django 1.11 дээр үүсгэсэн тул дээрх командыг ѳѳрчлѳх шаардлагатай.</p><blockquote>Дараагийн нийтлэл дээр django 1.11 ээс django 2.0 хувилбар руу шилжүүлэх(migrate) хийх талаар бичье</blockquote><pre>pip install django==1.11</pre><p>Ингээд django маань суугаад дууссан бол сервер ээ ажиллуулж үзээд localhost:8000 руу хандаж үзье</p><pre>python manage.py runserver</pre><p>ямар нэг асуудалгүй ажилласан бол одоо requirements.txt файл үүсгэх хэрэгтэй. Энэ файл нь яг ямар сангууд, хэд гэдэг хувилбартайг энэ тѳсѳлд ашиглаж байгаа вэ гэх товч мэдээллийг агуулна. Ингэснээр ѳѳр хѳгжүүлэгч тѳсѳл дээр ажиллах, эсвэл тѳслѳѳ ѳѳр компьютер дээр хѳгжүүлэхэд амар хялбар болж ѳгѳх юм. requirements.txtмаань хоосон учраас суусан сангуудын мэдээллийг бичиж ѳгье.pip listашиглаж нийт суусан сангаа харъя.</p><pre>Django (1.11)<br>pip (9.0.3)<br>pytz (2018.3)<br>setuptools (39.0.1)<br>wheel (0.30.0)</pre><p>requirements.txt файлд гараар бичиж ѳгч болох ч заримдаа тэмдэгт орхиод алдаж магадгүй зэрэг асуудалтай. Үүнээс сэргийлэх нэгэн автомат үйлдэл нь</p><pre>pip freeze &gt; requirements.txt</pre><p>Ингэснээр дээр гарч ирсэн сангуудын жагсаалтыг requirements.txt файлруу автоматаар бичих юм.</p><p>Одоо ѳѳр нэгэн эсвэл танай багийн хѳгжүүлэгч тѳслийг clone хийж дотор нь virtualenv үүсгээд</p><pre>pip install -r requirements.txt</pre><p>командыг ажиллуулахад virtual environment дотроо requirements.txt доторх бүх санг суулгаад зѳвхѳн нэмэлт хѳгжүүлэлтээ хийхэд бэлэн болох юм.</p><blockquote>Энд venv файлыг git рүү ХЭЗЭЭ ч хуулж болохгүй тул .gitignore файл дотор доорхи ѳѳрчлѳлтийг оруулав.</blockquote><pre>*.swp<br>*.pyc<br>.vscode<br>venv/</pre><p>Тѳслийн код <a href="https://github.com/Zorig/django-demo_project/tree/004">github</a> дээр update хийгдсэн.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4c50eea916c2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/limitx/django-004-%D1%85%D1%B3%D0%B3%D0%B6%D2%AF%D2%AF%D0%BB%D1%8D%D0%BB%D1%82%D0%B8%D0%B9%D0%BD-%D0%BE%D1%80%D1%87%D0%BD%D1%8B-%D1%82%D0%BE%D1%85%D0%B8%D1%80%D0%B3%D0%BE%D0%BE-4c50eea916c2">Django 004: Хѳгжүүлэлтийн орчны тохиргоо хэрэгжүүлэлт</a> was originally published in <a href="https://medium.com/limitx">limitx</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Django 003: Front-end хөгжүүлэлт буюу demo блогоо царайлаг болгох нь]]></title>
            <link>https://medium.com/limitx/django-003-front-end-%D1%85%D3%A9%D0%B3%D0%B6%D2%AF%D2%AF%D0%BB%D1%8D%D0%BB%D1%82-%D0%B1%D1%83%D1%8E%D1%83-demo-%D0%B1%D0%BB%D0%BE%D0%B3%D0%BE%D0%BE-%D1%86%D0%B0%D1%80%D0%B0%D0%B9%D0%BB%D0%B0%D0%B3-%D0%B1%D0%BE%D0%BB%D0%B3%D0%BE%D1%85-%D0%BD%D1%8C-a19ac7359c58?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/a19ac7359c58</guid>
            <category><![CDATA[вэб-хөгжүүлэлт]]></category>
            <category><![CDATA[django]]></category>
            <category><![CDATA[монгол]]></category>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[хичээл]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Mon, 26 Mar 2018 01:56:01 GMT</pubDate>
            <atom:updated>2018-03-26T01:56:01.289Z</atom:updated>
            <content:encoded><![CDATA[<p>Ѳмнѳх нийтлэл дээр блогийн дэлгэрэнгүй хэсгийг хардаг болсон бол энэ удаа блог оо арай царайлаг болгоё 😏.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2P1iq6SG6W-bfcMJe6CoSw.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/photos/krV5aS4jDjA?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">russn_fckr</a> on <a href="https://unsplash.com/search/photos/brush-color-snippets?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p>Вэб хѳгжүүлэлтийг дотор нь хэрэглэгчид харагдах, хэрэглэгчийн харилцах хэсэг болох <strong>front-end, </strong>тухайн харилцааны үр дүнд(товч дарах, форм бѳглѳх г.м) цаана нь ямар үйлдэл гүйцэтгэх, логик ажиллагааг хийх <strong>back-end </strong>хэсэг гэж 2 хуваадаг.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/602/1*rcocTCILp-7_Bc6gZihzhg.png" /></figure><p>Тэгэхээр бид front-end хэсгийг одоо хийнэ. Front-end хѳгжүүлэлтийн шаардлага дүрэм гэх зүйлийг энд бичих нь хэт анхан шатны зүйл учраас алгасъя. Манай нѳхцѳлд блог маань гүүглийн хайлтад ѳртѳх зорилготой тул mobile friendly буюу утсанд зориулсан хувилбартай хийх ёстой. Утас болон компьютероос үзэхэд зориулсан хэрэгслүүд байдгаас хэдийг дурдвал:</p><ul><li>Bootstrap — хамгийн алдартай олонд хүрсэн frontend library</li><li>Foundation — хамгийн ѳндѳр customize хийх боломжит frontend library</li><li>SemanticUI — хамгийн олон компоненттэй frontend library</li><li><a href="http://usablica.github.io/front-end-frameworks/compare.html">Бусад сангуудыг эндээс харж болно</a></li></ul><p>Дээрхээс foundation -ыг сонгон UI(user interface) хэсгээ хийнэ. Шалтгааныг <a href="https://codeburst.io/part-1-bootstrap-4-vs-foundation-6-4-the-grid-8c02747f14fb">эндээс харж болно</a>. Ер нь л customize хийх тал дээр хамгийн сайн нь болохоор мѳн дээр нь <a href="https://www.w3schools.com/css/css3_flexbox.asp">flexbox</a> -ыг маш сайн integrate хийсэн учраас сонголоо.</p><p>Эхлээд django дээр template -ын удамшил ашиглах хэрэгтэй. templates хавтас дотор base.html нэртэй файл үүсгэж дотор нь доорх html -ыг бичнэ.</p><pre>&lt;!DOCTYPE html&gt;<br>&lt;html lang=&quot;mn&quot;&gt;<br>&lt;head&gt;<br>  &lt;meta charset=&quot;UTF-8&quot;&gt;<br>  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;<br>  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;<br>  &lt;title&gt;Demo Blog&lt;/title&gt;<br>&lt;/head&gt;<br>&lt;body&gt;<br>  {% block content %}<br>  {% endblock content %}<br>&lt;/body&gt;<br>&lt;/html&gt;</pre><p>Энд html хуудасны стандарт анхны маркапыг бичиж өгсөн түүнчлэн django template хэлний нэг боломж болох block -ыг ашиглан удамшил болгоно. {% block content %} -оос эхлээд {% endblock content %} хооронд өөр хуудасны контентийг гаргана. Ингэснээр зарим хэсгийн маркапыг дахин бичихээс зайлсхийх давуу талтай. Одоо templates/index.html дээр өөрчлөлт оруулна.</p><pre>{% extends &#39;base.html&#39; %}<br>{% block content %}<br>  {% for blog in blogs %}<br>    &lt;a href=&quot;{{blog.get_absolute_url}}&quot;&gt;{{blog.title}}&lt;/a&gt;<br>    {{blog.body}}<br>    &lt;hr&gt;<br>  {% endfor %}<br>{% endblock content %}</pre><p>templates/index.html дээр {% extends &#39;base.html&#39; %} -ыг дуудсанаар base.html -ын дотор ашиглахыг зааж өгч, харин {% block content %} -с {% endblock content %} хооронд юу гарахыг нь бичиж өгнө. Ингээд render хийгдэх хуудсыг <strong>developer tools</strong> ээр нээгээд харвал доорх үр дүн гарна.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EimpU8wZ4mu6xcvxhTnQUQ.png" /></figure><p>Харин одоо base.html болон django -ын template удамшлыг ашиглаад foundation ээ дуудан ашиглая.</p><p>Foundation -ын <a href="https://foundation.zurb.com/sites/download/">вэб сайтаас</a> <strong>өөртөө тохируулан custom build </strong>хийн татаж авч болно эсвэл шууд download everything гээд бүгдийг нь татаж авч болно. Хэрвээ вэбийн дуудах хурдыг <strong>хурдан</strong> байлгана гэвэл хэрэглэхгүй компонентуудыг хасаж татаж авсан нь дээр. Татаж авсан файлыг төслийн хавтас дотор static хавтас үүсгэж дотор нь задална.</p><pre>demo_project/<br>  blog/<br>  db.sqlite3<br>  demo_project/<br>  manage.py<br>  README.md<br>  static/<br>    css/<br>      foundation.min.css<br>    js/<br>      foundation.min.js<br>      jquery.js<br>      what-input.js<br>  templates/</pre><p>Одоо demo_project/settings.py файлын хамгийн доод хэсэгт доорх кодыг хуулж тавина. Ингэснээр static файлуудын хавтасыг django -д зааж өгнө. Харин статик файлыг дуудахдаа <em>domain-хаяг/static/css/foundation.min.css</em> гэж дуудна гэсэн URL -ыг бас тохируулсан байна.</p><pre>STATIC_URL = &#39;/static/&#39;<br>STATICFILES_DIRS = (<br>    os.path.join(BASE_DIR, &#39;static&#39;),<br>)</pre><p>ингээд base.html дээр дараах өөрчлөлтийг оруулна. Django -ын template хэл нь бидэнд static файлууд дуудах нэг боломж {% static ..%}гаргаж өгсөн байгааг ашиглана. Ингэснээр дээр settings.py дээр тохируулж өгсөн хавтаснаас эдгээр файлыг хайх юм.</p><blockquote>Жич base.html -ын хамгийн дээд мөрөнд {% load static %} гэсэн байгааг мартаж болохгүй шүү.</blockquote><pre>{% load static %}<br>&lt;!DOCTYPE html&gt;<br>&lt;html lang=&quot;mn&quot;&gt;<br>&lt;head&gt;<br>  &lt;meta charset=&quot;UTF-8&quot;&gt;<br>  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;<br>  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;<br>  &lt;title&gt;Demo Blog&lt;/title&gt;<br>  &lt;link rel=&quot;stylesheet&quot; href=&quot;{% static &#39;css/foundation.min.css&#39; %}&quot;&gt;<br>&lt;/head&gt;<br>&lt;body&gt;<br>  {% block content %}<br>  {% endblock content %}<br>  &lt;script src=&quot;{% static &#39;js/jquery.js&#39; %}&quot;&gt;&lt;/script&gt;<br>  &lt;script src=&quot;{% static &#39;js/what-input.js&#39; %}&quot;&gt;&lt;/script&gt;<br>  &lt;script src=&quot;{% static &#39;js/foundation.min.js&#39; %}&quot;&gt;&lt;/script&gt;<br>  &lt;script&gt;<br>     $(document).foundation()<br>  &lt;/script&gt;<br>&lt;/body&gt;<br>&lt;/html&gt;</pre><p>Ингээд серверээ ажиллуулаад python manage.py runserver гээд хөтөчөө нээгээд <a href="http://localhost:8000">localhost:8000</a> руу хандахад дараах үр дүнг харуулна.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zgnzWM9-iXMwOz1ouBq0NQ.png" /></figure><p>Одоо маркап аа бага зэрэг янзалъя <a href="https://foundation.zurb.com/sites/docs/top-bar.html#basics">foundation-ын document дээрх navbar -ын маркапыг</a> templates/base.html -ын {% block content %} -ын дээд талд байрлуулна.</p><pre>  &lt;div class=&quot;top-bar&quot;&gt;<br>    &lt;div class=&quot;top-bar-left&quot;&gt;<br>      &lt;ul class=&quot;dropdown menu&quot; data-dropdown-menu&gt;<br>        &lt;li class=&quot;menu-text&quot;&gt;Site Title&lt;/li&gt;<br>        &lt;li&gt;<br>          &lt;a href=&quot;#&quot;&gt;One&lt;/a&gt;<br>          &lt;ul class=&quot;menu vertical&quot;&gt;<br>            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;One&lt;/a&gt;&lt;/li&gt;<br>            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Two&lt;/a&gt;&lt;/li&gt;<br>            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Three&lt;/a&gt;&lt;/li&gt;<br>          &lt;/ul&gt;<br>        &lt;/li&gt;<br>        &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Two&lt;/a&gt;&lt;/li&gt;<br>        &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Three&lt;/a&gt;&lt;/li&gt;<br>      &lt;/ul&gt;<br>    &lt;/div&gt;<br>    &lt;div class=&quot;top-bar-right&quot;&gt;<br>      &lt;ul class=&quot;menu&quot;&gt;<br>        &lt;li&gt;&lt;input type=&quot;search&quot; placeholder=&quot;Search&quot;&gt;&lt;/li&gt;<br>        &lt;li&gt;&lt;button type=&quot;button&quot; class=&quot;button&quot;&gt;Search&lt;/button&gt;&lt;/li&gt;<br>      &lt;/ul&gt;<br>    &lt;/div&gt;<br>  &lt;/div&gt;<br>{% block content %} &lt;!-- block content хэсэг --&gt;<br>{% endblock content %} </pre><p>Дараа нь templates/index.html дээр дараах өөрчлөлтийг оруулая. CSS -ын <a href="https://foundation.zurb.com/sites/docs/flexbox-mode.html">Flexbox</a> -ыг foundation дээр бас ашиглах боломжтой тул доор ашиглав.</p><pre>{% extends &#39;base.html&#39; %}<br>{% block content %}<br>  &lt;div class=&quot;grid-x&quot;&gt;<br>  {% for blog in blogs %}<br>    &lt;div class=&quot;cell&quot;&gt;<br>      &lt;div class=&quot;media-object&quot;&gt;<br>        &lt;div class=&quot;media-object-section&quot;&gt;<br>          &lt;h4&gt;&lt;a href=&quot;{{blog.get_absolute_url}}&quot;&gt;{{blog.title|capfirst}}&lt;/a&gt;&lt;/h4&gt;<br>          &lt;p&gt;{{blog.body|truncatechars:&#39;140&#39;}}&lt;/p&gt;<br>          &lt;a href=&quot;{{blog.get_absolute_url}}&quot;&gt;Үргэлжлэл...&lt;/a&gt;<br>        &lt;/div&gt;<br>      &lt;/div&gt;<br>    &lt;/div&gt;<br>  {% endfor %}<br>  &lt;/div&gt;<br>{% endblock content %}</pre><p>Энд django дээрх өөрийнх нь <a href="https://docs.djangoproject.com/en/2.0/ref/templates/builtins/"><strong>template tag</strong></a><strong> </strong>болох capfirst ашиглан зөвхөн эхний үсгийг томоор render хийх, truncatechars ашиглан нийт render хийх тэмдэгтийн тоог хязгаарлаж өгч байна. Ингээд эцсийн үр дүнг хөтчөөс харвал:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EhfULKqonzZxdCWQmozl0w.png" /></figure><p>Өөрчлөлт орсон код <a href="https://github.com/Zorig/django-demo_project/tree/003">github</a> дээр тавигдсан байгаа. Master branch дээр хамгийн сүүлийн өөрчлөлтүүд харин бусад branch(001, 002 …) дээр тухайн нийтлэлд харьяалагдах өөрчлөлтүүд тус тус байна.</p><p>Хэрвээ энэ нийтлэл танд таалагдсан бол clap, share хийж бусад хүмүүст ч бас хүргээрэй.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a19ac7359c58" width="1" height="1" alt=""><hr><p><a href="https://medium.com/limitx/django-003-front-end-%D1%85%D3%A9%D0%B3%D0%B6%D2%AF%D2%AF%D0%BB%D1%8D%D0%BB%D1%82-%D0%B1%D1%83%D1%8E%D1%83-demo-%D0%B1%D0%BB%D0%BE%D0%B3%D0%BE%D0%BE-%D1%86%D0%B0%D1%80%D0%B0%D0%B9%D0%BB%D0%B0%D0%B3-%D0%B1%D0%BE%D0%BB%D0%B3%D0%BE%D1%85-%D0%BD%D1%8C-a19ac7359c58">Django 003: Front-end хөгжүүлэлт буюу demo блогоо царайлаг болгох нь</a> was originally published in <a href="https://medium.com/limitx">limitx</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ember controller ашиглах нь]]></title>
            <link>https://medium.com/ember-notes/ember-controller-%D0%B0%D1%88%D0%B8%D0%B3%D0%BB%D0%B0%D1%85-%D0%BD%D1%8C-24bde5d954aa?source=rss-b4aaa9ce2e86------2</link>
            <guid isPermaLink="false">https://medium.com/p/24bde5d954aa</guid>
            <category><![CDATA[mongolia]]></category>
            <category><![CDATA[вэб-хѳгжүүлэлт]]></category>
            <category><![CDATA[ember]]></category>
            <category><![CDATA[emberjs]]></category>
            <category><![CDATA[монгол]]></category>
            <dc:creator><![CDATA[Zorig]]></dc:creator>
            <pubDate>Sun, 25 Feb 2018 15:51:56 GMT</pubDate>
            <atom:updated>2018-03-03T07:34:12.524Z</atom:updated>
            <content:encoded><![CDATA[<p>Ember -ын Route, Controller 2 бол яг Бонни Клайд 2 юм.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MzNMhadxFmVeKZ9-JOTX1A.jpeg" /><figcaption>source: <a href="http://mentalfloss.com/article/78096/13-infamous-facts-about-bonnie-and-clyde">http://mentalfloss.com/article/78096/13-infamous-facts-about-bonnie-and-clyde</a></figcaption></figure><p>Ember дээр Route -тэй салшгүй холбоотой нэг зүйл нь Controller юм. Controller нь route дуудагдах үед render хийгдэх тусгай компонентийн үүрэгтэй. Controller нь route ээс ирэх ганцхан model гэх property авдаг. Ашиглаж үзвэл:</p><pre>ember g controller controller-name</pre><p>Энд үүсгэх controller -ын нэр нь route -ын нэртэй таарч байх ёстой. Тэгэхээр манай нөхцөлд өмнө нь API -аас дата авч байгаа хэсгийг бага зэрэг өөрчлөөд user route, мөн user/detail route үүсгэе.</p><pre>ember g route user<br>ember g route user/detail</pre><p>ингээд router.js дээр дараах өөрчлөлтийг оруулна.</p><pre>import EmberRouter from &#39;<a href="http://twitter.com/ember/routing">@ember/routing</a>/router&#39;;<br>import config from &#39;./config/environment&#39;;</pre><pre>const Router = EmberRouter.extend({<br>  location: config.locationType,<br>  rootURL: config.rootURL<br>});</pre><pre>Router.map(function() {<br>  this.route(&#39;user&#39;, function() {<br>    this.route(&#39;detail&#39;, { path:&#39;/:id&#39;}); //detail дээр id авна<br>  });<br>});</pre><pre>export default Router;</pre><p>өмнөх app/routes/index.js route дээр бичсэн хэсгийг app/routes/user/detail.js руу хуулаад</p><pre>import Route from &#39;<a href="http://twitter.com/ember/routing">@ember/routing</a>/route&#39;;</pre><pre>export default Route.extend({<br>  model() {<br>    return this.store.findRecord(&#39;user&#39;, &#39;zorig&#39;) <br>  }<br>});</pre><p>app/templates/user/detail.hbs дотор дараах хэсгийг хуулж тавина.</p><pre>&lt;h4&gt;{{model.name}}&lt;/h4&gt;<br>&lt;p&gt;{{model.bio}}&lt;/p&gt;<br>&lt;span&gt;Followers: {{model.followers}}&lt;/span&gt;<br>&lt;span&gt;Following: {{model.following}}&lt;/span&gt;</pre><p>Одоо controller үүсгэе ember g controller user/detail ингэснээр app/controllers/user/detail.js файл үүснэ.</p><blockquote>Энд user/detail route-тай адил controller үүсгэж байна.</blockquote><p>Харин одоо controller дотор буюу app/controllers/user/detail.js дотор доорхи кодыг бичнэ.</p><blockquote>Доор <strong>ember </strong>-ын toggleProperty ашиглаж <strong>boolean</strong> утга сольж байна.</blockquote><pre>import Controller from &#39;<a href="http://twitter.com/ember/controller">@ember/controller</a>&#39;;</pre><pre>export default Controller.extend({<br>  isPictureHide: true,<br>  actions: {<br>    togglePicture() {<br>      this.toggleProperty(&#39;isPictureHide&#39;);<br>    }<br>  }<br>});</pre><p>Дараа нь app/templates/user/detail.hbs дээр дараахи өөрчлөлтийг оруулна.</p><pre>&lt;h4&gt;{{model.name}}&lt;/h4&gt;<br>&lt;p&gt;{{model.bio}}&lt;/p&gt;<br>&lt;span&gt;Followers: {{model.followers}}&lt;/span&gt;<br>&lt;span&gt;Following: {{model.following}}&lt;/span&gt;<br>&lt;!-- зураг харах/нуух товч шинээр нэмнэ --&gt;<br>{{#if isPictureHide}}<br>  &lt;div class=&quot;image&quot;&gt;<br>    &lt;button {{action &#39;togglePicture&#39;}}&gt;Зураг&lt;/button&gt;<br>  &lt;/div&gt;<br>{{else}}<br>&lt;div class=&quot;image&quot;&gt;<br>  &lt;button {{action &#39;togglePicture&#39;}}&gt;Нуух&lt;/button&gt;&lt;br/&gt;<br>  &lt;img src=&quot;{{model.avatar_url}}&quot; alt=&quot;{{model.name}}&quot;/&gt;<br>&lt;/div&gt;<br>{{/if}}</pre><p>Ингээд эцэст нь сервер ээ ажиллуулаад( ember s ) localhost:4200/user/zorig хаягруу хандаж үзэхэд доорхи үр дүнг үзүүлнэ.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/378/1*kBL6JUOrvPE2I8169rP3Ew.png" /><figcaption>http://localhost:4200/user/zorig</figcaption></figure><p>“<strong>Зураг</strong>” товчийг дарж үзээрэй. ;)</p><blockquote>Эх кодыг <a href="https://github.com/Zorig/ember-notes">github</a> -аас</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=24bde5d954aa" width="1" height="1" alt=""><hr><p><a href="https://medium.com/ember-notes/ember-controller-%D0%B0%D1%88%D0%B8%D0%B3%D0%BB%D0%B0%D1%85-%D0%BD%D1%8C-24bde5d954aa">Ember controller ашиглах нь</a> was originally published in <a href="https://medium.com/ember-notes">Zori’s ember.js тэмдэглэл</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>